Wt: Wt::Dbo::Query< Result, BindStrategy > Class Template Reference

Wt 4.10.4

Loading...
Searching...
No Matches
Public Member Functions | List of all members
Wt::Dbo::Query< Result, BindStrategy > Class Template Reference
Database Objects (Wt::Dbo)

A database query. More...

`#include <Wt/Dbo/Query.h>`

Inheritance diagram for Wt::Dbo::Query< Result, BindStrategy >:
[legend]

## Public Member Functions
| Query ()
| Default constructor.
| ~Query ()
| Destructor.
| Query (const Query &other)
| Copy constructor.
Query & | operator= (const Query &other)
| Assignment operator.
std::vector< FieldInfo > | fields () const
| Returns the result fields.
Session & | session () const
| Returns the session.
template<typename T >
Query< Result, BindStrategy > & | bind (const T &value)
| Binds a value to the next positional marker.
void | reset ()
| Resets bound values.
Result | resultValue () const
| Returns a unique result value.
collection< Result > | resultList () const
| Returns a result list.
| operator Result () const
| Returns a unique result value.
| operator collection< Result > () const
| Returns a result list.
std::string | asString () const
| Returns the SQL of the query as a string.
Query< Result, BindStrategy > & | bindSubqueryValues (const AbstractQuery &other)
| Copies all bound values of the argument to this query.
Methods for composing a query (DynamicBinding only)
Query< Result, BindStrategy > & | join (const std::string &other)
| Adds a join.
template<typename C >
Query< Result, BindStrategy > & | join (const std::string &alias, const std::string &condition)
| Adds a join.
Query< Result, BindStrategy > & | leftJoin (const std::string &other)
| Adds a left join.
template<typename C >
Query< Result, BindStrategy > & | leftJoin (const std::string &alias, const std::string &condition)
| Adds a left join.
Query< Result, BindStrategy > & | rightJoin (const std::string &other)
| Adds a right join.
template<typename C >
Query< Result, BindStrategy > & | rightJoin (const std::string &alias, const std::string &condition)
| Adds a right join.
Query< Result, BindStrategy > & | where (const std::string &condition)
| Adds a query condition.
Query< Result, BindStrategy > & | orWhere (const std::string &condition)
| Adds a query condition.
Query< Result, BindStrategy > & | orderBy (const std::string &fieldName)
| Sets the result order.
Query< Result, BindStrategy > & | groupBy (const std::string &fields)
| Sets the grouping field(s).
Query< Result, BindStrategy > & | having (const std::string &fields)
| Sets the grouping filter(s).
Query< Result, BindStrategy > & | offset (int count)
| Sets a result offset.
int | offset () const
| Returns an offset set for this query.
Query< Result, BindStrategy > & | limit (int count)
| Sets a result limit.
int | limit () const
| Returns a limit set for this query.
Public Member Functions inherited from Wt::Dbo::AbstractQuery
template<typename T >
AbstractQuery & | bind (const T &value)
| Binds a value to the next positional marker.
void | reset ()
| Resets bound values.
AbstractQuery & | join (const std::string &other)
| Adds a join.
AbstractQuery & | leftJoin (const std::string &other)
| Adds a left join.
AbstractQuery & | rightJoin (const std::string &other)
| Adds a right join.
AbstractQuery & | where (const std::string &condition)
| Adds a query condition.
AbstractQuery & | orWhere (const std::string &condition)
| Adds a query condition.
AbstractQuery & | orderBy (const std::string &fieldName)
| Sets the result order.
AbstractQuery & | groupBy (const std::string &fields)
| Sets the grouping field(s).
AbstractQuery & | having (const std::string &fields)
| Sets the grouping filter(s).
AbstractQuery & | offset (int count)
| Sets a result offset.
int | offset () const
| Returns an offset set for this query.
AbstractQuery & | limit (int count)
| Sets a result limit.
int | limit () const
| Returns a limit set for this query.

## Detailed Description

