The get()
method executes a query that is expected to produce at most one record.
For such a query, get()
is preferable to begin()
: it is more efficient, because it doesn't
create an iterator, and to the reader of your code it clearly signals
that multiple records are not expected.
For any query q
with value type T
,
q
.get()
returns a boost::optional<
T
>
.
q
produces no records, q
.get()
returns boost::none
.
q
produces exactly one record, q
.get()
returns that record, wrapped in
a boost::optional
.
q
produces more than one record, q
.get()
treats it as an error and throws
multi_row_exception
.
(Perhaps you meant to call q
.limit(1).get()
.)
One common use case is simple record retrieval by a unique key, e.g. a primary key:
extern const serial bridge_on_the_river_quince_id; const boost::optional<movie> botrq = movies .where(movies->id==bridge_on_the_river_quince_id) .get();
or retrieval of part of such a record:
const boost::optional<std::string> botrq_title = movies .where(movies->id==bridge_on_the_river_quince_id) .select(movies->title) .get();
In these cases we know that the query will produce at most one output,
because the where(
...)
clause is applied directly to a table,
and tests for an exact match of a unique key. In other cases our knowledge
may be indirect. E.g., recall this definition
of local_hits
:
const query<movie> local_hits = local_movies .distinct() .order(- score(local_movies->id)) .limit(n);
With a moment's thought we can prove that this query never produces two
movie
s with the same
id
. Therefore it is safe
to “look up” an id
in local_hits
, just as
we did in movies
:
const boost::optional<movie> local_hit_botrq = local_hits .where(local_hits->id==bridge_on_the_river_quince_id) .get();
or:
const boost::optional<std::string> local_hit_botrq_title = local_hits .where(local_hits->id==bridge_on_the_river_quince_id) .select(local_hits->title) .get();