From 77bbae6038d20576a4807ed8ca834685a1e85afa Mon Sep 17 00:00:00 2001 From: Constantin Michael Date: Tue, 3 May 2011 12:26:33 +0200 Subject: Add pgsql database implementation --- odb/pgsql/database.cxx | 231 ++++++++++++++++++++++++++++++++++++++++++ odb/pgsql/database.hxx | 167 ++++++++++++++++++++++++++++++ odb/pgsql/database.ixx | 18 ++++ odb/pgsql/details/options.cli | 29 +++--- odb/pgsql/dummy.cxx | 6 -- odb/pgsql/exceptions.cxx | 35 +++++++ odb/pgsql/exceptions.hxx | 39 +++++++ odb/pgsql/forward.hxx | 36 +++++++ odb/pgsql/makefile | 8 +- 9 files changed, 547 insertions(+), 22 deletions(-) create mode 100644 odb/pgsql/database.cxx create mode 100644 odb/pgsql/database.hxx create mode 100644 odb/pgsql/database.ixx delete mode 100644 odb/pgsql/dummy.cxx create mode 100644 odb/pgsql/exceptions.cxx create mode 100644 odb/pgsql/exceptions.hxx create mode 100644 odb/pgsql/forward.hxx (limited to 'odb') diff --git a/odb/pgsql/database.cxx b/odb/pgsql/database.cxx new file mode 100644 index 0000000..22468a4 --- /dev/null +++ b/odb/pgsql/database.cxx @@ -0,0 +1,231 @@ +// file : odb/pgsql/database.cxx +// author : Constantin Michael +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include + +#include +#include + +#include + +using namespace std; + +namespace odb +{ + namespace pgsql + { + database:: + database (const string& user, + const string& password, + const string& db, + const string& host, + unsigned int port, + const string& extra_conninfo, + auto_ptr factory) + : user_ (user), + password_ (password), + db_ (db), + host_ (host), + port_ (port), + extra_conninfo_ (extra_conninfo), + factory_ (factory) + { + ostringstream ss; + + if (!user.empty ()) + ss << "user='" << user << "' "; + + if (!password.empty ()) + ss << "password='" << password << "' "; + + if (!db.empty ()) + ss << "dbname='" << db << "' "; + + if (!host.empty ()) + ss << "host='" << host << "' "; + + if (port) + ss << "port=" << port << " "; + + // Only the last occurence of keyword/value pair is used by libpq. + // extra_conninfo specified options take precedence. + // + if (!extra_conninfo.empty ()) + ss << extra_conninfo; + + conninfo_ = ss.str (); + + // @@ Uncomment once factory has been implemented. + // + // if (factory_.get () == 0) + // factory_.reset (new connection_pool_factory ()); + + // factory_->database (*this); + } + + database:: + database (const string& user, + const string& password, + const string& db, + const string& host, + const string& socket_ext, + const string& extra_conninfo, + auto_ptr factory) + : user_ (user), + password_ (password), + db_ (db), + host_ (host), + port_ (0), + socket_ext_ (socket_ext), + extra_conninfo_ (extra_conninfo), + factory_ (factory) + { + ostringstream ss; + + if (!user.empty ()) + ss << "user='" << user << "' "; + + if (!password.empty ()) + ss << "password='" << password << "' "; + + if (!db.empty ()) + ss << "dbname='" << db << "' "; + + if (!host.empty ()) + ss << "host='" << host << "' "; + + if (!socket_ext.empty ()) + ss << "port='" << socket_ext << "' "; + + // Only the last occurence of keyword/value pair is used by libpq. + // extra_conninfo specified options take precedence. + // + if (!extra_conninfo.empty ()) + ss << extra_conninfo; + + conninfo_ = ss.str (); + + // @@ Uncomment once factory has been implemented. + // + // if (factory_.get () == 0) + // factory_.reset (new connection_pool_factory ()); + + // factory_->database (*this); + } + + database:: + database (const string& conninfo, + auto_ptr factory) + : port_ (0), conninfo_ (conninfo), factory_ (factory) + { + // @@ Uncomment once factory has been implemented. + // + // if (factory_.get () == 0) + // factory_.reset (new connection_pool_factory ()); + + // factory_->database (*this); + } + + database:: + database (int& argc, + char* argv[], + bool erase, + const string& extra_conninfo, + auto_ptr factory) + : port_ (0), factory_ (factory) + { + 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); + + ostringstream oss; + + if (ops.user_specified ()) + { + user_ = ops.user (); + oss << "user='" << user_ << "' "; + } + + if (ops.password_specified ()) + { + password_ = ops.password (); + oss << "password='" << password_ << "' "; + } + + if (ops.database_specified ()) + { + db_ = ops.database (); + oss << "dbname='" << db_ << "' "; + } + + if (ops.host_specified ()) + { + host_ = ops.host (); + oss << "host='" << host_ << "' "; + } + + if (ops.port_specified ()) + { + istringstream iss (ops.port ()); + + if (iss >> port_ && iss.eof ()) + oss << " port=" << port_ << " "; + else + { + port_ = 0; + socket_ext_ = ops.port (); + oss << "port='" << socket_ext_ << "' "; + } + } + + if (!extra_conninfo.empty ()) + oss << extra_conninfo; + + conninfo_ = oss.str (); + } + catch (const cli::exception& e) + { + ostringstream oss; + oss << e; + throw cli_exception (oss.str ()); + } + + // @@ Uncomment once factory has been implemented. + // + // 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 () + { + } + + // @@ Implement on completion of supporting code. + // + // unsigned long long database:: + // execute (const char* s, std::size_t n) + // { + // } + + // @@ Implement on completion of supporting code. + // + // transaction_impl* database:: + // begin () + // { + // } + } +} diff --git a/odb/pgsql/database.hxx b/odb/pgsql/database.hxx new file mode 100644 index 0000000..fbd15b9 --- /dev/null +++ b/odb/pgsql/database.hxx @@ -0,0 +1,167 @@ +// file : odb/pgsql/database.hxx +// author : Constantin Michael +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_PGSQL_DATABASE_HXX +#define ODB_PGSQL_DATABASE_HXX + +#include + +#include +#include // std::auto_ptr +#include // std::ostream + +#include + +#include +#include + +#include + +namespace odb +{ + namespace pgsql + { + class LIBODB_PGSQL_EXPORT database: public odb::database + { + public: + database (const std::string& db, + const std::string& user, + const std::string& password, + const std::string& host = "", + unsigned int port = 0, + const std::string& extra_conninfo = "", + std::auto_ptr factory = + std::auto_ptr (0)); + + database (const std::string& db, + const std::string& user, + const std::string& password, + const std::string& host = "", + const std::string& socket_ext = "", + const std::string& extra_conninfo = "", + std::auto_ptr factory = + std::auto_ptr (0)); + + explicit + database (const std::string& conninfo, + std::auto_ptr = + std::auto_ptr (0)); + + // Extract the database parameters from the command line. The + // following options are recognized: + // + // --user | --username + // --password + // --database | --dbname + // --host + // --port + // --options-file + // + // For more information, see the output of the print_usage() function + // below. If erase is true, the above options are removed from the + // argv array and the argc count is updated accordingly. This + // constructor may throw the cli_exception exception. + // + database (int& argc, + char* argv[], + bool erase = false, + const std::string& extra_conninfo = "", + std::auto_ptr = + std::auto_ptr (0)); + + static void + print_usage (std::ostream&); + + public: + // @@ Implement on completion of supporting code. + // + // using odb::database::execute; + // virtual unsigned long long + // execute (const char* statement, std::size_t length); + + public: + // @@ Implement on completion of supporting code. + // + // virtual transaction_impl* + // begin (); + + public: + // @@ Implement on completion of supporting code. + // + // details::shared_ptr + // connection (); + + public: + virtual + ~database (); + + public: + const std::string& + host () const + { + return host_; + } + + const std::string& + db () const + { + return db_; + } + + const std::string& + user () const + { + return user_; + } + + const std::string& + password () const + { + return password_; + } + + unsigned int + port () const + { + return port_; + } + + const std::string& + socket_ext () const + { + return socket_ext_; + } + + const std::string& + extra_conninfo () const + { + return extra_conninfo_; + } + + const std::string& + conninfo () const + { + return conninfo_; + } + + private: + std::string user_; + std::string password_; + std::string db_; + std::string host_; + unsigned int port_; + std::string socket_ext_; + std::string extra_conninfo_; + std::string conninfo_; + std::auto_ptr factory_; + }; + } +} + +#include + +#include + +#endif // ODB_PGSQL_DATABASE_HXX diff --git a/odb/pgsql/database.ixx b/odb/pgsql/database.ixx new file mode 100644 index 0000000..04fcb16 --- /dev/null +++ b/odb/pgsql/database.ixx @@ -0,0 +1,18 @@ +// file : odb/pgsql/database.ixx +// author : Constantin Michael +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +namespace odb +{ + namespace pgsql + { + // @@ Implement on completion of supporting code. + // + // inline details::shared_ptr database:: + // connection () + // { + // return factory_->connect (); + // } + } +} diff --git a/odb/pgsql/details/options.cli b/odb/pgsql/details/options.cli index 925cef3..ef81993 100644 --- a/odb/pgsql/details/options.cli +++ b/odb/pgsql/details/options.cli @@ -13,7 +13,7 @@ namespace odb { class options { - std::string --user + std::string --user | --username { "", "PostgreSQL database user." @@ -22,10 +22,10 @@ namespace odb std::string --password { "", - "PostgreSQL database password" + "PostgreSQL database password." }; - std::string --dbname + std::string --database | --dbname { "", "PostgreSQL database name." @@ -33,21 +33,24 @@ namespace odb std::string --host { - "", - "Name of the PostgreSQL host to connect to (localhost by default)." + "", + "PostgreSQL database host name or address (localhost by default)." }; - std::string --hostaddr + std::string --port { - "", - "Numeric IP address of host to connect to in dotted-decimal format." + "", + "PostgreSQL database port number or socket file name extension for + Unix-domain connections." }; - unsigned int --port = 0 - { - "", - "PostgreSQL database port number." - }; + std::string --options-file + { + "" + "Read additional options from . Each option appearing on a + separate line optionally followed by space and an option value. + Empty lines and lines starting with \cb{#} are ignored." + }; }; } } diff --git a/odb/pgsql/dummy.cxx b/odb/pgsql/dummy.cxx deleted file mode 100644 index 2fbc6c8..0000000 --- a/odb/pgsql/dummy.cxx +++ /dev/null @@ -1,6 +0,0 @@ -#include - -PGconn* dummy () -{ - return PQconnectdb ("connection info"); -} diff --git a/odb/pgsql/exceptions.cxx b/odb/pgsql/exceptions.cxx new file mode 100644 index 0000000..bea0870 --- /dev/null +++ b/odb/pgsql/exceptions.cxx @@ -0,0 +1,35 @@ +// file : odb/pgsql/exceptions.cxx +// author : Constantin Michael +// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include + +using namespace std; + +namespace odb +{ + namespace pgsql + { + // + // cli_exception + // + + cli_exception:: + cli_exception (const std::string& what) + : what_ (what) + { + } + + cli_exception:: + ~cli_exception () throw () + { + } + + const char* cli_exception:: + what () const throw () + { + return what_.c_str (); + } + } +} diff --git a/odb/pgsql/exceptions.hxx b/odb/pgsql/exceptions.hxx new file mode 100644 index 0000000..0ceb83c --- /dev/null +++ b/odb/pgsql/exceptions.hxx @@ -0,0 +1,39 @@ +// file : odb/pgsql/exceptions.hxx +// author : Constantin Michael +// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_PGSQL_EXCEPTIONS_HXX +#define ODB_PGSQL_EXCEPTIONS_HXX + +#include + +#include + +#include + +#include + +#include + +namespace odb +{ + namespace pgsql + { + struct LIBODB_PGSQL_EXPORT cli_exception: odb::exception + { + cli_exception (const std::string& what); + ~cli_exception () throw (); + + virtual const char* + what () const throw (); + + private: + std::string what_; + }; + } +} + +#include + +#endif // ODB_PGSQL_EXCEPTIONS_HXX diff --git a/odb/pgsql/forward.hxx b/odb/pgsql/forward.hxx new file mode 100644 index 0000000..8b8ac90 --- /dev/null +++ b/odb/pgsql/forward.hxx @@ -0,0 +1,36 @@ +// file : odb/pgsql/forward.hxx +// author : Constantin Michael +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_PGSQL_FORWARD_HXX +#define ODB_PGSQL_FORWARD_HXX + +#include + +namespace odb +{ + namespace pgsql + { + class database; + class connection; + class connection_factory; + class transaction; + class query; + + // Implementation details. + // + class binding; + class select_statement; + + template + class object_statements; + + template + class container_statements; + } +} + +#include + +#endif // ODB_PGSQL_FORWARD_HXX diff --git a/odb/pgsql/makefile b/odb/pgsql/makefile index 63e0289..11e8762 100644 --- a/odb/pgsql/makefile +++ b/odb/pgsql/makefile @@ -1,12 +1,14 @@ # file : odb/pgsql/makefile # author : Boris Kolpackov +# author : Constantin Michael # copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC # license : GNU GPL v2; see accompanying LICENSE file include $(dir $(lastword $(MAKEFILE_LIST)))../../build/bootstrap.make -cxx := \ -dummy.cxx +cxx := \ +database.cxx \ +exceptions.cxx cli_tun := details/options.cli cxx_tun := $(cxx) @@ -28,7 +30,7 @@ $(call import,\ $(call import,\ $(scf_root)/import/libodb/stub.make,\ - l: odb.l,cpp-options: odb.l.cpp-options) + l: odb.l,cpp-options: odb.l.cpp-options) $(call import,\ $(scf_root)/import/libpq/stub.make,\ -- cgit v1.1