template<class Result, typename BindStrategy>
class Wt::Dbo::Query< Result, BindStrategy >

A database query.

The query fetches results of type `Result` from the database. This can be any type for which query_result_traits are properly implemented. The library provides these implementations for primitive values (see sql_value_traits), database objects (ptr) and `std::tuple`.

Simple queries can be done using Session::find(), while more elaborate queries (with arbitrary result types) using Session::query().

You may insert positional holders anywhere in the query for parameters using '?', and bind these to actual values using bind().

The query result may be fetched using resultValue() or resultList().

Usage example:

typedef Wt::Dbo::ptr<Account> AccountPtr;
typedef Wt::Dbo::collection<AccountPtr> Accounts;
Wt::Dbo::Query<AccountPtr> query = session.find<Account>().where("balance > ?").bind(100000);
Accounts accounts = query.resultList();
for (Accounts::const_iterator i = accounts.begin(); i != accounts.end(); ++i)
std::cerr << "Name: " << (*i)->name << std::end;
Wt::Dbo::Query
A database query.
Definition WGlobal.h:284
Wt::Dbo::Query::session
Session & session() const
Returns the session.
Wt::Dbo::Query::where
Query< Result, BindStrategy > & where(const std::string &condition)
Adds a query condition.
Wt::Dbo::Query::resultList
collection< Result > resultList() const
Returns a result list.
Wt::Dbo::Session::find
Query< ptr< C >, BindStrategy > find(const std::string &condition=std::string())
Finds database objects.
Definition Session_impl.h:265
Wt::Dbo::collection
An STL container for iterating query results.
Definition WGlobal.h:280
Wt::Dbo::ptr
A smart pointer for a database object.
Definition WGlobal.h:283

The `BindStrategy` specifies how you want to bind parameters to your query (if any).

When using DynamicBinding (which is the default), parameter binding to an actual sql statement is deferred until the query is run. This has the advantage that you can compose the query definition using helper methods provided in the query object (where(), orWhere(), groupBy(), having() and orderBy()), possibly intermixing this with parameter binding, and you can keep the query around and run the query multiple times, perhaps with different parameter values or to scroll through the query results. The where(), orWhere(), groupBy(), having(), and orderBy() are merely convenience methods which you may use to compose the querys incrementally, but you may just as well specify the entire SQL as a single string.

When using DirectBinding, parameters are directly bound to an underlying sql statement. Therefore, the query must be specified entirely when created. Because of this reliance on an sql statement, it can be run only once (one call to resultValue() or resultList()) after which it should be discarded. You should not try to keep a query object around when using this parameter binding strategy (that will amost always not do what you would hope it to do).

## Member Function Documentation

## ◆ asString()

template<class Result , typename BindStrategy >

std::string Wt::Dbo::Query< Result, BindStrategy >::asString | ( |  | ) | const

Returns the SQL of the query as a string.

The returned string can be used as a subquery in another query. The bound values can be copied to the other query using Query::bindSubqueryValues().

Note
  This method is not available when using a DirectBinding binding strategy.

## ◆ bind()

template<class Result , typename BindStrategy >
template<typename T >

Query< Result, BindStrategy > & Wt::Dbo::Query< Result, BindStrategy >::bind | ( | const T & | value | ) |

Binds a value to the next positional marker.

This binds the `value` to the next positional marker in the query condition.

## ◆ bindSubqueryValues()

template<class Result , typename BindStrategy >

Query< Result, BindStrategy > & Wt::Dbo::Query< Result, BindStrategy >::bindSubqueryValues | ( | const AbstractQuery< Result, BindStrategy > & | other | ) |

Copies all bound values of the argument to this query.

This method should be used together with asString(). When a subquery is added, all of its bound values must be copied to this query.

This can be used as follows (query all paintings more expensive than any Vermeer):

