Skip to content

Commit

Permalink
Implement sequence-related functions for ODBC backend.
Browse files Browse the repository at this point in the history
Determine which kind of database we're connected to and implement either
get_next_sequence_value() or get_last_insert_id() using database-specific
queries depending on it.

Signed-off-by: Vadim Zeitlin <vz-soci@zeitlins.org>
  • Loading branch information
vadz committed Jul 10, 2012
1 parent c3afdf2 commit 49278cb
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
83 changes: 83 additions & 0 deletions src/backends/odbc/session.cpp
Expand Up @@ -7,6 +7,7 @@

#define SOCI_ODBC_SOURCE
#include "soci-odbc.h"
#include "session.h"

using namespace soci;
using namespace soci::details;
Expand Down Expand Up @@ -95,6 +96,88 @@ void odbc_session_backend::rollback()
reset_transaction();
}

bool odbc_session_backend::get_next_sequence_value(
session & s, std::string const & sequence, long & value)
{
std::string query;

switch ( get_database_product() )
{
case prod_firebird:
query = "select next value for " + sequence + " from rdb$database";
break;

case prod_oracle:
query = "select " + sequence + ".nextval from dual";
break;

case prod_postgresql:
query = "select nextval('" + sequence + "')";
break;

case prod_mssql:
case prod_mysql:
case prod_sqlite:
// These RDBMS implement get_last_insert_id() instead.
return false;

case prod_unknown:
// For this one we can't do anything at all.
return false;

case prod_uninitialized:
// This is not supposed to happen at all but still cover this case
// here to avoid gcc warnings about unhandled enum values in a
// switch.
return false;
}

s << query, into(value);

return true;
}

bool odbc_session_backend::get_last_insert_id(
session & s, std::string const & table, long & value)
{
std::string query;

switch ( get_database_product() )
{
case prod_mssql:
query = "select ident_current('" + table + "')";
break;

case prod_mysql:
query = "select last_insert_id()";
break;

case prod_sqlite:
query = "select last_insert_rowid()";
break;

case prod_firebird:
case prod_oracle:
case prod_postgresql:
// For these RDBMS get_next_sequence_value() should have been used.
return false;


case prod_unknown:
// For this one we can't do anything at all.
return false;

case prod_uninitialized:
// As above, this is not supposed to happen but put it here to
// mollify gcc.
return false;
}

s << query, into(value);

return true;
}

void odbc_session_backend::reset_transaction()
{
SQLRETURN rc = SQLSetConnectAttr( hdbc_, SQL_ATTR_AUTOCOMMIT,
Expand Down
5 changes: 5 additions & 0 deletions src/backends/odbc/soci-odbc.h
Expand Up @@ -243,6 +243,11 @@ struct odbc_session_backend : details::session_backend
virtual void commit();
virtual void rollback();

virtual bool get_next_sequence_value(session & s,
std::string const & sequence, long & value);
virtual bool get_last_insert_id(session & s,
std::string const & table, long & value);

virtual std::string get_backend_name() const { return "odbc"; }

void reset_transaction();
Expand Down

0 comments on commit 49278cb

Please sign in to comment.