[odb-users] Executing native selects for no mapped type
Roland Kloeters
roland.kloeters at xcom.de
Wed Aug 17 07:34:17 EDT 2011
Hi Boris,
of course there is a way I could use.
I would prefer to use
#pragma db view query("SELECT nextval('sequence')")
struct sequence_value
{
unsigned long long value;
};
result r (db->query<sequence_value> ());
Or you could specify the actual sequence name at the query execution
time:
#pragma db view
struct sequence_value
{
unsigned long long value;
};
string seq_name = ...;
result r (
db->query<sequence_value> (
"SELECT nextval('" + query::_val (seq_name) + "')");
Unfortunately my ODB Compiler is not willing to know the pragma "view".
I get an error like "Sequence.h:16:19: error: unknown db pragma 'view'"
What now?
Kind regards
Roland
Am Mittwoch, den 17.08.2011, 12:51 +0200 schrieb Boris Kolpackov:
> Hi Roland,
>
> Roland Kloeters <roland.kloeters at xcom.de> writes:
>
> > As I cannot set the value by default using #pragma db id auto I have to
> > select the value from the sequence directly.
> >
> > I am using postgresql as RDMS so my select would be: "select
> > nextval('sequence')".
> >
> > [...]
> >
> > Is there any chance of executing native select statements and retrieving
> > the results?
>
> One way to do it would be to get the native Postgres connection handle
> from odb::pgsql::connection and execute the query using the low-level
> C API (libpq). This is not the most convenient way but it is always an
> option.
>
> Also we have been thinking about supporting what we call 'view' objects.
> A view is a read-only object that can only be loaded using a query. They
> could be useful for retrieving only a porting of an object, supporting
> ad-hoc table joins, or performing stored procedure calls. Here is an
> example:
>
> #pragma db view query("SELECT person.name, employer.name FROM person LEFT JOIN employer ON person.employer = employer.id")
> struct name_and_employer
> {
> string name;
> string employer;
> };
>
> typedef query<name_and_employer> query;
> typedef result<name_and_employer> result;
>
> result r (
> db->query<name_and_employer> (
> "WHERE person.age < " + query::_val(30));
>
> Your case would have been handled like this:
>
> #pragma db view query("SELECT nextval('sequence')")
> struct sequence_value
> {
> unsigned long long value;
> };
>
> result r (db->query<sequence_value> ());
>
> Or you could specify the actual sequence name at the query execution time:
>
> #pragma db view
> struct sequence_value
> {
> unsigned long long value;
> };
>
> string seq_name = ...;
>
> result r (
> db->query<sequence_value> (
> "SELECT nextval('" + query::_val (seq_name) + "')");
>
> Do you think something like this will work well for your use case?
>
> In fact, it is possible to kind of emulate views using the existing
> objects functionality. First we define the object (it must contain
> the dummy object id):
>
> #pragma db object
> struct sequence_value
> {
> #pragma db id
> unsigned int dummy;
>
> unsigned long long value;
> };
>
> Then the transaction that gets the next value would look like this
> (PostgreSQL-specific code):
>
> #include <odb/pgsql/result.hxx>
> #include <odb/pgsql/connection.hxx>
> #include <odb/pgsql/transaction-impl.hxx>
>
> namespace pgsql = odb::pgsql;
>
> transaction t (db->begin ());
>
> odb::result<sequence_value> r;
>
> {
> pgsql::connection& conn (pgsql::transaction::current ().connection ());
>
> odb::query<sequence_value> q;
>
> odb::details::shared_ptr<pgsql::select_statement> st (
> new (odb::details::shared) pgsql::select_statement (
> conn,
> "sequence_value_query" // Statement name.
> "select 0, nextval('sequence')",
> q.parameter_types (),
> q.parameter_count (),
> q.parameters_binding (),
> conn.statement_cache ().find<sequence_value> ().out_image_binding ()));
>
> st->execute ();
> st->deallocate ();
>
> odb::details::shared_ptr<odb::result_impl<sequence_value> > ri (
> new (odb::details::shared) pgsql::result_impl<sequence_value> (
> q, st, conn.statement_cache ().find<sequence_value> ()));
>
> r = odb::result<sequence_value> (ri);
> }
>
> // Iterate over the query result as usual. For example, r->begin ()->value
> // is the returned sequence value.
>
> t.commit ();
>
> This could be a temporary solution until views are supported natively by
> ODB.
>
> Boris
More information about the odb-users
mailing list