aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-01-24 15:10:21 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-01-24 15:10:21 +0200
commit1fa74e93cbc6ec0cc8ca8e6b653d1b530c01744a (patch)
treebd6c172a39959b4069e648b5599db8a206c216fb
parentec2ad3cce4c5feb1dabd1fe87dc26799722def19 (diff)
Add support for mapping char[N] to CHAR/VARCHAR database types
Also improve query support for arrays (decaying).
-rw-r--r--odb/query-dynamic.hxx52
-rw-r--r--odb/query.hxx24
2 files changed, 66 insertions, 10 deletions
diff --git a/odb/query-dynamic.hxx b/odb/query-dynamic.hxx
index ed32ec9..4f5de9f 100644
--- a/odb/query-dynamic.hxx
+++ b/odb/query-dynamic.hxx
@@ -24,19 +24,51 @@ namespace odb
template <typename T>
struct val_bind
{
+ typedef const T& type;
+
explicit
- val_bind (const T& v): val (v) {}
+ val_bind (type v): val (v) {}
- const T& val;
+ type val;
};
+ // Passing arrays by value in dynamic queries is not supported.
+ // Pass by reference instead.
+ //
+ template <typename T, std::size_t N>
+ struct val_bind<T[N]>;
+
template <typename T>
struct ref_bind
{
+ typedef const T& type;
+
+ explicit
+ ref_bind (type r): ref (r) {}
+
+ const void*
+ ptr () const {return &ref;}
+
+ type ref;
+ };
+
+ template <typename T, std::size_t N>
+ struct ref_bind<T[N]>
+ {
+ typedef const T* type;
+
explicit
- ref_bind (const T& r): ref (r) {}
+ ref_bind (type r): ref (r) {}
+
+ // Allow implicit conversion from decayed ref_bind's.
+ //
+ ref_bind (ref_bind<T*> r): ref (r.ref) {}
+ ref_bind (ref_bind<const T*> r): ref (r.ref) {}
+
+ const void*
+ ptr () const {return ref;}
- const T& ref;
+ type ref;
};
//
@@ -384,7 +416,7 @@ namespace odb
equal (ref_bind<T> r) const
{
query_base q (native_info);
- q.append_ref (&r.ref, native_info);
+ q.append_ref (r.ptr (), native_info);
q.append (query_base::clause_part::op_eq, 0);
return q;
}
@@ -455,7 +487,7 @@ namespace odb
unequal (ref_bind<T> r) const
{
query_base q (native_info);
- q.append_ref (&r.ref, native_info);
+ q.append_ref (r.ptr (), native_info);
q.append (query_base::clause_part::op_ne, 0);
return q;
}
@@ -526,7 +558,7 @@ namespace odb
less (ref_bind<T> r) const
{
query_base q (native_info);
- q.append_ref (&r.ref, native_info);
+ q.append_ref (r.ptr (), native_info);
q.append (query_base::clause_part::op_lt, 0);
return q;
}
@@ -597,7 +629,7 @@ namespace odb
greater (ref_bind<T> r) const
{
query_base q (native_info);
- q.append_ref (&r.ref, native_info);
+ q.append_ref (r.ptr (), native_info);
q.append (query_base::clause_part::op_gt, 0);
return q;
}
@@ -668,7 +700,7 @@ namespace odb
less_equal (ref_bind<T> r) const
{
query_base q (native_info);
- q.append_ref (&r.ref, native_info);
+ q.append_ref (r.ptr (), native_info);
q.append (query_base::clause_part::op_le, 0);
return q;
}
@@ -739,7 +771,7 @@ namespace odb
greater_equal (ref_bind<T> r) const
{
query_base q (native_info);
- q.append_ref (&r.ref, native_info);
+ q.append_ref (r.ptr (), native_info);
q.append (query_base::clause_part::op_ge, 0);
return q;
}
diff --git a/odb/query.hxx b/odb/query.hxx
index adea4b3..67de520 100644
--- a/odb/query.hxx
+++ b/odb/query.hxx
@@ -51,6 +51,30 @@ namespace odb
}
};
+ // Query parameter decay traits.
+ //
+ template <typename T>
+ struct decay_traits
+ {
+ typedef const T& type;
+
+ static type
+ instance ();
+ };
+
+ template <typename T, std::size_t N>
+ struct decay_traits<T[N]>
+ {
+ typedef const T* type;
+
+ // Use the pointer comparability as a proxy for data comparability.
+ // Note that it is stricter than using element comparability (i.e.,
+ // one can compare int to char but not int* to char*).
+ //
+ static type
+ instance ();
+ };
+
// VC9 cannot handle certain cases of non-type arguments with default
// values in template functions (e.g., database::query()). As a result,
// we have to use the impl trick below instead of simply having kind