Skip to content

Commit

Permalink
#177: added Query, selection for StatementFactory, etc.
Browse files Browse the repository at this point in the history
  • Loading branch information
hohwille committed Apr 16, 2016
1 parent eb5543a commit d3b9d5a
Show file tree
Hide file tree
Showing 45 changed files with 893 additions and 192 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@
*/
public interface ReadableProperty<V> extends ReadOnlyProperty<V>, PropertyPath<V> {

/**
* @return the name of the property. By convention it should start with a {@link Character#isUpperCase(char) capital}
* letter followed by alpha-numeric characters. The name of a single property must especially not contain the
* dot character (.) that is used to separate segments in a {@link PropertyPath path}.
*/
@Override
String getName();

/**
* @return the type of the property {@link #getValue() value}. Please note that the generic signature of this method
* is returning the type {@link GenericType}{@literal <? extends V>} instead of {@link GenericType}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,12 @@
*/
public interface PropertyPath<V> extends AttributeReadName, AttributeReadValue<V> {

/**
* @return the name what is the {@link String} representation of this path. In case of a
* {@link net.sf.mmm.util.property.api.ReadableProperty single property} the name of the property. Otherwise
* an entire path (such as e.g. "entity.property").
*/
@Override
String getName();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0 */
package net.sf.mmm.util.query.api;

/**
* This is the abstract interface of a {@link Command} that can be executed against a database as {@link #getSql() SQL}.
* It is either a {@link Query} or a {@link net.sf.mmm.util.query.api.statement.Statement}.
*
* @author hohwille
* @since 8.0.0
*/
public abstract interface Command {

/**
* @return the current SQL {@link String} of this {@link Command}. In case of a
* {@link net.sf.mmm.util.query.api.statement.Statement} it may only be an SQL fragment as the final operation
* such as {@link net.sf.mmm.util.query.api.statement.SelectStatement#fetch()} will complete the statement.
*/
String getSql();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0 */
package net.sf.mmm.util.query.api;

import java.util.Iterator;
import java.util.List;

/**
* This is the interface for a regular {@link Query} that returns the {@link List} of matching objects.
*
* @param <E> the generic type of the {@link List}-{@link List#get(int) elements}.
*
* @see net.sf.mmm.util.query.api.statement.SelectStatement#query()
*
* @author hohwille
* @since 8.0.0
*/
public interface ListQuery<E> extends Query<List<E>>, Iterable<E> {

/**
* {@link #execute() Executes} the query and returns the matching objects as {@link Iterator}. This method may be
* overridden for database technology implementations that have native support for {@link Iterator} (unlike
* {@link net.sf.mmm.util.query.base.statement.jpql.Jpql}). In such case this method is way more efficient if you only
* need to iterate the results to a specific point without the need to know the {@link List#size() number of matches}.
* If possible you shall prefer this method over {@link #execute()}.
*
* @return an {@link Iterator} of the {@link #execute() results}.
*/
default Iterator<E> iterator() {

return execute().iterator();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0 */
package net.sf.mmm.util.query.api;

/**
* A {@link Query} that {@link #execute() results} in a {@link Number}.
*
* @param <E> the generic type of the {@link #execute() result}.
*
* @author hohwille
* @since 8.0.0
*/
public interface NumberQuery<E extends Number & Comparable<?>> extends Query<E> {

}
25 changes: 25 additions & 0 deletions mmm-util-query/src/main/java/net/sf/mmm/util/query/api/Query.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0 */
package net.sf.mmm.util.query.api;

/**
* This is the interface for a query that is the {@link net.sf.mmm.util.query.api.statement.SelectStatement#query()
* result} of a {@link net.sf.mmm.util.query.api.statement.SelectStatement}.<br/>
* Besides {@link #execute() executing} the {@link Query} you can also reuse it as a sub-query in more complex
* {@link net.sf.mmm.util.query.api.statement.Statement}s.
*
* @param <E> the generic type of the {@link #execute() result}.
*
* @author hohwille
* @since 8.0.0
*/
public interface Query<E> extends Command {

/**
* Executes the {@link Query} {@link Command} and returns the result.
*
* @return the result of the {@link Query} execution.
*/
E execute();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0 */
package net.sf.mmm.util.query.api;

import net.sf.mmm.util.exception.api.ObjectNotFoundException;

/**
* This is the interface for a {@link Query} that can only match a single result.
*
* @param <E> the generic type of the {@link #execute() result}.
* @see #executeRequired()
*
* @author hohwille
* @since 8.0.0
*/
public interface SingleQuery<E> extends Query<E> {

/**
* @throws ObjectNotFoundException if the query had no match.
* @return the result of {@link #execute()} but never {@code null}.
*/
E executeRequired() throws ObjectNotFoundException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
import java.util.List;

import net.sf.mmm.util.exception.api.ObjectNotFoundException;
import net.sf.mmm.util.query.api.ListQuery;
import net.sf.mmm.util.query.api.NumberQuery;
import net.sf.mmm.util.query.api.Query;
import net.sf.mmm.util.query.api.SingleQuery;

/**
* A {@link FeatureFetch} is for a regular query {@link net.sf.mmm.util.query.api.statement.Statement} to fetch and retrieve
* results.
* A {@link FeatureFetch} is for a regular {@link net.sf.mmm.util.query.api.statement.SelectStatement} to fetch and
* retrieve results.
*
* @see net.sf.mmm.util.query.api.statement.SelectStatement
*
Expand All @@ -19,61 +23,89 @@
*/
public abstract interface FeatureFetch<E> extends StatementFeature {

/**
* @return a {@link ListQuery} to fetch all matching results with a regular SELECT.
*/
ListQuery<E> query();

/**
* Executes this query to fetch all matching results.
*
* @return the {@link List} with all matching results. Will be an {@link List#isEmpty() empty List} if no results are
* found.
*/
List<E> fetch();
default List<E> fetch() {

return query().execute();
}

/**
* @return a {@link SingleQuery} to fetch the first matching results with a SELECT.
*/
SingleQuery<E> queryFirst();

/**
* Executes this query to fetch the first matching result.
* Executes {@link #queryFirst()} and returns the result.
*
* @return the first matching result or {@code null} if no result is found.
*/
E fetchFirst();
default E fetchFirst() {

return queryFirst().execute();
}

/**
* Executes this query to fetch the first matching result.
* Executes {@link #queryFirst()} and returns the result.
*
* @return the first matching result or {@code null} if no result is found.
* @return the first matching result.
* @throws ObjectNotFoundException if the query had no match.
*/
default E fetchFirstRequired() {
default E fetchFirstRequired() throws ObjectNotFoundException {

E result = fetchFirst();
if (result == null) {
throw new ObjectNotFoundException(toString());
}
return result;
return queryFirst().executeRequired();
}

/**
* Executes this query to fetch a unique result.
* @return a {@link SingleQuery} to fetch a single unique matching result with a SELECT. The {@link Query}
* {@link Query#execute() execution} will fail with an exception if it matches multiple result objects. It can
* only have a single or an empty ({@code null}) result.
*/
SingleQuery<E> queryOne();

/**
* Executes {@link #queryOne()} and returns the result.
*
* @return the unique result or {@code null} if no result is found.
*/
E fetchOne();
default E fetchOne() {

return queryOne().execute();
}

/**
* Executes this query to fetch a unique result.
*
* @return the unique result or {@code null} if no result is found.
* @return the unique result.
* @throws ObjectNotFoundException if the query had no match.
*/
default E fetchOneRequired() {
default E fetchOneRequired() throws ObjectNotFoundException {

E result = fetchOne();
if (result == null) {
throw new ObjectNotFoundException(toString());
}
return result;
return queryOne().executeRequired();
}

/**
* Executes this query as a COUNT-query.
* @return a {@link NumberQuery} to fetch the number of matching objects with a {@code SELECT COUNT}.
*/
NumberQuery<Long> queryCount();

/**
* Executes {@link #queryCount()} and returns the result.
*
* @return the number of objects (rows) matching this query.
*/
long fetchCount();
default long fetchCount() {

return queryCount().execute().longValue();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import net.sf.mmm.util.property.api.path.PropertyPath;

/**
* This is the abstract interface for a query {@link net.sf.mmm.util.query.api.statement.Statement} allowing a
* This is the abstract interface for a {@link net.sf.mmm.util.query.api.statement.Statement} allowing a
* {@link #groupBy(PropertyPath) GROUP BY clause}.
*
* @param <SELF> the generic type of this query itself (this) for fluent API calls.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import net.sf.mmm.util.query.api.expression.Expression;

/**
* This is the abstract interface for a query {@link net.sf.mmm.util.query.api.statement.Statement} allowing a
* This is the abstract interface for a {@link net.sf.mmm.util.query.api.statement.Statement} allowing a
* {@link #having(Expression...) HAVING clause}.
*
* @param <SELF> the generic type of this query itself (this) for fluent API calls.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import net.sf.mmm.util.query.base.path.Alias;

/**
* Extends {@link Statement} for a query {@link net.sf.mmm.util.query.api.statement.Statement} with support for
* #innerJoin block.
* Extends {@link Statement} for a {@link net.sf.mmm.util.query.api.statement.Statement} with support for #innerJoin
* block.
*
* @param <SELF> the generic type of this query itself (this) for fluent API calls.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import net.sf.mmm.util.query.api.variable.Variable;

/**
* Extends {@link Statement} for a query {@link net.sf.mmm.util.query.api.statement.Statement} with support for
* Extends {@link Statement} for a {@link net.sf.mmm.util.query.api.statement.Statement} with support for
* {@link #let(PropertyPath, String) LET} block.
*
* @param <SELF> the generic type of this query itself (this) for fluent API calls.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
package net.sf.mmm.util.query.api.feature;

/**
* This is the abstract interface for a query {@link net.sf.mmm.util.query.api.statement.Statement} with support for
* This is the abstract interface for a {@link net.sf.mmm.util.query.api.statement.Statement} with support for
* {@link #limit(int)}.
*
* @param <SELF> the generic type of this query itself (this) for fluent API calls.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import net.sf.mmm.util.query.api.statement.Statement;

/**
* Extends {@link Statement} for a query {@link net.sf.mmm.util.query.api.statement.Statement} that modifies data.
* Extends {@link Statement} for a {@link net.sf.mmm.util.query.api.statement.Statement} that modifies data.
*
* @see net.sf.mmm.util.query.api.statement.ModifyStatement
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import net.sf.mmm.util.property.api.path.PropertyPath;

/**
* This is the abstract interface for a query {@link net.sf.mmm.util.query.api.statement.Statement} allowing an
* This is the abstract interface for a {@link net.sf.mmm.util.query.api.statement.Statement} allowing an
* {@link #orderBy(PropertyPath, SortOrder) ORDER BY clause}.
*
* @param <SELF> the generic type of this query itself (this) for fluent API calls.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
package net.sf.mmm.util.query.api.feature;

/**
* This is the abstract interface for a query {@link net.sf.mmm.util.query.api.statement.Statement} with paging support via
* This is the abstract interface for a {@link net.sf.mmm.util.query.api.statement.Statement} with paging support via
* {@link #limit(int)} and {@link #offset(long)}.
*
* @param <SELF> the generic type of this query itself (this) for fluent API calls.
Expand Down
Loading

0 comments on commit d3b9d5a

Please sign in to comment.