auto maxPriceQuery = session.query<int>("select MAX(p.price) from \"painting\" as p")
.where("p.artist = ?").bind("Vermeer");
auto q = session.query<dbo::ptr<Painting>>("select p from \"painting\" as p")
.where("p.price > (" + maxPriceQuery.asString() + ")").bindSubqueryValues(maxPriceQuery);
Wt::Dbo::Session::query
Query< Result, BindStrategy > query(const std::string &sql)
Creates a query.
Definition Session_impl.h:280

which is equivalent to this code:

auto q = session.query<dbo::ptr<Painting>>(
"select p from \"painting\" as p "
"where p.price > (select MAX(p.price) from \"painting\" as p "
" where p.artist = ?)")
.bind("Vermeer");
Wt::Dbo::Query::bind
Query< Result, BindStrategy > & bind(const T &value)
Binds a value to the next positional marker.

Note
  This method is not available when using a DirectBinding binding strategy.

## ◆ groupBy()

template<class Result , typename BindStrategy >

Query< Result, BindStrategy > & Wt::Dbo::Query< Result, BindStrategy >::groupBy | ( | const std::string & | fields | ) |

Sets the grouping field(s).

This is a convenience method for creating a SQL query, and sets a group by field expression for the current query.

Groups results based on unique values of the indicated field(s), which is a comma separated list of fields. Only fields on which you group and aggregate functions can be selected by a query.

A field that refers to a database object that is selected by the query is expanded to all the corresponding fields of that database object (as in the select statement).

Note
  This method is not available when using a DirectBinding binding strategy.

## ◆ having()

template<class Result , typename BindStrategy >

Query< Result, BindStrategy > & Wt::Dbo::Query< Result, BindStrategy >::having | ( | const std::string & | fields | ) |

Sets the grouping filter(s).

It's like where(), but for aggregate fields.

For example you can't go:

select department.name, count(employees) from department where count(employees) > 5 group by count(employees);

Because you can't have aggregate fields in a where clause, but you can go:

select department.name, count(employees) from department group by count(employees) having count(employees) > 5;

This will of course return all the departments with more than 5 employees (and their employee count).

Note
  This method is not available when using a DirectBinding binding strategy.
  You must have a group by clause, in order to have a 'having' clause

## ◆ join() [1/2]

template<class Result , typename BindStrategy >
template<typename C >

Query< Result, BindStrategy > & Wt::Dbo::Query< Result, BindStrategy >::join | ( | const std::string & | alias,
|  | const std::string & | condition )

Adds a join.

This is a convenience method for creating a SQL query, and concatenates a new join to the current query. The method uses the name supplied to Session::mapClass() as the table name for the template argument and the first method argument as an alias. The second argument is the condition following the "on" keyword.

Usage example:

// ...
session->mapClass<A>("table_a");
session->mapClass<B>("table_b");
// ...
using ResultType = std::tuple< Wt::Dbo::ptr<A>, Wt::Dbo::ptr<B> >;
auto results = session.query<ResultType>("select a, b from \"table_a\" a")
.join<B>("b", "a.b_id = b.id");
Wt::Dbo::Query::join
Query< Result, BindStrategy > & join(const std::string &other)
Adds a join.
Wt::Dbo::Session::mapClass
void mapClass(const char *tableName)
Maps a class to a database table.
Definition Session_impl.h:40
Wt::Key::A
@ A
'A' key
Wt::Key::B
@ B
'B' key

Note
  This method is not available when using a DirectBinding binding strategy.

## ◆ join() [2/2]

template<class Result , typename BindStrategy >

Query< Result, BindStrategy > & Wt::Dbo::Query< Result, BindStrategy >::join | ( | const std::string & | other | ) |

Adds a join.

This is a convenience method for creating a SQL query, and concatenates a new join to the current query.

The join should be a valid SQL join expression, e.g. "customer c on o.customer_id = c.id"

Note
  This method is not available when using a DirectBinding binding strategy.

## ◆ leftJoin() [1/2]

template<class Result , typename BindStrategy >
template<typename C >

