summaryrefslogtreecommitdiff
path: root/ADBC/adbc
diff options
context:
space:
mode:
authorJames H. Hill <hilljh82@gmail.com>2010-01-04 06:04:32 +0000
committerJames H. Hill <hilljh82@gmail.com>2010-01-04 06:04:32 +0000
commitfa73865b3a0ffaf7cf74fc936f040cbed855dfdb (patch)
treeefc91d03c0f3cd0db67ad33c97b07763a8a147a9 /ADBC/adbc
parent642d0d9813dbc1f5757041fc1838f7b859a633d2 (diff)
downloadATCD-fa73865b3a0ffaf7cf74fc936f040cbed855dfdb.tar.gz
Mon Jan 4 06:02:42 UTC 2010 James H. Hill <hillj at cs dot iupui dot edu>
Diffstat (limited to 'ADBC/adbc')
-rw-r--r--ADBC/adbc/ODBC/ODBC.mpc22
-rw-r--r--ADBC/adbc/ODBC/ODBC_Connection.cpp88
-rw-r--r--ADBC/adbc/ODBC/ODBC_Connection.h93
-rw-r--r--ADBC/adbc/ODBC/ODBC_Connection.inl28
-rw-r--r--ADBC/adbc/ODBC/ODBC_Env.cpp114
-rw-r--r--ADBC/adbc/ODBC/ODBC_Env.h72
-rw-r--r--ADBC/adbc/ODBC/ODBC_Env.inl28
-rw-r--r--ADBC/adbc/ODBC/ODBC_Exception.cpp47
-rw-r--r--ADBC/adbc/ODBC/ODBC_Exception.h74
-rw-r--r--ADBC/adbc/ODBC/ODBC_Exception.inl37
-rw-r--r--ADBC/adbc/ODBC/ODBC_Parameter.cpp97
-rw-r--r--ADBC/adbc/ODBC/ODBC_Parameter.h113
-rw-r--r--ADBC/adbc/ODBC/ODBC_Parameter.inl235
-rw-r--r--ADBC/adbc/ODBC/ODBC_Parameter_List.cpp38
-rw-r--r--ADBC/adbc/ODBC/ODBC_Parameter_List.h84
-rw-r--r--ADBC/adbc/ODBC/ODBC_Parameter_List.inl54
-rw-r--r--ADBC/adbc/ODBC/ODBC_Query.cpp173
-rw-r--r--ADBC/adbc/ODBC/ODBC_Query.h142
-rw-r--r--ADBC/adbc/ODBC/ODBC_Query.inl50
-rw-r--r--ADBC/adbc/ODBC/ODBC_Record.cpp85
-rw-r--r--ADBC/adbc/ODBC/ODBC_Record.h103
-rw-r--r--ADBC/adbc/ODBC/ODBC_Record.inl168
-rw-r--r--ADBC/adbc/ODBC/ODBC_Types.cpp50
-rw-r--r--ADBC/adbc/ODBC/ODBC_Types.h85
-rw-r--r--ADBC/adbc/ODBC/ODBC_Types.inl152
-rw-r--r--ADBC/adbc/ODBC/ODBC_export.h58
26 files changed, 2290 insertions, 0 deletions
diff --git a/ADBC/adbc/ODBC/ODBC.mpc b/ADBC/adbc/ODBC/ODBC.mpc
new file mode 100644
index 00000000000..2f0345d1242
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC.mpc
@@ -0,0 +1,22 @@
+// $Id$
+
+project (ADBC_ODBC) : odbc, adbc_lib {
+ sharedname += ADBC_ODBC
+ dynamicflags += ADBC_ODBC_BUILD_DLL
+
+ Source_Files {
+ ODBC_Connection.cpp
+ ODBC_Env.cpp
+ ODBC_Exception.cpp
+ ODBC_Parameter.cpp
+ ODBC_Parameter_List.cpp
+ ODBC_Query.cpp
+ ODBC_Record.cpp
+ ODBC_Types.cpp
+ }
+
+ Header_Files {
+ ODBC.h
+ ODBC_export.h
+ }
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Connection.cpp b/ADBC/adbc/ODBC/ODBC_Connection.cpp
new file mode 100644
index 00000000000..f27341d44c2
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Connection.cpp
@@ -0,0 +1,88 @@
+// $Id$
+
+#include "ODBC_Connection.h"
+
+#if !defined (__ADBC_INLINE__)
+#include "ODBC_Connection.inl"
+#endif
+
+#include "ODBC_Query.h"
+#include "ace/CORBA_macros.h"
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// init
+//
+void Connection::init (void)
+{
+ // Allocate the connection handle.
+ SQL_ENV_VERIFY (::SQLAllocHandle (SQL_HANDLE_DBC, this->env_, &this->handle_),
+ this->env_->handle ());
+}
+
+//
+// ~Connection
+//
+Connection::~Connection (void)
+{
+ if (this->handle_ != SQL_NULL_HANDLE)
+ ::SQLFreeHandle (SQL_HANDLE_DBC, this->handle_);
+}
+
+//
+// connect
+//
+void Connection::connect (const ACE_CString & connstr)
+{
+ // Remove this connection.
+ this->disconnect ();
+
+ // Establish a connection with the database.
+ short result = 0;
+ static SQLCHAR tempstr[1024];
+
+ SQL_CONN_VERIFY (::SQLDriverConnect (this->handle_,
+ 0,
+ (SQLCHAR *)connstr.c_str (),
+ connstr.length (),
+ tempstr,
+ sizeof (tempstr),
+ &result,
+ SQL_DRIVER_NOPROMPT),
+ this->handle_);
+
+ // Pass control to the base class.
+ ::ADBC::Connection::connect (connstr);
+}
+
+//
+// disconnect
+//
+void Connection::disconnect (void)
+{
+ if (this->handle_ != SQL_NULL_HDBC && this->is_connected ())
+ SQL_CONN_VERIFY (::SQLDisconnect (this->handle_),
+ this->handle_);
+
+ // Pass control to the base class.
+ ::ADBC::Connection::disconnect ();
+}
+
+//
+// create_query
+//
+Query * Connection::create_query (void)
+{
+ Query * query = 0;
+
+ ACE_NEW_THROW_EX (query,
+ Query (*this),
+ ACE_bad_alloc ());
+
+ return query;
+}
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Connection.h b/ADBC/adbc/ODBC/ODBC_Connection.h
new file mode 100644
index 00000000000..41eea1afd13
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Connection.h
@@ -0,0 +1,93 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ODBC_Connection.h
+ *
+ * $Id$
+ *
+ * @author James H. Hill
+ */
+//=============================================================================
+
+#ifndef _ADBC_ODBC_CONNECTION_H_
+#define _ADBC_ODBC_CONNECTION_H_
+
+#include "ODBC_Env.h"
+#include "ODBC_Exception.h"
+#include "ODBC_Query.h"
+#include "adbc/Connection.h"
+
+namespace ADBC
+{
+namespace ODBC
+{
+// Forward decl.
+class Query;
+
+/**
+ * @class Connection
+ *
+ * @brief Wrapper class for handling ODBC connection objects.
+ *
+ * This class provides a minimal set of operations used in ADBC for
+ * creating connection to a database using the ODBC protocol. Futhermore,
+ * this class is the only way to create an ODBC_Query object for performing
+ * SQL queries using the ODBC protocol.
+ */
+class ADBC_ODBC_Export Connection :
+ public ::ADBC::Connection
+{
+ // Friend decl.
+ friend class Query;
+
+public:
+ /// Constructor
+ Connection (Environment * env = Environment::instance ());
+
+ /// Destructor
+ virtual ~Connection (void);
+
+ /**
+ * Establish connection of an ODBC database. The connection string
+ * is a full connection string that depends on the target database
+ * driver. For a complete list of ODBC connection string formats,
+ * please see the following location:
+ *
+ * http://www.connectionstrings.com
+ *
+ * @param[in] connstr The connection string.
+ */
+ virtual void connect (const ACE_CString & connstr);
+
+ /// Close the existing connection
+ virtual void disconnect (void);
+
+ /**
+ * Create an ODBC query object.
+ *
+ * @return Pointer to the database query.
+ */
+ virtual ::ADBC::ODBC::Query * create_query (void);
+
+ /// Get the underlying handle to the connection.
+ HDBC handle (void) const;
+
+private:
+ /// Initialize the connection.
+ void init (void);
+
+ /// Handle to the database connection
+ HDBC handle_;
+
+ /// Pointer to the target environment.
+ Environment * env_;
+};
+}
+}
+
+#if defined (__ADBC_INLINE__)
+#include "ODBC_Connection.inl"
+#endif
+
+#endif // !defined _ADBC_ODBC_CONNECTION_H_
diff --git a/ADBC/adbc/ODBC/ODBC_Connection.inl b/ADBC/adbc/ODBC/ODBC_Connection.inl
new file mode 100644
index 00000000000..2c36c758772
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Connection.inl
@@ -0,0 +1,28 @@
+// $Id$
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// Connection
+//
+ADBC_INLINE
+Connection::Connection (Environment * env)
+: handle_ (SQL_NULL_HANDLE),
+ env_ (env)
+{
+ this->init ();
+}
+
+//
+// handle
+//
+ADBC_INLINE
+HDBC Connection::handle (void) const
+{
+ return this->handle_;
+}
+
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Env.cpp b/ADBC/adbc/ODBC/ODBC_Env.cpp
new file mode 100644
index 00000000000..496f96eb7c7
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Env.cpp
@@ -0,0 +1,114 @@
+// $Id$
+
+#include "ODBC_Env.h"
+
+#if !defined (__ADBC_INLINE__)
+#include "ODBC_Env.inl"
+#endif
+
+#include "ODBC_Exception.h"
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// delete_singleton_env_
+//
+bool Environment::delete_singleton_env_ = false;
+
+//
+// singleton_env_
+//
+Environment * Environment::singleton_env_ = 0;
+
+//
+// ~Environment
+//
+Environment::~Environment (void)
+{
+ if (this->handle_ != SQL_NULL_HANDLE)
+ ::SQLFreeHandle (SQL_HANDLE_ENV, this->handle_);
+}
+
+//
+// init
+//
+void Environment::init (void)
+{
+ // Allocate environment handle. Eventually we would like to be
+ // able to attach to user-defined environments.
+ SQL_VERIFY (::SQLAllocHandle (SQL_HANDLE_ENV,
+ SQL_NULL_HANDLE,
+ &this->handle_),
+ Exception ("failed to allocate environment handle"));
+
+ // Set the version of ODBC. Right now we only support ODBC 3.x
+ SQL_ENV_VERIFY (::SQLSetEnvAttr (this->handle_,
+ SQL_ATTR_ODBC_VERSION,
+ (void *)SQL_OV_ODBC3,
+ 0),
+ this->handle_);
+}
+
+//
+// instance
+//
+Environment * Environment::instance (Environment * new_env)
+{
+ ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
+ *ACE_Static_Object_Lock::instance (), 0));
+
+ Environment * old_env = Environment::singleton_env_;
+
+ // We can't safely delete it since we don't know who created it!
+ Environment::delete_singleton_env_ = false;
+ Environment::singleton_env_ = new_env;
+
+ return old_env;
+}
+
+//
+// instance
+//
+Environment * Environment::instance (void)
+{
+ if (Environment::singleton_env_ == 0)
+ {
+ // Perform Double-Checked Locking Optimization.
+ ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
+ *ACE_Static_Object_Lock::instance (), 0));
+
+ if (Environment::singleton_env_ == 0)
+ {
+ ACE_NEW_RETURN (Environment::singleton_env_,
+ Environment (),
+ 0);
+
+ Environment::delete_singleton_env_ = true;
+ }
+ }
+
+ return Environment::singleton_env_;
+}
+
+//
+// close_singleton
+//
+void Environment::close_singleton (void)
+{
+ ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
+ *ACE_Static_Object_Lock::instance ()));
+
+ if (Environment::singleton_env_)
+ {
+ // Delete the existing environment.
+ delete Environment::singleton_env_;
+
+ Environment::singleton_env_ = 0;
+ Environment::delete_singleton_env_ = false;
+ }
+}
+
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Env.h b/ADBC/adbc/ODBC/ODBC_Env.h
new file mode 100644
index 00000000000..6c25d1eb70c
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Env.h
@@ -0,0 +1,72 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ODBC_Env.h
+ *
+ * $Id$
+ *
+ * @author James H. Hill
+ */
+//=============================================================================
+
+#ifndef _ADBC_ODBC_ENV_H_
+#define _ADBC_ODBC_ENV_H_
+
+#include "ace/Singleton.h"
+#include "ace/Thread_Mutex.h"
+#include "ODBC.h"
+
+namespace ADBC
+{
+namespace ODBC
+{
+/**
+ * @class Environment
+ *
+ * Environment for an existing ODBC connection.
+ */
+class ADBC_ODBC_Export Environment
+{
+public:
+ /// Default constructor.
+ Environment (void);
+
+ /// Destructor.
+ ~Environment (void);
+
+ /// Get the underlying environment handle.
+ HENV handle (void) const;
+
+ /// Get pointer to a process-wide Environment.
+ static Environment *instance (void);
+
+ /// Set pointer to a process-wide Environment and return
+ /// existing pointer.
+ static Environment *instance (Environment * env);
+
+ /// Delete the dynamically allocated Singleton
+ static void close_singleton (void);
+
+private:
+ /// Initialize the environment.
+ void init (void);
+
+ /// Handle to the environment.
+ HENV handle_;
+
+ /// Pointer to a process-wide ACE_Thread_Manager.
+ static Environment * singleton_env_;
+
+ /// Must delete the thr_mgr_ if true.
+ static bool delete_singleton_env_;
+};
+
+}
+}
+
+#if defined (__ADBC_INLINE__)
+#include "ODBC_Env.inl"
+#endif
+
+#endif // !defined _ADBC_ODBC_ENV_H_
diff --git a/ADBC/adbc/ODBC/ODBC_Env.inl b/ADBC/adbc/ODBC/ODBC_Env.inl
new file mode 100644
index 00000000000..d90a5a9da34
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Env.inl
@@ -0,0 +1,28 @@
+// -*- C++ -*-
+// $Id$
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// Environment
+//
+ADBC_INLINE
+Environment::Environment (void)
+: handle_ (SQL_NULL_HANDLE)
+{
+ this->init ();
+}
+
+//
+// handle
+//
+ADBC_INLINE
+HENV Environment::handle (void) const
+{
+ return this->handle_;
+}
+
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Exception.cpp b/ADBC/adbc/ODBC/ODBC_Exception.cpp
new file mode 100644
index 00000000000..40e1c7baaf8
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Exception.cpp
@@ -0,0 +1,47 @@
+// $Id$
+
+#include "ODBC_Exception.h"
+
+#if !defined (__ADBC_INLINE__)
+#include "ODBC_Exception.inl"
+#endif
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// Exception
+//
+Exception::Exception (SQLHANDLE handle, SQLSMALLINT type)
+{
+ static char message[256], state[6];
+ SQLSMALLINT actual;
+
+ SQLRETURN retval = ::SQLGetDiagRec (type,
+ handle,
+ 1,
+ (SQLCHAR *)state,
+ &this->native_,
+ (SQLCHAR *)message,
+ sizeof (message),
+ &actual);
+
+ if (SQL_SUCCEED (retval))
+ {
+ // We need to make sure the code is NULL-terminated
+ // before continuing.
+ state[5] = 0;
+
+ // Store the information.
+ this->state_ = state;
+ this->message_ = message;
+ }
+ else
+ {
+ this->state_ = "00000";
+ this->message_ = "failed to get ODBC exception";
+ }
+}
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Exception.h b/ADBC/adbc/ODBC/ODBC_Exception.h
new file mode 100644
index 00000000000..287418724c9
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Exception.h
@@ -0,0 +1,74 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Exception.h
+ *
+ * $Id$
+ *
+ * @author James H. Hill
+ */
+//=============================================================================
+
+#ifndef _ADBC_ODBC_EXCEPTION_H_
+#define _ADBC_ODBC_EXCEPTION_H_
+
+#include "adbc/Exception.h"
+#include "ODBC.h"
+
+namespace ADBC
+{
+namespace ODBC
+{
+/**
+ * @class Exception
+ *
+ * @brief Base class for all ODBC exception classes.
+ */
+class ADBC_ODBC_Export Exception : public ::ADBC::Exception
+{
+public:
+ /// Default constructor.
+ Exception (void);
+
+ /**
+ * Initializing constructor.
+ *
+ * @param[in] handle Faulting ODBC handle.
+ * @param[in] type Type of handle.
+ */
+ Exception (SQLHANDLE handle, SQLSMALLINT type);
+
+ /**
+ * Initializing constructor.
+ *
+ * @param[in] message Set the error message.
+ */
+ Exception (const char * message);
+
+ /// Default destructor.
+ virtual ~Exception (void);
+};
+}
+}
+
+#define SQL_ENV_VERIFY(op, handle) \
+ SQL_VERIFY (op, ::ADBC::ODBC::Exception (handle, SQL_HANDLE_ENV))
+
+/// Exception for an ODBC connection \a handle.
+#define SQL_CONN_VERIFY(op, handle) \
+ SQL_VERIFY (op, ::ADBC::ODBC::Exception (handle, SQL_HANDLE_DBC))
+
+/// Exception for an ODBC statement \a handle.
+#define SQL_STMT_VERIFY(op, handle) \
+ SQL_VERIFY (op, ::ADBC::ODBC::Exception (handle, SQL_HANDLE_STMT))
+
+/// Exception for an ODBC description \a handle.
+#define SQL_DESC_VERIFY(op, handle) \
+ SQL_VERIFY (op, ::ADBC::ODBC::Exception (handle, SQL_HANDLE_DESC))
+
+#if defined (__ADBC_INLINE__)
+#include "ODBC_Exception.inl"
+#endif
+
+#endif // !defined _ADBC_ODBC_EXCEPTION_H_
diff --git a/ADBC/adbc/ODBC/ODBC_Exception.inl b/ADBC/adbc/ODBC/ODBC_Exception.inl
new file mode 100644
index 00000000000..c022c5997b2
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Exception.inl
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+// $Id$
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// Exception
+//
+ADBC_INLINE
+Exception::Exception (void)
+: ::ADBC::Exception ("unknown ODBC exception has occurred")
+{
+
+}
+
+//
+// Exception
+//
+ADBC_INLINE
+Exception::Exception (const char * message)
+: ::ADBC::Exception (message)
+{
+
+}
+
+//
+// ~Exception
+//
+ADBC_INLINE
+Exception::~Exception (void)
+{
+
+}
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Parameter.cpp b/ADBC/adbc/ODBC/ODBC_Parameter.cpp
new file mode 100644
index 00000000000..324f4d84d1c
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Parameter.cpp
@@ -0,0 +1,97 @@
+// $Id$
+
+#include "ODBC_Parameter.h"
+
+#if !defined (__ADBC_INLINE__)
+#include "ODBC_Parameter.inl"
+#endif
+
+#include "ODBC_Query.h"
+#include "ODBC_Types.h"
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// operator =
+//
+const Parameter & Parameter::operator = (const Parameter & rhs)
+{
+ if (this == &rhs)
+ return *this;
+
+ this->query_ = rhs.query_;
+ this->index_ = rhs.index_;
+
+ return *this;
+}
+
+//
+// bind
+//
+void Parameter::bind (Date_Time * dt)
+{
+ this->bind_i (SQL_PARAM_INPUT,
+ SQL_C_TYPE_TIMESTAMP,
+ SQL_TYPE_TIMESTAMP,
+ 0,
+ 0,
+ dt->value (),
+ 0);
+
+ ::ADBC::Parameter::bind (dt);
+}
+
+//
+// bind
+//
+void Parameter::bind (::ADBC::Date_Time * dt)
+{
+ Date_Time * date_time = dynamic_cast <Date_Time *> (dt);
+
+ if (0 == date_time)
+ throw ::ADBC::ODBC::Exception ("object is not of type ::ADBC::ODBC::Date_Time");
+
+ this->bind (date_time);
+}
+
+//
+//
+// bind_i
+//
+void Parameter::bind_i (SQLSMALLINT iotype,
+ SQLSMALLINT valuetype,
+ SQLSMALLINT paramtype,
+ SQLUINTEGER columnsize,
+ SQLSMALLINT decimals,
+ SQLPOINTER valueptr,
+ SQLINTEGER buffer_length)
+{
+ // Initialize the intptr_ data member.
+ switch (valuetype)
+ {
+ case SQL_C_CHAR:
+ this->intptr_ = buffer_length == 0 ? SQL_NTS : buffer_length;
+ break;
+
+ default:
+ this->intptr_ = 0;
+ };
+
+ // Bind the parameter for the statement.
+ SQL_STMT_VERIFY (::SQLBindParameter (this->query_->handle (),
+ this->index_ + 1,
+ iotype,
+ valuetype,
+ paramtype,
+ columnsize,
+ decimals,
+ valueptr,
+ buffer_length,
+ &this->intptr_),
+ this->query_->handle ());
+}
+
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Parameter.h b/ADBC/adbc/ODBC/ODBC_Parameter.h
new file mode 100644
index 00000000000..dd0188b97ac
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Parameter.h
@@ -0,0 +1,113 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ODBC_Parameter.h
+ *
+ * $Id$
+ *
+ * @author James H. Hill
+ */
+//=============================================================================
+
+#ifndef _ODBC_PARAMETER_H_
+#define _ODBC_PARAMETER_H_
+
+#include "adbc/Parameter.h"
+#include "ODBC_Exception.h"
+#include "ODBC_Types.h"
+
+namespace ADBC
+{
+namespace ODBC
+{
+// Forward decl.
+class Query;
+
+// Forward decl.
+class Parameter_List;
+
+/**
+ * @class Parameter
+ *
+ * ODBC implementation of the ADBC_DB_Parameter abstract type.
+ */
+class ADBC_ODBC_Export Parameter : public ::ADBC::Parameter
+{
+ // Friend decl.
+ friend class Parameter_List;
+
+public:
+ /// Default constructor
+ Parameter (void);
+
+ /**
+ * Copy constructor.
+ *
+ * @param[in] p Source parameter.
+ */
+ Parameter (const Parameter & p);
+
+ /// Destructor.
+ virtual ~Parameter (void);
+
+ virtual void null (void);
+
+ virtual void bind (char * buffer, size_t bufsize);
+
+ virtual void bind (const char * buffer, size_t bufsize);
+
+ virtual void bind (ACE_INT16 * buffer);
+
+ virtual void bind (ACE_UINT16 * buffer);
+
+ virtual void bind (ACE_INT32 * buffer);
+
+ virtual void bind (ACE_UINT32 * buffer);
+
+ virtual void bind (ACE_UINT64 * value);
+
+ virtual void bind (ACE_INT64 * value);
+
+ virtual void bind (float * value);
+
+ virtual void bind (double * value);
+
+ void bind (Date_Time * dt);
+ virtual void bind (::ADBC::Date_Time * dt);
+
+ const Parameter & operator = (const Parameter & rhs);
+
+ /**
+ * Get the current length/size of the parameter.
+ *
+ * @return The length/size of the parameter.
+ */
+ virtual long length (void);
+
+ /// Test if the parameter is NULL
+ virtual bool is_null (void) const;
+
+private:
+ /// Helper method for binding SQL parameters.
+ void bind_i (SQLSMALLINT iotype,
+ SQLSMALLINT valuetype,
+ SQLSMALLINT paramtype,
+ SQLUINTEGER columnsize,
+ SQLSMALLINT decimals,
+ SQLPOINTER valueptr,
+ SQLINTEGER buffer_length);
+
+ /// Handle to the ODBC statement.
+ const Query * query_;
+
+ /// Size of the parameter buffer.
+ SQLINTEGER intptr_;
+
+ /// Pointer to allocated memory.
+ void * buffer_;
+};
+}
+}
+
+#endif // !defined _ODBC_PARAMETER_H_
diff --git a/ADBC/adbc/ODBC/ODBC_Parameter.inl b/ADBC/adbc/ODBC/ODBC_Parameter.inl
new file mode 100644
index 00000000000..7eeb019c3ed
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Parameter.inl
@@ -0,0 +1,235 @@
+// -*- C++ -*-
+// $Id$
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// ODBC_Parameter
+//
+ADBC_INLINE
+Parameter::Parameter (void)
+: query_ (0)
+{
+
+}
+
+//
+// ODBC_Parameter
+//
+ADBC_INLINE
+Parameter::Parameter (const Parameter & p)
+: ADBC::Parameter (p),
+ query_ (p.query_)
+{
+ new Parameter ();
+}
+
+//
+// ~ODBC_Parameter
+//
+ADBC_INLINE
+Parameter::~Parameter (void)
+{
+
+}
+
+//
+// null
+//
+ADBC_INLINE
+void Parameter::null (void)
+{
+ this->intptr_ = SQL_NULL_DATA;
+}
+
+//
+// is_null
+//
+ADBC_INLINE
+bool Parameter::is_null (void) const
+{
+ return this->intptr_ == SQL_NULL_DATA;
+}
+
+//
+// length
+//
+ADBC_INLINE
+long Parameter::length (void)
+{
+ return this->intptr_;
+}
+
+//
+// bind
+//
+ADBC_INLINE
+void Parameter::bind (const char * buffer, size_t bufsize)
+{
+ this->bind_i (SQL_PARAM_INPUT,
+ SQL_C_CHAR,
+ SQL_CHAR,
+ 0,
+ 0,
+ (SQLPOINTER)buffer,
+ bufsize);
+
+ ::ADBC::Parameter::bind (buffer, bufsize);
+}
+
+//
+// bind
+//
+ADBC_INLINE
+void Parameter::bind (char * buffer, size_t bufsize)
+{
+ this->bind_i (SQL_PARAM_INPUT,
+ SQL_C_CHAR,
+ SQL_CHAR,
+ 0,
+ 0,
+ buffer,
+ bufsize);
+
+ ::ADBC::Parameter::bind (buffer, bufsize);
+}
+
+//
+// bind
+//
+ADBC_INLINE
+void Parameter::bind (ACE_INT16 * buffer)
+{
+ this->bind_i (SQL_PARAM_INPUT,
+ SQL_C_SSHORT,
+ SQL_SMALLINT,
+ 0,
+ 0,
+ buffer,
+ 0);
+
+ ::ADBC::Parameter::bind (buffer);
+}
+
+//
+// bind
+//
+ADBC_INLINE
+void Parameter::bind (ACE_UINT16 * buffer)
+{
+ this->bind_i (SQL_PARAM_INPUT,
+ SQL_C_USHORT,
+ SQL_SMALLINT,
+ 0,
+ 0,
+ &buffer,
+ 0);
+
+ ::ADBC::Parameter::bind (buffer);
+}
+
+//
+// bind
+//
+ADBC_INLINE
+void Parameter::bind (ACE_INT32 * buffer)
+{
+ this->bind_i (SQL_PARAM_INPUT,
+ SQL_C_SLONG,
+ SQL_INTEGER,
+ 0,
+ 0,
+ &buffer,
+ 0);
+
+ ::ADBC::Parameter::bind (buffer);
+}
+
+//
+// bind
+//
+ADBC_INLINE
+void Parameter::bind (ACE_UINT32 * buffer)
+{
+ this->bind_i (SQL_PARAM_INPUT,
+ SQL_C_ULONG,
+ SQL_INTEGER,
+ 0,
+ 0,
+ &buffer,
+ 0);
+
+ ::ADBC::Parameter::bind (buffer);
+}
+
+//
+// bind
+//
+ADBC_INLINE
+void Parameter::bind (ACE_INT64 * buffer)
+{
+ this->bind_i (SQL_PARAM_INPUT,
+ SQL_C_UBIGINT,
+ SQL_BIGINT,
+ 0,
+ 0,
+ &buffer,
+ 0);
+
+ ::ADBC::Parameter::bind (buffer);
+}
+
+//
+// bind
+//
+ADBC_INLINE
+void Parameter::bind (ACE_UINT64 * buffer)
+{
+ this->bind_i (SQL_PARAM_INPUT,
+ SQL_C_SBIGINT,
+ SQL_BIGINT,
+ 0,
+ 0,
+ &buffer,
+ 0);
+
+ ::ADBC::Parameter::bind (buffer);
+}
+
+//
+// bind
+//
+ADBC_INLINE
+void Parameter::bind (float * buffer)
+{
+ this->bind_i (SQL_PARAM_INPUT,
+ SQL_C_FLOAT,
+ SQL_REAL,
+ 0,
+ 0,
+ &buffer,
+ 0);
+
+ ::ADBC::Parameter::bind (buffer);
+}
+
+//
+// bind
+//
+ADBC_INLINE
+void Parameter::bind (double * buffer)
+{
+ this->bind_i (SQL_PARAM_INPUT,
+ SQL_C_DOUBLE,
+ SQL_DOUBLE,
+ 0,
+ 0,
+ &buffer,
+ 0);
+
+ ::ADBC::Parameter::bind (buffer);
+}
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Parameter_List.cpp b/ADBC/adbc/ODBC/ODBC_Parameter_List.cpp
new file mode 100644
index 00000000000..97de42dac6c
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Parameter_List.cpp
@@ -0,0 +1,38 @@
+// $Id$
+
+#include "ODBC_Parameter_List.h"
+
+#if !defined (__ADBC_INLINE__)
+#include "ODBC_Parameter_List.inl"
+#endif
+
+#include "ODBC_Query.h"
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// update
+//
+void Parameter_List::update (void)
+{
+ // Get the number of parameters in the prepared statement.
+ SQLSMALLINT param_count;
+
+ SQL_STMT_VERIFY (::SQLNumParams (this->query_.handle (), &param_count),
+ this->query_.handle ());
+
+ // If this is the first prepared statement on this handle
+ // then we need to allocate a new parameter list.
+ this->params_.size (param_count);
+
+ for (SQLSMALLINT i = 0; i < param_count; ++ i)
+ {
+ this->params_[i].query_ = &this->query_;
+ this->params_[i].index_ = i;
+ }
+}
+
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Parameter_List.h b/ADBC/adbc/ODBC/ODBC_Parameter_List.h
new file mode 100644
index 00000000000..1f8a248ac7c
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Parameter_List.h
@@ -0,0 +1,84 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ODBC_Parameter_List.h
+ *
+ * $Id$
+ *
+ * @author James H. Hill
+ */
+//=============================================================================
+
+#ifndef _ADBC_ODBC_PARAMETER_LIST_H_
+#define _ADBC_ODBC_PARAMETER_LIST_H_
+
+#include "ace/Array.h"
+#include "adbc/Parameter_List.h"
+#include "ODBC_Parameter.h"
+
+// Forward decl.
+class ODBC_Query;
+
+namespace ADBC
+{
+namespace ODBC
+{
+/**
+ * @class ODBC_Parameter_List
+ *
+ * Container class for ODBC_Parameter objects.
+ */
+class ADBC_ODBC_Export Parameter_List :
+ public ::ADBC::Parameter_List
+{
+ // Friend decl.
+ friend class Query;
+
+public:
+ /**
+ * Initializing constructor.
+ */
+ Parameter_List (const Query & query);
+
+ /// Destructor.
+ virtual ~Parameter_List (void);
+
+ /**
+ * Get the size of the parameter list.
+ *
+ * @return Size of the parmameter list.
+ */
+ virtual size_t size (void) const;
+
+ /**
+ * Get an existing parameter.
+ *
+ * @param[in] index Index of the parameter.
+ * @param[out] param Pointer to the parameter.
+ */
+ virtual const Parameter & operator [] (size_t index) const;
+
+ virtual Parameter & operator [] (size_t index);
+
+ /// Update the number of parameters for parent query.
+ void update (void);
+
+private:
+ /// Helper function to initialize a parameter.
+ void init (Parameter & p, size_t index);
+
+ /// Type definition of the list of parameters.
+ ACE_Array <Parameter> params_;
+
+ /// The parent of the query.
+ const Query & query_;
+};
+}
+}
+
+#if defined (__ADBC_INLINE__)
+#include "ODBC_Parameter_List.inl"
+#endif
+
+#endif // !defined _ODBC_PARAMETER_LIST_H_
diff --git a/ADBC/adbc/ODBC/ODBC_Parameter_List.inl b/ADBC/adbc/ODBC/ODBC_Parameter_List.inl
new file mode 100644
index 00000000000..3225d75c75f
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Parameter_List.inl
@@ -0,0 +1,54 @@
+// $Id$
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// Parameter_List
+//
+ADBC_INLINE
+Parameter_List::Parameter_List (const Query & query)
+: query_ (query)
+{
+
+}
+
+//
+// ~Parameter_List
+//
+ADBC_INLINE
+Parameter_List::~Parameter_List (void)
+{
+
+}
+
+//
+// size
+//
+ADBC_INLINE
+size_t Parameter_List::size (void) const
+{
+ return this->size ();
+}
+
+//
+// operator []
+//
+ADBC_INLINE
+const Parameter & Parameter_List::operator [] (size_t index) const
+{
+ return this->params_[index];
+}
+
+//
+// operator []
+//
+ADBC_INLINE
+Parameter & Parameter_List::operator [] (size_t index)
+{
+ return this->params_[index];
+}
+
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Query.cpp b/ADBC/adbc/ODBC/ODBC_Query.cpp
new file mode 100644
index 00000000000..4c437edfa29
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Query.cpp
@@ -0,0 +1,173 @@
+// $Id$
+
+#include "ODBC_Query.h"
+
+#if !defined (__ADBC_INLINE__)
+#include "ODBC_Query.inl"
+#endif
+
+#include "ODBC_Connection.h"
+#include "ODBC_Record.h"
+#include "ODBC_Parameter.h"
+#include "ODBC_Parameter_List.h"
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// ~Query
+//
+Query::~Query (void)
+{
+ if (this->handle_ != SQL_NULL_HSTMT)
+ ::SQLFreeHandle (SQL_HANDLE_STMT, this->handle_);
+}
+
+//
+// init
+//
+void Query::init (void)
+{
+ SQL_CONN_VERIFY (::SQLAllocHandle (SQL_HANDLE_STMT,
+ this->parent_.handle (),
+ &this->handle_),
+ this->parent_.handle ());
+
+ // Set the attributes for the statement. We need to find a
+ // better method for setting attributes. Maybe we can overload
+ // the operator [].
+ SQL_STMT_VERIFY (::SQLSetStmtAttr (this->handle_,
+ SQL_ATTR_CONCURRENCY,
+ (SQLPOINTER) SQL_CONCUR_ROWVER,
+ 0),
+ this->handle_);
+
+ SQL_STMT_VERIFY (::SQLSetStmtAttr (this->handle_,
+ SQL_ATTR_CURSOR_TYPE,
+ (SQLPOINTER) SQL_CURSOR_KEYSET_DRIVEN,
+ 0),
+ this->handle_);
+}
+
+//
+// prepare
+//
+void Query::prepare (const char * stmt)
+{
+ // Prepare the SQL statement.
+ SQL_STMT_VERIFY (::SQLPrepare (this->handle_,
+ (SQLCHAR *) stmt,
+ SQL_NTS),
+ this->handle_);
+
+ /// Update the parameters for this statement.
+ this->params_.update ();
+ this->is_prepared_ = true;
+}
+
+//
+// execute_no_record
+//
+void Query::execute_no_record (void)
+{
+ if (!this->is_prepared_)
+ throw ::ADBC::ODBC::Exception ("statement is not prepared");
+
+ SQL_STMT_VERIFY (::SQLExecute (this->handle_),
+ this->handle_);
+
+ // There is no cursor associated with non-record statements.
+ this->cursor_open_ = false;
+}
+
+//
+// execute_no_record
+//
+void Query::execute_no_record (const char * query)
+{
+ SQL_STMT_VERIFY (::SQLExecDirect (this->handle_, (SQLCHAR *)query, SQL_NTS),
+ this->handle_);
+
+ // The statement is not prepared, and there is no cursor
+ // associated with non-record statements.
+ this->is_prepared_ = false;
+ this->cursor_open_ = false;
+}
+
+//
+// last_insert_id
+//
+long Query::last_insert_id (void)
+{
+ // Execute the statement and move to the first and only row in
+ // the result set. There has to be some way to get the last insert
+ // id without having to execute an SQL statement.
+ Query temp_query (this->parent_);
+ Record & record = temp_query.execute ("SELECT LAST_INSERT_ID()");
+
+ // Get the data returned from the statement.
+ long last_id = 0;
+ record.get_data (1, last_id);
+
+ return last_id;
+}
+
+//
+// cancel
+//
+void Query::cancel (void)
+{
+ SQL_STMT_VERIFY (::SQLCancel (this->handle_),
+ this->handle_);
+}
+
+//
+// execute
+//
+Record & Query::execute (const char * query)
+{
+ // Execute the query and set the <cursor_open_> to open.
+ this->execute_no_record (query);
+
+ // Move to the first record, if available.
+ this->record_.reset ();
+ return this->record_;
+}
+
+//
+// execute
+//
+Record & Query::execute (void)
+{
+ // Execute the prepared SQL statement.
+ this->execute_no_record ();
+
+ // Move to the first record, if available.
+ this->record_.reset ();
+ return this->record_;
+}
+
+//
+// reset
+//
+void Query::reset (void)
+{
+ SQL_STMT_VERIFY (::SQLFreeStmt (this->handle_, SQL_CLOSE),
+ this->handle_);
+}
+
+//
+// count
+//
+size_t Query::count (void) const
+{
+ SQLINTEGER count;
+ SQL_STMT_VERIFY (::SQLRowCount (this->handle_, &count),
+ this->handle_);
+
+ return count;
+}
+
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Query.h b/ADBC/adbc/ODBC/ODBC_Query.h
new file mode 100644
index 00000000000..d7af509b16d
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Query.h
@@ -0,0 +1,142 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ODBC_Query.h
+ *
+ * $Id$
+ *
+ * @author James H. Hill <hillj@isis.vanderbilt.edu>
+ */
+//=============================================================================
+
+#ifndef _ADBC_ODBC_QUERY_H_
+#define _ADBC_ODBC_QUERY_H_
+
+#include "adbc/Query.h"
+#include "ODBC_Parameter_List.h"
+#include "ODBC_Record.h"
+
+namespace ADBC
+{
+namespace ODBC
+{
+// Forward decl.
+class Connection;
+
+/**
+ * @class ODBC_Query
+ *
+ * @brief Wrapper class for using ODBC statement handles.
+ *
+ * This class contains common operations used by ADBC for executing
+ * SQL statements using ODBC. One cannot instantiate an object of this
+ * class alone. Instead, it can only be created by an Connection
+ * object. This prevents the creation of dangling ODBC_Query objects
+ * (those not associated with a connection).
+ */
+class ADBC_ODBC_Export Query : public ::ADBC::Query
+{
+public:
+ /**
+ * Initializing constructor.
+ *
+ * @param[in] conn Parent database connection.
+ */
+ Query (Connection & conn);
+
+ /// Destructor.
+ virtual ~Query (void);
+
+ /**
+ * Prepare an SQL query for execution.
+ *
+ * @param[in] query NULL-terminate SQL query string.
+ */
+ virtual void prepare (const char * query);
+
+ /// Execute a prepare query.
+ virtual void execute_no_record (void);
+
+ /**
+ * Execute a query.
+ *
+ * @param[in] query Query to execute.
+ */
+ virtual void execute_no_record (const char * query);
+
+ /**
+ * Get the last insert id. This method is only value if an
+ * insert was made to a table with an \a auto_increment field.
+ *
+ * @return The last id inserted.
+ */
+ virtual long last_insert_id (void);
+
+ /// Cancel the current operation.
+ virtual void cancel (void);
+
+ /**
+ * Execute a query. This method is useful with the query is known
+ * to return results that will consist of multiple data rows, and
+ * columns. The client has the responsibility of delete the record
+ * once its done with it.
+ *
+ * @return Pointer to a record.
+ */
+ virtual Record & execute (const char * query);
+
+ /**
+ * Execute a prepared query. This method is useful with the query is
+ * known to return results that will consist of multiple data rows,
+ * and columns. The client has the responsibility of delete the record
+ * once its done with it.
+ *
+ * @return Pointer to a record.
+ */
+ virtual Record & execute (void);
+
+ /// Get a read-only list of the parameters.
+ virtual const Parameter_List & parameters (void) const;
+
+ /// Get a list of the parameters.
+ virtual Parameter_List & parameters (void);
+
+ /// Reset the query string.
+ void reset (void);
+
+ virtual size_t count (void) const;
+
+ /// Get the handle to the underlying statement.
+ HSTMT handle (void) const;
+
+private:
+ /// Initialize the query.
+ void init (void);
+
+ /// Parent of the query.
+ Connection & parent_;
+
+ /// handle to the ODBC statement
+ HSTMT handle_;
+
+ /// The state of the cursor.
+ bool cursor_open_;
+
+ /// The query is prepared.
+ bool is_prepared_;
+
+ /// Pointer to the parameters for the method.
+ Parameter_List params_;
+
+ /// The record associated with this query.
+ Record record_;
+};
+}
+}
+
+#if defined (__ADBC_INLINE__)
+#include "ODBC_Query.inl"
+#endif
+
+#endif // !defined _ADBC_ODBC_QUERY_H_
diff --git a/ADBC/adbc/ODBC/ODBC_Query.inl b/ADBC/adbc/ODBC/ODBC_Query.inl
new file mode 100644
index 00000000000..3ee92e0c8aa
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Query.inl
@@ -0,0 +1,50 @@
+// $Id$
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// Query
+//
+ADBC_INLINE
+Query::Query (Connection & conn)
+: parent_ (conn),
+ handle_ (SQL_NULL_HSTMT),
+ cursor_open_ (false),
+ is_prepared_ (false),
+ params_ (*this),
+ record_ (*this)
+{
+ this->init ();
+}
+
+//
+// parameters
+//
+ADBC_INLINE
+Parameter_List & Query::parameters (void)
+{
+ return this->params_;
+}
+
+//
+// parameters
+//
+ADBC_INLINE
+const Parameter_List & Query::parameters (void) const
+{
+ return this->params_;
+}
+
+//
+// handle
+//
+ADBC_INLINE
+HSTMT Query::handle (void) const
+{
+ return this->handle_;
+}
+
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Record.cpp b/ADBC/adbc/ODBC/ODBC_Record.cpp
new file mode 100644
index 00000000000..b8b22db5101
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Record.cpp
@@ -0,0 +1,85 @@
+// $Id$
+
+#include "ODBC_Record.h"
+
+#if !defined (__ADBC_INLINE__)
+#include "ODBC_Record.inl"
+#endif
+
+#include "ODBC_Query.h"
+#include "ace/Date_Time.h"
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// reset
+//
+void Record::reset (void)
+{
+ // Move to the first record in the result set.
+ if (!SQL_SUCCEED (this->state_))
+ this->state_ = ::SQLFetchScroll (this->query_.handle (),
+ SQL_FETCH_FIRST,
+ 0);
+
+ if (this->state_ == SQL_ERROR || this->state_ == SQL_INVALID_HANDLE)
+ throw Exception (this->query_.handle (), SQL_HANDLE_STMT);
+}
+
+//
+// advance
+//
+void Record::advance (void)
+{
+ if (this->state_ != SQL_NO_DATA)
+ this->state_ = ::SQLFetch (this->query_.handle ());
+
+ if (this->state_ == SQL_ERROR || this->state_ == SQL_INVALID_HANDLE)
+ throw Exception (this->query_.handle (), SQL_HANDLE_STMT);
+}
+
+//
+// get_data
+//
+void Record::get_data (size_t column, ACE_Date_Time & datetime)
+{
+ SQL_TIMESTAMP_STRUCT timestamp;
+
+ this->get_data_i (static_cast <SQLUSMALLINT> (column),
+ SQL_C_TYPE_TIMESTAMP,
+ &timestamp,
+ sizeof (SQL_TIMESTAMP_STRUCT),
+ 0);
+
+ // Convert the <SQL_TIMESTAMP_STRUCT> to a <ACE_Time_Value>.
+ datetime.month (timestamp.month);
+ datetime.day (timestamp.day);
+ datetime.year (timestamp.year);
+ datetime.hour (timestamp.hour);
+ datetime.minute (timestamp.minute);
+ datetime.second (timestamp.second);
+ datetime.microsec (timestamp.fraction);
+}
+
+//
+// get_data_i
+//
+void Record::get_data_i (SQLUSMALLINT column,
+ SQLSMALLINT target_type,
+ SQLPOINTER target,
+ SQLINTEGER bufsize,
+ SQLINTEGER * result)
+{
+ SQL_STMT_VERIFY (::SQLGetData (this->query_.handle (),
+ column,
+ target_type,
+ target,
+ bufsize,
+ result),
+ this->query_.handle ());
+}
+
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Record.h b/ADBC/adbc/ODBC/ODBC_Record.h
new file mode 100644
index 00000000000..2f935aa2c76
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Record.h
@@ -0,0 +1,103 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ODBC_Record.h
+ *
+ * $Id$
+ *
+ * @author James H. Hill
+ */
+//=============================================================================
+
+#ifndef _ADBC_ODBC_RECORD_H_
+#define _ADBC_ODBC_RECORD_H_
+
+#include "adbc/Record.h"
+#include "ODBC.h"
+
+namespace ADBC
+{
+namespace ODBC
+{
+// Forward decl.
+class Query;
+
+/**
+ * @class ODBC_Record
+ *
+ * Implementation of the ::ADBC::Record for ODBC.
+ */
+class ADBC_ODBC_Export Record : public ::ADBC::Record
+{
+public:
+ /**
+ * Initializing constructor.
+ *
+ * @param[in] handle Statement handle.
+ */
+ Record (const Query & query);
+
+ /// Destructor.
+ virtual ~Record (void);
+
+ // Move to the next record.
+ virtual void advance (void);
+
+ // Test if the iterator is done.
+ virtual bool done (void) const;
+
+ virtual void reset (void);
+
+ /**
+ * Get the number of columns in the result.
+ *
+ * @return Number of columns.
+ */
+ virtual size_t columns (void) const;
+
+ virtual void get_data (size_t column, char * buffer, size_t bufsize);
+
+ virtual void get_data (size_t column, char & value);
+
+ virtual void get_data (size_t column, unsigned char & value);
+
+ virtual void get_data (size_t column, short & value);
+
+ virtual void get_data (size_t column, unsigned short & value);
+
+ virtual void get_data (size_t column, long & value);
+
+ virtual void get_data (size_t column, unsigned long & value);
+
+ virtual void get_data (size_t column, float & value);
+
+ virtual void get_data (size_t column, double & value);
+
+ virtual void get_data (size_t column, ACE_Date_Time & datetime);
+
+private:
+ /// Help method that wraps the SQLGetData method.
+ void get_data_i (SQLUSMALLINT column,
+ SQLSMALLINT target_type,
+ SQLPOINTER target,
+ SQLINTEGER bufsize,
+ SQLINTEGER * result);
+
+ /// Parent of the record.
+ const Query & query_;
+
+ /// Number of columns in the record set.
+ size_t columns_;
+
+ /// State of the iterator.
+ SQLRETURN state_;
+};
+}
+}
+
+#if defined (__ADBC_INLINE__)
+#include "ODBC_Record.inl"
+#endif
+
+#endif // !defined _ADBC_ODBC_RECORD_H_
diff --git a/ADBC/adbc/ODBC/ODBC_Record.inl b/ADBC/adbc/ODBC/ODBC_Record.inl
new file mode 100644
index 00000000000..a7a7ff5e220
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Record.inl
@@ -0,0 +1,168 @@
+// $Id$
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// Record
+//
+ADBC_INLINE
+Record::Record (const Query & query)
+: query_ (query),
+ columns_ (0),
+ state_ (SQL_SUCCESS)
+{
+
+}
+
+//
+// ~Record
+//
+ADBC_INLINE
+Record::~Record (void)
+{
+
+}
+
+
+//
+// get_data
+//
+ADBC_INLINE
+void Record::
+get_data (size_t column, char * buffer, size_t bufsize)
+{
+ this->get_data_i (static_cast <SQLUSMALLINT> (column),
+ SQL_C_CHAR,
+ buffer,
+ bufsize,
+ 0);
+}
+
+
+//
+// get_data
+//
+ADBC_INLINE
+void Record::get_data (size_t column, long & value)
+{
+ this->get_data_i (static_cast <SQLUSMALLINT> (column),
+ SQL_C_SLONG,
+ &value,
+ sizeof (long),
+ 0);
+}
+
+//
+// get_data
+//
+ADBC_INLINE
+void Record::get_data (size_t column, unsigned long & value)
+{
+ this->get_data_i (static_cast <SQLUSMALLINT> (column),
+ SQL_C_ULONG,
+ &value,
+ sizeof (unsigned long),
+ 0);
+}
+
+//
+// get_data
+//
+ADBC_INLINE
+void Record::get_data (size_t column, char & value)
+{
+ this->get_data_i (static_cast <SQLUSMALLINT> (column),
+ SQL_C_CHAR,
+ &value,
+ sizeof (char),
+ 0);
+}
+
+//
+// get_data
+//
+ADBC_INLINE
+void Record::get_data (size_t column, unsigned char & value)
+{
+ this->get_data_i (static_cast <SQLUSMALLINT> (column),
+ SQL_C_CHAR,
+ &value,
+ sizeof (unsigned char),
+ 0);
+}
+
+//
+// get_data
+//
+ADBC_INLINE
+void Record::get_data (size_t column, short & value)
+{
+ this->get_data_i (static_cast <SQLUSMALLINT> (column),
+ SQL_C_SHORT,
+ &value,
+ sizeof (short),
+ 0);
+}
+
+//
+// get_data
+//
+ADBC_INLINE
+void Record::get_data (size_t column, unsigned short & value)
+{
+ this->get_data_i (static_cast <SQLUSMALLINT> (column),
+ SQL_C_USHORT,
+ &value,
+ sizeof (unsigned short),
+ 0);
+}
+
+//
+// get_data
+//
+ADBC_INLINE
+void Record::get_data (size_t column, float & value)
+{
+ this->get_data_i (static_cast <SQLUSMALLINT> (column),
+ SQL_C_FLOAT,
+ &value,
+ sizeof (float),
+ 0);
+}
+
+
+//
+// get_data
+//
+ADBC_INLINE
+void Record::get_data (size_t column, double & value)
+{
+ this->get_data_i (static_cast <SQLUSMALLINT> (column),
+ SQL_C_DOUBLE,
+ &value,
+ sizeof (double),
+ 0);
+}
+
+//
+// columns
+//
+ADBC_INLINE
+size_t Record::columns (void) const
+{
+ return this->columns_;
+}
+
+//
+// done
+//
+ADBC_INLINE
+bool Record::done (void) const
+{
+ return this->state_ == SQL_NO_DATA;
+}
+
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Types.cpp b/ADBC/adbc/ODBC/ODBC_Types.cpp
new file mode 100644
index 00000000000..3efad071cd0
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Types.cpp
@@ -0,0 +1,50 @@
+// $Id$
+
+#include "ODBC_Types.h"
+
+#if !defined (__ADBC_INLINE__)
+#include "ODBC_Types.inl"
+#endif
+
+#include "ace/OS_NS_string.h"
+#include "ace/Date_Time.h"
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// Date_Time
+//
+Date_Time::Date_Time (void)
+{
+ ACE_OS::memset (&this->datetime_,
+ 0,
+ sizeof (SQL_TIMESTAMP_STRUCT));
+}
+
+//
+// set
+//
+void Date_Time::set (const ACE_Date_Time & datetime)
+{
+ this->month (datetime.month ());
+ this->day (datetime.day ());
+ this->year (datetime.year ());
+ this->hour (datetime.hour ());
+ this->minute (datetime.minute ());
+ this->second (datetime.second ());
+ this->fraction (datetime.microsec ());
+}
+
+//
+// set
+//
+void Date_Time::set (const Date_Time & datetime)
+{
+ ACE_OS::memcpy (&this->datetime_,
+ &datetime.datetime_,
+ sizeof (SQL_TIMESTAMP_STRUCT));
+}
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_Types.h b/ADBC/adbc/ODBC/ODBC_Types.h
new file mode 100644
index 00000000000..df4b4d54545
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Types.h
@@ -0,0 +1,85 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ODBC_Types.h
+ *
+ * $Id$
+ *
+ * @author James H. Hill
+ */
+//=============================================================================
+
+#ifndef _ADBC_ODBC_TYPES_H_
+#define _ADBC_ODBC_TYPES_H_
+
+#include "ODBC.h"
+#include "adbc/Types.h"
+
+// Forward decl.
+class ACE_Date_Time;
+
+namespace ADBC
+{
+namespace ODBC
+{
+/**
+ * @class Date_Time
+ *
+ * ODBC implementation of the ::ADBC::Date_Time class.
+ */
+class ADBC_ODBC_Export Date_Time : public ::ADBC::Date_Time
+{
+public:
+ /// Default constructor.
+ Date_Time (void);
+
+ /// Destructor.
+ virtual ~Date_Time (void);
+
+ long month (void) const;
+
+ void month (long);
+
+ long day (void) const;
+
+ void day (long);
+
+ long year (void) const;
+
+ void year (long);
+
+ long hour (void) const;
+
+ void hour (long);
+
+ long minute (void) const;
+
+ void minute (long);
+
+ long second (void) const;
+
+ void second (long);
+
+ long fraction (void) const;
+
+ void fraction (long);
+
+ void * value (void);
+
+ void set (const ACE_Date_Time & datetime);
+
+ void set (const Date_Time & datetime);
+
+private:
+ /// SQL timestamp data value.
+ SQL_TIMESTAMP_STRUCT datetime_;
+};
+}
+}
+
+#if defined (__ADBC_INLINE__)
+#include "ODBC_Types.inl"
+#endif
+
+#endif // !defined _ADBC_ODBC_TYPES_H_
diff --git a/ADBC/adbc/ODBC/ODBC_Types.inl b/ADBC/adbc/ODBC/ODBC_Types.inl
new file mode 100644
index 00000000000..8d07ad1b434
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_Types.inl
@@ -0,0 +1,152 @@
+// $Id$
+
+namespace ADBC
+{
+namespace ODBC
+{
+//
+// ~Date_Time
+//
+ADBC_INLINE
+Date_Time::~Date_Time (void)
+{
+
+}
+
+//
+// month
+//
+ADBC_INLINE
+void Date_Time::month (long value)
+{
+ this->datetime_.month = static_cast <SQLUSMALLINT> (value);
+}
+
+//
+// month
+//
+ADBC_INLINE
+long Date_Time::month (void) const
+{
+ return this->datetime_.month;
+}
+
+//
+// day
+//
+ADBC_INLINE
+void Date_Time::day (long value)
+{
+ this->datetime_.day = static_cast <SQLUSMALLINT> (value);
+}
+
+//
+// day
+//
+ADBC_INLINE
+long Date_Time::day (void) const
+{
+ return this->datetime_.day;
+}
+
+//
+// year
+//
+ADBC_INLINE
+void Date_Time::year (long value)
+{
+ this->datetime_.year = static_cast <SQLUSMALLINT> (value);
+}
+
+//
+// year
+//
+ADBC_INLINE
+long Date_Time::year (void) const
+{
+ return this->datetime_.year;
+}
+
+//
+// hour
+//
+ADBC_INLINE
+void Date_Time::hour (long value)
+{
+ this->datetime_.hour = static_cast <SQLSMALLINT> (value);
+}
+
+//
+// hour
+//
+ADBC_INLINE
+long Date_Time::hour (void) const
+{
+ return this->datetime_.hour;
+}
+
+//
+// minute
+//
+ADBC_INLINE
+void Date_Time::minute (long value)
+{
+ this->datetime_.minute = static_cast <SQLUSMALLINT> (value);
+}
+
+//
+// minute
+//
+ADBC_INLINE
+long Date_Time::minute (void) const
+{
+ return this->datetime_.minute;
+}
+
+//
+// second
+//
+ADBC_INLINE
+void Date_Time::second (long value)
+{
+ this->datetime_.second = static_cast <SQLUSMALLINT> (value);
+}
+
+//
+// second
+//
+ADBC_INLINE
+long Date_Time::second (void) const
+{
+ return this->datetime_.second;
+}
+
+//
+// fraction
+//
+ADBC_INLINE
+void Date_Time::fraction (long value)
+{
+ this->datetime_.fraction = static_cast <SQLUSMALLINT> (value);
+}
+
+//
+// fraction
+//
+ADBC_INLINE
+long Date_Time::fraction (void) const
+{
+ return this->datetime_.fraction;
+}
+
+//
+// fraction
+//
+ADBC_INLINE
+void * Date_Time::value (void)
+{
+ return &this->datetime_;
+}
+
+}
+}
diff --git a/ADBC/adbc/ODBC/ODBC_export.h b/ADBC/adbc/ODBC/ODBC_export.h
new file mode 100644
index 00000000000..4231105e7b0
--- /dev/null
+++ b/ADBC/adbc/ODBC/ODBC_export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl ADBC_ODBC
+// ------------------------------
+#ifndef ADBC_ODBC_EXPORT_H
+#define ADBC_ODBC_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (ADBC_ODBC_HAS_DLL)
+# define ADBC_ODBC_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && ADBC_ODBC_HAS_DLL */
+
+#if !defined (ADBC_ODBC_HAS_DLL)
+# define ADBC_ODBC_HAS_DLL 1
+#endif /* ! ADBC_ODBC_HAS_DLL */
+
+#if defined (ADBC_ODBC_HAS_DLL) && (ADBC_ODBC_HAS_DLL == 1)
+# if defined (ADBC_ODBC_BUILD_DLL)
+# define ADBC_ODBC_Export ACE_Proper_Export_Flag
+# define ADBC_ODBC_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define ADBC_ODBC_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* ADBC_ODBC_BUILD_DLL */
+# define ADBC_ODBC_Export ACE_Proper_Import_Flag
+# define ADBC_ODBC_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define ADBC_ODBC_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* ADBC_ODBC_BUILD_DLL */
+#else /* ADBC_ODBC_HAS_DLL == 1 */
+# define ADBC_ODBC_Export
+# define ADBC_ODBC_SINGLETON_DECLARATION(T)
+# define ADBC_ODBC_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* ADBC_ODBC_HAS_DLL == 1 */
+
+// Set ADBC_ODBC_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (ADBC_ODBC_NTRACE)
+# if (ACE_NTRACE == 1)
+# define ADBC_ODBC_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define ADBC_ODBC_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !ADBC_ODBC_NTRACE */
+
+#if (ADBC_ODBC_NTRACE == 1)
+# define ADBC_ODBC_TRACE(X)
+#else /* (ADBC_ODBC_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define ADBC_ODBC_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (ADBC_ODBC_NTRACE == 1) */
+
+#endif /* ADBC_ODBC_EXPORT_H */
+
+// End of auto generated file.