diff --git a/modules/dbsupport/src/main/java/org/jpos/ee/DBFilter.java b/modules/dbsupport/src/main/java/org/jpos/ee/DBFilter.java new file mode 100644 index 0000000000..552d82cc01 --- /dev/null +++ b/modules/dbsupport/src/main/java/org/jpos/ee/DBFilter.java @@ -0,0 +1,21 @@ +package org.jpos.ee; + + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +/** + * Functional interface to create predicates for querying {@link DBManager} + * @param The root entity type on which to create the predicate + */ +@FunctionalInterface +public interface DBFilter { + /** + * Creates the predicate for the root + * @param criteriaBuilder criteria builder for predicate creation + * @param root root entity of the query + * @return Predicate suitable to add to a query on the given root + */ + Predicate createPredicate(CriteriaBuilder criteriaBuilder, Root root); +} diff --git a/modules/dbsupport/src/main/java/org/jpos/ee/DBManager.java b/modules/dbsupport/src/main/java/org/jpos/ee/DBManager.java index 0d2ac8abda..b7b779bb74 100644 --- a/modules/dbsupport/src/main/java/org/jpos/ee/DBManager.java +++ b/modules/dbsupport/src/main/java/org/jpos/ee/DBManager.java @@ -24,6 +24,7 @@ import javax.persistence.criteria.*; import org.hibernate.query.Query; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -97,9 +98,6 @@ public T getItemByParam(String param, Object value, boolean withFilter) { } } - public List getItemsByParam(String param, Object value) { - return getItemsByParam(param,value,false); - } public List getItemsByParam(String param, Object value, boolean withFilter) { try { @@ -126,6 +124,152 @@ public List getItemsByParam(int offset, int limit, String param, Object value } } + public List queryItems(int offset, int limit, DBFilter filter) { + return queryItems(offset, limit, false, filter); + } + + /** + * Paged version of {@link #queryItems(DBFilter[])} + * @param offset page start + * @param limit page size + * @param filters predicate creators + * @return items for which predicate created by filters are true + */ + @SafeVarargs + public final List queryItems(int offset, int limit, DBFilter... filters) { + return queryItems(offset, limit, false, filters); + } + + public List queryItems(int offset, int limit, boolean internalFilters, DBFilter filter) { + Query q = createQuery(internalFilters, filter); + if (limit > 0) q.setMaxResults(limit); + if (offset > 0) q.setFirstResult(offset); + return q.getResultList(); + } + + /** + * Paged version of {@link #queryItems(boolean, DBFilter[])} + * @param offset page start + * @param limit page size + * @param internalFilters if true include manager's internal filter + * @param filters predicate creators + * @return items for which predicate created by filters are true + */ + @SafeVarargs + public final List queryItems(int offset, int limit, boolean internalFilters, DBFilter... filters) { + Query q = createQuery(internalFilters, filters); + if (limit > 0) q.setMaxResults(limit); + if (offset > 0) q.setFirstResult(offset); + return q.getResultList(); + } + + public List queryItems(DBFilter filter) { + return queryItems(false, filter); + } + + /** + * Arbitrary query over the entity type (T) of this manager + * Example usage: + *
+     *     List≤T&ge results = queryItems( (cb, root) ->
+     *          cb.or(
+     *              cb.greaterThanOrEqualTo(root.get("property"), value),
+     *              cb.isNotNull(root.get("otherProperty")
+     *          )
+     *     )
+     * 
+ * + * @param filters predicate creators + * @return items for which predicate created by filters are true + */ + @SafeVarargs + public final List queryItems(DBFilter... filters) { + return queryItems(false, filters); + } + + public List queryItems(boolean internalFilters, DBFilter filter) { + return createQuery(internalFilters, filter).getResultList(); + } + + /** + * Version of {@link #queryItems(DBFilter[])} that adds the manager internal predicates + * @param internalFilters if true the manager's internal predicates are added + * @param filters predicate creators + * @return items for which predicate created by filters are true + */ + @SafeVarargs + public final List queryItems(boolean internalFilters, DBFilter... filters) { + return createQuery(internalFilters, filters).getResultList(); + } + public List getItemsByParam(String param, Object value) { + return getItemsByParam(param,value,false); + } + + public Query createQuery(DBFilter filter) { + return createQuery(false, filter); + } + + /** + * Similar to {@link #queryItems(DBFilter[])} but returns the query to be modified prior execution + * @param filters predicate creators + * @return Hibernate Query ready to be executed or modified prior execution + */ + @SafeVarargs + public final Query createQuery(DBFilter... filters) { + return createQuery(false, filters); + } + + public Query createQuery(boolean internalFilters, DBFilter filter) { + return db.session().createQuery(createCriteriaQuery(internalFilters, filter)); + } + + /** + * Similar to {@link #createQuery(DBFilter[])} with ability of adding manager's internal predicates + * @param internalFilters include manager's internal predicates? + * @param filters predicate creators + * @return Hibernate Query Ready to be executed or modified prior execution + */ + @SafeVarargs + public final Query createQuery(boolean internalFilters, DBFilter... filters) { + return db.session().createQuery(createCriteriaQuery(internalFilters, filters)); + } + + protected CriteriaQuery createCriteriaQuery(DBFilter filter) { + return createCriteriaQuery(false, filter); + } + + @SafeVarargs + protected final CriteriaQuery createCriteriaQuery(DBFilter... filters) { + return createCriteriaQuery(false, filters); + } + + protected CriteriaQuery createCriteriaQuery(boolean internalFilters, DBFilter filter) { + + CriteriaBuilder cb = db.session().getCriteriaBuilder(); + + CriteriaQuery query = cb.createQuery(clazz); + Root root = query.from(clazz); + Predicate predicate = (filter != null) ? filter.createPredicate(cb, root) : null; + if (internalFilters){ + Predicate[] predicates = buildFilters(root); + if (predicates != null && predicates.length > 0) { + predicate = (predicate != null) ? cb.and(predicate, cb.and(predicates)) : cb.and(predicates); + } + } + if (predicate != null) query = query.where(predicate); + return query.select(root); + } + + @SafeVarargs + protected final CriteriaQuery createCriteriaQuery(boolean internalFilters, DBFilter... filters) { + CriteriaQuery query = createCriteriaQuery(internalFilters, (DBFilter) null); + CriteriaBuilder cb = db.session().getCriteriaBuilder(); + Root root = query.from(clazz); + + return query.where(query.getRestriction() + , cb.and(Arrays.stream(filters).map(f -> f.createPredicate(cb, root)).toArray(Predicate[]::new))); + } + private CriteriaQuery createQueryByParam(String param, Object value, boolean withFilter) { CriteriaBuilder criteriaBuilder = db.session().getCriteriaBuilder(); CriteriaQuery query = criteriaBuilder.createQuery(clazz);