Query< Result, BindStrategy > & Wt::Dbo::Query< Result, BindStrategy >::leftJoin | ( | const std::string & | alias,
|  | const std::string & | condition )

Adds a left join.

This is a convenience method for creating a SQL query, and concatenates a new left join to the current query. The method uses the name supplied to Session::mapClass() as the table name for the template argument and the first method argument as an alias. The second argument is the condition following the "on" keyword.

Usage example:

// ...
session->mapClass<A>("table_a");
session->mapClass<B>("table_b");
// ...
using ResultType = std::tuple< Wt::Dbo::ptr<A>, Wt::Dbo::ptr<B> >;
auto results = session.query<ResultType>("select a, b from \"table_a\" a")
.leftJoin<B>("b", "a.b_id = b.id");
Wt::Dbo::Query::leftJoin
Query< Result, BindStrategy > & leftJoin(const std::string &other)
Adds a left join.

Note
  This method is not available when using a DirectBinding binding strategy.

## ◆ leftJoin() [2/2]

template<class Result , typename BindStrategy >

Query< Result, BindStrategy > & Wt::Dbo::Query< Result, BindStrategy >::leftJoin | ( | const std::string & | other | ) |

Adds a left join.

This is a convenience method for creating a SQL query, and concatenates a new left join to the current query.

The join should be a valid SQL join expression, e.g. "customer c on o.customer_id = c.id"

Note
  This method is not available when using a DirectBinding binding strategy.

## ◆ limit() [1/2]

template<class Result , typename BindStrategy >

int Wt::Dbo::Query< Result, BindStrategy >::limit | ( |  | ) | const

Returns a limit set for this query.

See also
  limit(int)

## ◆ limit() [2/2]

template<class Result , typename BindStrategy >

Query< Result, BindStrategy > & Wt::Dbo::Query< Result, BindStrategy >::limit | ( | int | count | ) |

Sets a result limit.

Sets a result limit. This has the effect that the next resultList() call will return up to `count` results. Use -1 to indicate no limit.

This provides the (non standard) limit part of an SQL query.

See also
  offset()

Note
  This method is not available when using a DirectBinding binding strategy.

## ◆ offset() [1/2]

template<class Result , typename BindStrategy >

int Wt::Dbo::Query< Result, BindStrategy >::offset | ( |  | ) | const

Returns an offset set for this query.

See also
  offset(int)

## ◆ offset() [2/2]

template<class Result , typename BindStrategy >

Query< Result, BindStrategy > & Wt::Dbo::Query< Result, BindStrategy >::offset | ( | int | count | ) |

Sets a result offset.

Sets a result offset. This has the effect that the next resultList() call will skip as many results as the offset indicates. Use -1 to indicate no offset.

This provides the (non standard) offset part of an SQL query.

See also
  limit()

Note
  This method is not available when using a DirectBinding binding strategy.

## ◆ operator collection< Result >()

template<class Result , typename BindStrategy >

Wt::Dbo::Query< Result, BindStrategy >::operator collection< Result > | ( |  | ) | const

Returns a result list.

This is a convenience conversion operator that calls resultList().

## ◆ operator Result()

template<class Result , typename BindStrategy >

Wt::Dbo::Query< Result, BindStrategy >::operator Result | ( |  | ) | const

Returns a unique result value.

This is a convenience conversion operator that calls resultValue().

## ◆ orderBy()

template<class Result , typename BindStrategy >

Query< Result, BindStrategy > & Wt::Dbo::Query< Result, BindStrategy >::orderBy | ( | const std::string & | fieldName | ) |

Sets the result order.

This is a convenience method for creating a SQL query, and sets an order by field expression for the current query.

Orders the results based on the given field name (or multiple names, comma-separated).

Note
  This method is not available when using a DirectBinding binding strategy.

## ◆ orWhere()

template<class Result , typename BindStrategy >

Query< Result, BindStrategy > & Wt::Dbo::Query< Result, BindStrategy >::orWhere | ( | const std::string & | condition | ) |

