aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Shepanski <michael@codesynthesis.com>2014-11-04 16:10:03 +1100
committerBoris Kolpackov <boris@codesynthesis.com>2014-11-10 16:43:00 +0200
commit6375147d5ae76a84dd64f1996cb0d9d501839db6 (patch)
tree1240e3b8c1567fde1ae11d0c93e5b38c15111506
parent1f217e38f7507758da1d33d46e675e801621aa38 (diff)
Implement {query,execute}_{one,value}() shortcut functions
Useful in situations where the query is know to return at most one element (*_one) or exactly one element (*_value).
-rw-r--r--odb/database.hxx62
-rw-r--r--odb/database.ixx110
-rw-r--r--odb/prepared-query.hxx23
-rw-r--r--odb/result.hxx19
-rw-r--r--odb/result.txx52
5 files changed, 266 insertions, 0 deletions
diff --git a/odb/database.hxx b/odb/database.hxx
index 4e59aaf..1f56b7f 100644
--- a/odb/database.hxx
+++ b/odb/database.hxx
@@ -242,6 +242,56 @@ namespace odb
result<T>
query (const odb::query<T>&, bool cache = true);
+ // Query one API.
+ //
+ template <typename T>
+ typename object_traits<T>::pointer_type
+ query_one ();
+
+ template <typename T>
+ bool
+ query_one (T& object);
+
+ template <typename T>
+ T
+ query_value ();
+
+ template <typename T>
+ typename object_traits<T>::pointer_type
+ query_one (const char*);
+
+ template <typename T>
+ bool
+ query_one (const char*, T& object);
+
+ template <typename T>
+ T
+ query_value (const char*);
+
+ template <typename T>
+ typename object_traits<T>::pointer_type
+ query_one (const std::string&);
+
+ template <typename T>
+ bool
+ query_one (const std::string&, T& object);
+
+ template <typename T>
+ T
+ query_value (const std::string&);
+
+ template <typename T>
+ typename object_traits<T>::pointer_type
+ query_one (const odb::query<T>&);
+
+ template <typename T>
+ bool
+ query_one (const odb::query<T>&, T& object);
+
+ template <typename T>
+ T
+ query_value (const odb::query<T>&);
+
// Query preparation.
//
template <typename T>
@@ -487,6 +537,18 @@ namespace odb
void
erase_ (const typename object_traits<T>::pointer_type&);
+ template <typename T, database_id DB, typename Q>
+ typename object_traits<T>::pointer_type
+ query_one_ (const Q&);
+
+ template <typename T, database_id DB, typename Q>
+ bool
+ query_one_ (const Q&, T&);
+
+ template <typename T, database_id DB, typename Q>
+ T
+ query_value_ (const Q&);
+
template <typename T,
database_id DB,
class_kind kind = class_traits<T>::kind>
diff --git a/odb/database.ixx b/odb/database.ixx
index 6cfbeec..739db03 100644
--- a/odb/database.ixx
+++ b/odb/database.ixx
@@ -473,6 +473,90 @@ namespace odb
}
template <typename T>
+ inline typename object_traits<T>::pointer_type database::
+ query_one ()
+ {
+ return query_one<T> (odb::query<T> ());
+ }
+
+ template <typename T>
+ inline bool database::
+ query_one (T& o)
+ {
+ return query_one<T> (odb::query<T> (), o);
+ }
+
+ template <typename T>
+ inline T database::
+ query_value ()
+ {
+ return query_value<T> (odb::query<T> ());
+ }
+
+ template <typename T>
+ inline typename object_traits<T>::pointer_type database::
+ query_one (const char* q)
+ {
+ return query_one<T> (odb::query<T> (q));
+ }
+
+ template <typename T>
+ inline bool database::
+ query_one (const char* q, T& o)
+ {
+ return query_one<T> (odb::query<T> (q), o);
+ }
+
+ template <typename T>
+ inline T database::
+ query_value (const char* q)
+ {
+ return query_value<T> (odb::query<T> (q));
+ }
+
+ template <typename T>
+ inline typename object_traits<T>::pointer_type database::
+ query_one (const std::string& q)
+ {
+ return query_one<T> (odb::query<T> (q));
+ }
+
+ template <typename T>
+ inline bool database::
+ query_one (const std::string& q, T& o)
+ {
+ return query_one<T> (odb::query<T> (q), o);
+ }
+
+ template <typename T>
+ inline T database::
+ query_value (const std::string& q)
+ {
+ return query_value<T> (odb::query<T> (q));
+ }
+
+ template <typename T>
+ inline bool database::
+ query_one (const odb::query<T>& q, T& o)
+ {
+ return query_one_<T, id_common> (q, o);
+ }
+
+ template <typename T>
+ inline typename object_traits<T>::pointer_type database::
+ query_one (const odb::query<T>& q)
+ {
+ return query_one_<T, id_common> (q);
+ }
+
+ template <typename T>
+ inline T database::
+ query_value (const odb::query<T>& q)
+ {
+ return query_value_<T, id_common> (q);
+ }
+
+ template <typename T>
inline prepared_query<T> database::
prepare_query (const char* n, const char* q)
{
@@ -620,6 +704,32 @@ namespace odb
erase_<T, DB> (pointer_traits<pointer_type>::get_ref (pobj));
}
+ template <typename T, database_id DB, typename Q>
+ inline typename object_traits<T>::pointer_type database::
+ query_one_ (const Q& q)
+ {
+ return query_<T, DB>::call (*this, q).one ();
+ }
+
+ template <typename T, database_id DB, typename Q>
+ inline bool database::
+ query_one_ (const Q& q, T& o)
+ {
+ return query_<T, DB>::call (*this, q).one (o);
+ }
+
+ template <typename T, database_id DB, typename Q>
+ inline T database::
+ query_value_ (const Q& q)
+ {
+ // Compiler error pointing here? The object must be default-constructible
+ // in order to use the return-by-value API.
+ //
+ T o;
+ query_<T, DB>::call (*this, q).value (o);
+ return o;
+ }
+
// execute()
//
inline unsigned long long database::
diff --git a/odb/prepared-query.hxx b/odb/prepared-query.hxx
index b321564..5fc4783 100644
--- a/odb/prepared-query.hxx
+++ b/odb/prepared-query.hxx
@@ -86,6 +86,29 @@ namespace odb
return r;
}
+ typename object_traits<T>::pointer_type
+ execute_one ()
+ {
+ return execute (false).one ();
+ }
+
+ bool
+ execute_one (T& object)
+ {
+ return execute (false).one (object);
+ }
+
+ T
+ execute_value ()
+ {
+ // Compiler error pointing here? The object must be default-
+ // constructible in order to use the return-by-value API.
+ //
+ T o;
+ execute (false).value (o);
+ return o;
+ }
+
const char*
name () const
{
diff --git a/odb/result.hxx b/odb/result.hxx
index 93c0dce..5f84342 100644
--- a/odb/result.hxx
+++ b/odb/result.hxx
@@ -209,6 +209,23 @@ namespace odb
return impl_ ? impl_->size () : 0;
}
+ // query_one() and query_value() implementation details.
+ //
+ public:
+ typename object_traits<T>::pointer_type
+ one ();
+
+ bool
+ one (T&);
+
+ // We cannot return by value here since result can be instantiated
+ // for an abstract type (polymorphic abstract base) and it seems
+ // the signature must be valid to the point being able to call the
+ // necessary constructors.
+ //
+ void
+ value (T&);
+
private:
friend class result<const T>;
@@ -222,6 +239,8 @@ namespace odb
}
}
+#include <odb/result.txx>
+
#include <odb/post.hxx>
#endif // ODB_RESULT_HXX
diff --git a/odb/result.txx b/odb/result.txx
new file mode 100644
index 0000000..c1bed1c
--- /dev/null
+++ b/odb/result.txx
@@ -0,0 +1,52 @@
+// file : odb/result.txx
+// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#include <cassert>
+
+namespace odb
+{
+ template <typename T>
+ typename object_traits<T>::pointer_type result<T>::
+ one ()
+ {
+ typedef typename object_traits<T>::pointer_type pointer_type;
+
+ iterator i (begin ());
+
+ if (i != end ())
+ {
+ pointer_type o (i.load ());
+ assert (++i == end ()); // More than one element in query_one() result.
+ return o;
+ }
+
+ return pointer_type ();
+ }
+
+ template <typename T>
+ bool result<T>::
+ one (T& o)
+ {
+ iterator i (begin ());
+
+ if (i != end ())
+ {
+ i.load (o);
+ assert (++i == end ()); // More than one element in query_one() result.
+ return true;
+ }
+
+ return false;
+ }
+
+ template <typename T>
+ void result<T>::
+ value (T& o)
+ {
+ iterator i (begin ());
+ assert (i != end ()); // Zero elements in query_value() result.
+ i.load (o);
+ assert (++i == end ()); // More than one element in query_value() result.
+ }
+}