diff options
author | Constantin Michael <constantin@codesynthesis.com> | 2011-09-05 12:10:45 +0200 |
---|---|---|
committer | Constantin Michael <constantin@codesynthesis.com> | 2011-09-05 16:08:45 +0200 |
commit | 63295f6e051e75cf07cb6212a2631df8eb8a90c4 (patch) | |
tree | 79aa54d3cdfa2b29c7f1a52829d12495250e6d9f /odb/oracle/database.cxx | |
parent | d6518580059c6a0d34d7a1683fabc3bfcc4b5e27 (diff) |
Add database, connection, connection-factory, and transaction support
Diffstat (limited to 'odb/oracle/database.cxx')
-rw-r--r-- | odb/oracle/database.cxx | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/odb/oracle/database.cxx b/odb/oracle/database.cxx new file mode 100644 index 0000000..239fa0d --- /dev/null +++ b/odb/oracle/database.cxx @@ -0,0 +1,230 @@ +// file : odb/oracle/database.cxx +// author : Constantin Michael <constantin@codesynthesis.com> +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : ODB NCUEL; see accompanying LICENSE file + +#include <sstream> + +#include <oci.h> + +#include <odb/oracle/database.hxx> +#include <odb/oracle/exceptions.hxx> +#include <odb/oracle/error.hxx> + +#include <odb/oracle/details/options.hxx> + +using namespace std; + +namespace odb +{ + namespace oracle + { + database:: + database (const string& user, + const string& password, + const string& db, + OCIEnv* environment, + auto_ptr<connection_factory> factory) + : user_ (user), + password_ (password), + db_ (db), + port_ (0), + environment_ (environment), + factory_ (factory) + { + if (environment_ == 0) + { + // @@ Be aware of encoding caveats. + // + sword s (OCIEnvNlsCreate (&environment_, + OCI_THREADED, + 0, 0, 0, 0, 0, 0, 0, 0)); + + if (s == OCI_ERROR) + translate_error (environment_); + + auto_environment_.reset (environment_); + } + } + + database:: + database (const string& user, + const string& password, + const string& service, + const string& host, + unsigned int port, + OCIEnv* environment, + auto_ptr<connection_factory> factory) + : user_ (user), + password_ (password), + service_ (service), + host_ (host), + port_ (port), + environment_ (environment), + factory_ (factory) + { + if (environment_ == 0) + { + // @@ Be aware of encoding caveats. + // + sword s (OCIEnvNlsCreate (&environment_, + OCI_THREADED, + 0, 0, 0, 0, 0, 0, 0, 0)); + + if (s == OCI_ERROR) + translate_error (environment_); + + auto_environment_.reset (environment_); + } + + ostringstream ss; + + if (!host.empty ()) + { + ss << "//" << host_; + + if (port != 0) + ss << ":" << port; + } + + if (!service_.empty ()) + { + if (!host.empty ()) + ss << "/" << service_; + else + ss << service_; + } + + // @@ Quote FQ connect identifier. + // + db_ = ss.str (); + + if (factory_.get () == 0) + factory_.reset (new connection_pool_factory ()); + + factory_->database (*this); + } + + database:: + database (int& argc, + char* argv[], + bool erase, + OCIEnv* environment, + auto_ptr<connection_factory> factory) + : port_ (0), + environment_ (environment), + factory_ (factory) + { + if (environment_ == 0) + { + // @@ Be aware of encoding caveats. + // + sword s (OCIEnvNlsCreate (&environment_, + OCI_THREADED, + 0, 0, 0, 0, 0, 0, 0, 0)); + + if (s == OCI_ERROR) + translate_error (environment_); + + auto_environment_.reset (environment_); + } + + using namespace details; + + try + { + cli::argv_file_scanner scan (argc, argv, "--options-file", erase); + options ops (scan, cli::unknown_mode::skip, cli::unknown_mode::skip); + + if (ops.user_specified ()) + user_ = ops.user (); + + if (ops.password_specified ()) + password_ = ops.password (); + + if (ops.database_specified ()) + { + if (ops.host_specified () || + ops.port_specified () || + ops.service_specified ()) + + throw cli_exception ("--host, --port, or --service options " + "cannot be specified together with " + "--database option"); + db_ = ops.database (); + } + else + { + bool host_present (false); + ostringstream oss; + + if (ops.host_specified () && !ops.host ().empty ()) + { + host_present = true; + + host_ = ops.host (); + oss << "//" << host_; + + if (ops.port_specified ()) + { + port_ = ops.port (); + + if (port_ != 0) + oss << ":" << port_; + } + } + + if (ops.service_specified () && !ops.service ().empty ()) + { + service_ = ops.service (); + + if (host_present) + oss << "/" << service_; + else + oss << service_; + } + + db_ = oss.str (); + } + + // @@ Quote FQ connect identifier. + // + } + catch (const cli::exception& e) + { + ostringstream oss; + oss << e; + throw cli_exception (oss.str ()); + } + + if (factory_.get () == 0) + factory_.reset (new connection_pool_factory ()); + + factory_->database (*this); + } + + void database:: + print_usage (std::ostream& os) + { + details::options::print_usage (os); + } + + database:: + ~database () + { + } + + transaction_impl* database:: + begin () + { + return new transaction_impl (*this); + } + + odb::connection* database:: + connection_ () + { + connection_ptr c (factory_->connect ()); + return c.release (); + } + } +} |