Adds a query condition.

This is a convenience method for creating a SQL query, and concatenates a new where condition expression to the current query.

The condition must be a valid SQL condition expression.

Multiple conditions may be provided by successive calls to orWhere(), and are concatenated together using 'or'. Previous conditions will be surrounded by brackets and the new condition will be concatenated using 'or'. For example:

query.where("column_a = ?").bind("A")
.where("column_b = ?").bind("B")
.orWhere("column_c = ?").bind("C");

results in: "where ((column_a = 'A') and (column_b = 'B')) or column_c = 'C'"

As with any part of the SQL query, a condition may contain positional markers '?' to which values may be bound using bind().

Note
  This method is not available when using a DirectBinding binding strategy.

## ◆ reset()

template<class Result , typename BindStrategy >

void Wt::Dbo::Query< Result, BindStrategy >::reset | ( |  | ) |

Resets bound values.

This undoes all previous calls to bind().

## ◆ resultList()

template<class Result , typename BindStrategy >

collection< Result > Wt::Dbo::Query< Result, BindStrategy >::resultList | ( |  | ) | const

Returns a result list.

This returns a collection which is backed by the underlying query. The query is not actually run until this collection is traversed or its size is asked.

When using a DynamicBinding bind strategy, after a result has been fetched, the query can no longer be used.

## ◆ resultValue()

template<class Result , typename BindStrategy >

Result Wt::Dbo::Query< Result, BindStrategy >::resultValue | ( |  | ) | const

Returns a unique result value.

You can use this method if you are expecting the query to return at most one result. If the query returns more than one result a NoUniqueResultException is thrown.

When using a DynamicBinding bind strategy, after a result has been fetched, the query can no longer be used.

## ◆ rightJoin() [1/2]

template<class Result , typename BindStrategy >
template<typename C >

Query< Result, BindStrategy > & Wt::Dbo::Query< Result, BindStrategy >::rightJoin | ( | const std::string & | alias,
|  | const std::string & | condition )

Adds a right join.

This is a convenience method for creating a SQL query, and concatenates a new right join to the current query. The method uses the name supplied to Session::mapClass() as the table name for the template argument and the first method argument as an alias. The second argument is the condition following the "on" keyword.

Usage example:

// ...
session->mapClass<A>("table_a");
session->mapClass<B>("table_b");
// ...
using ResultType = std::tuple< Wt::Dbo::ptr<A>, Wt::Dbo::ptr<B> >;
auto results = session.query<ResultType>("select a, b from \"table_a\" a")
.rightJoin<B>("b", "a.b_id = b.id");
Wt::Dbo::Query::rightJoin
Query< Result, BindStrategy > & rightJoin(const std::string &other)
Adds a right join.

Note
  This method is not available when using a DirectBinding binding strategy.

## ◆ rightJoin() [2/2]

template<class Result , typename BindStrategy >

Query< Result, BindStrategy > & Wt::Dbo::Query< Result, BindStrategy >::rightJoin | ( | const std::string & | other | ) |

Adds a right join.

This is a convenience method for creating a SQL query, and concatenates a new right join to the current query.

The join should be a valid SQL join expression, e.g. "customer c on o.customer_id = c.id"

Note
  This method is not available when using a DirectBinding binding strategy.

## ◆ where()

template<class Result , typename BindStrategy >

Query< Result, BindStrategy > & Wt::Dbo::Query< Result, BindStrategy >::where | ( | const std::string & | condition | ) |

Adds a query condition.

This is a convenience method for creating a SQL query, and concatenates a new where condition expression to the current query.

The condition must be a valid SQL condition expression.

Multiple conditions may be provided by successive calls to where(), which must each be fulfilled, and are concatenated together using 'and'.

As with any part of the SQL query, a condition may contain positional markers '?' to which values may be bound using bind().

Note
  This method is not available when using a DirectBinding binding strategy.