diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2013-06-21 10:39:59 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2013-06-21 10:39:59 +0200 |
commit | 6cd8b9f561b912f264ba4f723845935c40a3cb95 (patch) | |
tree | 5983e0af3d2ee621242ca6707a58c89b9914d8f0 /libcommon/common | |
parent | 236cd9bb1dd022e64d690c9b0080d1a15c5f61c7 (diff) |
Add support for running tests in dynamic multi-database mode
Only possible in the development build system at this stage.
Diffstat (limited to 'libcommon/common')
-rw-r--r-- | libcommon/common/common.cxx | 314 | ||||
-rw-r--r-- | libcommon/common/common.hxx | 13 | ||||
-rw-r--r-- | libcommon/common/concrete.hxx | 9 | ||||
-rw-r--r-- | libcommon/common/makefile | 44 |
4 files changed, 284 insertions, 96 deletions
diff --git a/libcommon/common/common.cxx b/libcommon/common/common.cxx index 65fbcfe..4ca2b68 100644 --- a/libcommon/common/common.cxx +++ b/libcommon/common/common.cxx @@ -6,80 +6,26 @@ #include <utility> // std::move #include <iostream> -#include <common/config.hxx> - #include <odb/database.hxx> -#if defined(DATABASE_MYSQL) -# include <odb/mysql/database.hxx> -# include <odb/mysql/connection-factory.hxx> -#elif defined(DATABASE_SQLITE) -# include <odb/connection.hxx> -# include <odb/transaction.hxx> -# include <odb/schema-catalog.hxx> -# include <odb/sqlite/database.hxx> -# include <odb/sqlite/connection-factory.hxx> -#elif defined(DATABASE_PGSQL) -# include <odb/pgsql/database.hxx> -# include <odb/pgsql/connection-factory.hxx> -#elif defined(DATABASE_ORACLE) -# include <odb/oracle/database.hxx> -# include <odb/oracle/connection-factory.hxx> -#elif defined(DATABASE_MSSQL) -# include <odb/mssql/database.hxx> -# include <odb/mssql/connection-factory.hxx> -#else -# error unknown database -#endif - +#include <common/config.hxx> #include <common/common.hxx> using namespace std; using namespace odb::core; -#if defined(DATABASE_MYSQL) -namespace mysql = odb::mysql; -#elif defined(DATABASE_SQLITE) -namespace sqlite = odb::sqlite; -#elif defined(DATABASE_PGSQL) -namespace pgsql = odb::pgsql; -#elif defined(DATABASE_ORACLE) -namespace oracle = odb::oracle; -#elif defined(DATABASE_MSSQL) -namespace mssql = odb::mssql; -#endif - -auto_ptr<database> -create_database (int& argc, - char* argv[], -#if defined(DATABASE_SQLITE) - bool schema, -#else - bool, -#endif - size_t max_connections) -{ - if (argc > 1 && argv[1] == string ("--help")) - { - cout << "Usage: " << argv[0] << " [options]" << endl - << "Options:" << endl; - -#if defined(DATABASE_MYSQL) - mysql::database::print_usage (cout); -#elif defined(DATABASE_SQLITE) - sqlite::database::print_usage (cout); -#elif defined(DATABASE_PGSQL) - pgsql::database::print_usage (cout); -#elif defined(DATABASE_ORAClE) - oracle::database::print_usage (cout); -#endif - exit (0); - } +// MySQL. +// +#if defined(DATABASE_MYSQL) || defined(DATABASE_COMMON) - auto_ptr<database> db; +#include <odb/mysql/database.hxx> +#include <odb/mysql/connection-factory.hxx> -#if defined(DATABASE_MYSQL) +static auto_ptr<database> +create_mysql_database (int& argc, char* argv[], bool, size_t max_connections) +{ + namespace mysql = odb::mysql; #ifdef HAVE_CXX11 unique_ptr<mysql::connection_factory> f; @@ -90,15 +36,35 @@ create_database (int& argc, if (max_connections != 0) f.reset (new mysql::connection_pool_factory (max_connections)); - db.reset (new mysql::database (argc, argv, false, "", 0, + return auto_ptr<database> ( + new mysql::database (argc, argv, false, "", 0, #ifdef HAVE_CXX11 - move (f) + move (f) #else - f + f #endif - )); + )); +} +#endif // MySQL -#elif defined(DATABASE_SQLITE) + +// SQLite. +// +#if defined(DATABASE_SQLITE) || defined(DATABASE_COMMON) + +#include <odb/connection.hxx> +#include <odb/transaction.hxx> +#include <odb/schema-catalog.hxx> +#include <odb/sqlite/database.hxx> +#include <odb/sqlite/connection-factory.hxx> + +static auto_ptr<database> +create_sqlite_database (int& argc, + char* argv[], + bool schema, + size_t max_connections) +{ + namespace sqlite = odb::sqlite; #ifdef HAVE_CXX11 unique_ptr<sqlite::connection_factory> f; @@ -109,7 +75,7 @@ create_database (int& argc, if (max_connections != 0) f.reset (new sqlite::connection_pool_factory (max_connections)); - db.reset ( + auto_ptr<database> db ( new sqlite::database ( argc, argv, false, SQLITE_OPEN_READWRITE @@ -144,7 +110,22 @@ create_database (int& argc, c->execute ("PRAGMA foreign_keys=ON"); } -#elif defined(DATABASE_PGSQL) + return db; +} +#endif // SQLite + + +// PostgreSQL. +// +#if defined(DATABASE_PGSQL) || defined(DATABASE_COMMON) + +#include <odb/pgsql/database.hxx> +#include <odb/pgsql/connection-factory.hxx> + +static auto_ptr<database> +create_pgsql_database (int& argc, char* argv[], bool, size_t max_connections) +{ + namespace pgsql = odb::pgsql; #ifdef HAVE_CXX11 unique_ptr<pgsql::connection_factory> f; @@ -155,15 +136,29 @@ create_database (int& argc, if (max_connections != 0) f.reset (new pgsql::connection_pool_factory (max_connections)); - db.reset (new pgsql::database (argc, argv, false, "", + return auto_ptr<database> ( + new pgsql::database (argc, argv, false, "", #ifdef HAVE_CXX11 - move (f) + move (f) #else - f + f #endif - )); + )); +} +#endif // PostgreSQL -#elif defined(DATABASE_ORACLE) + +// Oracle. +// +#if defined(DATABASE_ORACLE) || defined(DATABASE_COMMON) + +#include <odb/oracle/database.hxx> +#include <odb/oracle/connection-factory.hxx> + +static auto_ptr<database> +create_oracle_database (int& argc, char* argv[], bool, size_t max_connections) +{ + namespace oracle = odb::oracle; #ifdef HAVE_CXX11 unique_ptr<oracle::connection_factory> f; @@ -177,15 +172,28 @@ create_database (int& argc, // Set client database character set and client national character set // to UTF-8. // - db.reset (new oracle::database (argc, argv, false, 873, 873, 0, + return auto_ptr<database> ( + new oracle::database (argc, argv, false, 873, 873, 0, #ifdef HAVE_CXX11 - move (f) + move (f) #else - f + f #endif - )); + )); +} +#endif // Oracle -#elif defined(DATABASE_MSSQL) +// SQL Server. +// +#if defined(DATABASE_MSSQL) || defined(DATABASE_COMMON) + +#include <odb/mssql/database.hxx> +#include <odb/mssql/connection-factory.hxx> + +static auto_ptr<database> +create_mssql_database (int& argc, char* argv[], bool, size_t max_connections) +{ + namespace mssql = odb::mssql; #ifdef HAVE_CXX11 unique_ptr<mssql::connection_factory> f; @@ -196,18 +204,147 @@ create_database (int& argc, if (max_connections != 0) f.reset (new mssql::connection_pool_factory (max_connections)); - db.reset (new mssql::database (argc, argv, false, "", - mssql::isolation_read_committed, 0, + return auto_ptr<database> ( + new mssql::database (argc, argv, false, "", + mssql::isolation_read_committed, 0, #ifdef HAVE_CXX11 - move (f) + move (f) #else - f + f #endif - )); + )); +} +#endif // SQL Server + +// +// +auto_ptr<database> +create_database (int argc, + char* argv[], + bool schema, + size_t max_connections, +#if defined(DATABASE_COMMON) + odb::database_id db +#else + odb::database_id #endif +) +{ + char** argp (argv + 1); // Position of the next argument. + int argn (argc - 1); // Number of arguments left. - return db; +#if defined(DATABASE_COMMON) + // Figure out which database we are creating. We may be given the + // database name as a program argument or as an id. + // + if (db == odb::id_common && argn != 0) + { + string s (*argp); + + if (s == "mysql") + db = odb::id_mysql; + else if (s == "sqlite") + db = odb::id_sqlite; + else if (s == "pgsql") + db = odb::id_pgsql; + else if (s == "oracle") + db = odb::id_oracle; + else if (s == "mssql") + db = odb::id_mssql; + + if (db != odb::id_common) + { + argp++; + argn--; + } + } + + if (db == odb::id_common) + { + cerr << "Usage: " << argv[0] << " <db> [options]" << endl; + exit (1); + } +#endif + + if (argn != 0 && *argp == string ("--help")) + { +#if defined(DATABASE_COMMON) + cout << "Usage: " << argv[0] << " <db> [options]" << endl; +#else + cout << "Usage: " << argv[0] << " [options]" << endl; +#endif + + cout << "Options:" << endl; + +#if defined(DATABASE_MYSQL) + odb::mysql::database::print_usage (cout); +#elif defined(DATABASE_SQLITE) + odb::sqlite::database::print_usage (cout); +#elif defined(DATABASE_PGSQL) + odb::pgsql::database::print_usage (cout); +#elif defined(DATABASE_ORACLE) + odb::oracle::database::print_usage (cout); +#elif defined(DATABASE_MSSQL) + odb::mssql::database::print_usage (cout); +#elif defined(DATABASE_COMMON) + switch (db) + { + case odb::id_mysql: + odb::mysql::database::print_usage (cout); + break; + case odb::id_sqlite: + odb::sqlite::database::print_usage (cout); + break; + case odb::id_pgsql: + odb::pgsql::database::print_usage (cout); + break; + case odb::id_oracle: + odb::oracle::database::print_usage (cout); + break; + case odb::id_mssql: + odb::mssql::database::print_usage (cout); + break; + case odb::id_common: + assert (false); + } +#else +# error unknown database +#endif + + exit (0); + } + +#if defined(DATABASE_MYSQL) + return create_mysql_database (argc, argv, schema, max_connections); +#elif defined(DATABASE_SQLITE) + return create_sqlite_database (argc, argv, schema, max_connections); +#elif defined(DATABASE_PGSQL) + return create_pgsql_database (argc, argv, schema, max_connections); +#elif defined(DATABASE_ORACLE) + return create_oracle_database (argc, argv, schema, max_connections); +#elif defined(DATABASE_MSSQL) + return create_mssql_database (argc, argv, schema, max_connections); +#elif defined(DATABASE_COMMON) + switch (db) + { + case odb::id_mysql: + return create_mysql_database (argc, argv, schema, max_connections); + case odb::id_sqlite: + return create_sqlite_database (argc, argv, schema, max_connections); + case odb::id_pgsql: + return create_pgsql_database (argc, argv, schema, max_connections); + case odb::id_oracle: + return create_oracle_database (argc, argv, schema, max_connections); + case odb::id_mssql: + return create_mssql_database (argc, argv, schema, max_connections); + case odb::id_common: + assert (false); + } + return auto_ptr<database> (); +#else +# error unknown database +#endif } bool @@ -215,7 +352,8 @@ size_available () { #if defined(DATABASE_SQLITE) || \ defined(DATABASE_ORACLE) || \ - defined(DATABASE_MSSQL) + defined(DATABASE_MSSQL) || \ + defined(DATABASE_COMMON) return false; #else return true; diff --git a/libcommon/common/common.hxx b/libcommon/common/common.hxx index 114dbdd..f9bbd4d 100644 --- a/libcommon/common/common.hxx +++ b/libcommon/common/common.hxx @@ -20,20 +20,25 @@ #endif LIBCOMMON_EXPORT std::auto_ptr<odb::database> -create_database (int& argc, +create_database (int argc, char* argv[], bool create_schema = true, - std::size_t max_connections = 0); + std::size_t max_connections = 0, + odb::database_id db = odb::id_common); template <typename T> std::auto_ptr<T> -create_specific_database (int& argc, +create_specific_database (int argc, char* argv[], bool create_schema = true, std::size_t max_connections = 0) { std::auto_ptr<odb::database> r ( - create_database (argc, argv, create_schema, max_connections)); + create_database (argc, argv, + create_schema, + max_connections, + T::database_id)); + return std::auto_ptr<T> (&dynamic_cast<T&> (*r.release ())); } diff --git a/libcommon/common/concrete.hxx b/libcommon/common/concrete.hxx index 3141ba4..5c28b63 100644 --- a/libcommon/common/concrete.hxx +++ b/libcommon/common/concrete.hxx @@ -44,6 +44,15 @@ namespace odb_db = odb::oracle; namespace odb_db = odb::mssql; +#elif defined(DATABASE_COMMON) + +// Fallback to common interface. +// +#include <odb/database.hxx> +#include <odb/transaction.hxx> + +namespace odb_db = odb; + #endif #endif // LIBCOMMON_COMMON_CONCRETE_HXX diff --git a/libcommon/common/makefile b/libcommon/common/makefile index 53df875..5d23fa9 100644 --- a/libcommon/common/makefile +++ b/libcommon/common/makefile @@ -12,10 +12,6 @@ cxx_od := $(cxx_obj:.o=.o.d) common.l := $(out_base)/common.l common.l.cpp-options := $(out_base)/common.l.cpp-options -default := $(out_base)/ -dist := $(out_base)/.dist -clean := $(out_base)/.clean - # Import. # $(call import,\ @@ -23,9 +19,47 @@ $(call import,\ l: odb.l,cpp-options: odb.l.cpp-options) ifdef db_id +ifneq ($(db_id),common) $(call import,\ $(scf_root)/import/libodb-$(db_id)/stub.make,\ l: odb_db.l,cpp-options: odb_db.l.cpp-options) +else +# Import all database runtimes. +# +$(call import,\ + $(scf_root)/import/libodb-mysql/stub.make,\ + l: odb_mysql.l,cpp-options: odb_mysql.l.cpp-options) + +$(call import,\ + $(scf_root)/import/libodb-sqlite/stub.make,\ + l: odb_sqlite.l,cpp-options: odb_sqlite.l.cpp-options) + +$(call import,\ + $(scf_root)/import/libodb-pgsql/stub.make,\ + l: odb_pgsql.l,cpp-options: odb_pgsql.l.cpp-options) + +$(call import,\ + $(scf_root)/import/libodb-oracle/stub.make,\ + l: odb_oracle.l,cpp-options: odb_oracle.l.cpp-options) + +$(call import,\ + $(scf_root)/import/libodb-mssql/stub.make,\ + l: odb_mssql.l,cpp-options: odb_mssql.l.cpp-options) + +odb_db.l := \ +$(odb_mysql.l) \ +$(odb_sqlite.l) \ +$(odb_pgsql.l) \ +$(odb_oracle.l) \ +$(odb_mssql.l) + +odb_db.l.cpp-options := \ +$(odb_mysql.l.cpp-options) \ +$(odb_sqlite.l.cpp-options) \ +$(odb_pgsql.l.cpp-options) \ +$(odb_oracle.l.cpp-options) \ +$(odb_mssql.l.cpp-options) +endif endif ifeq ($(odb_db.l.cpp-options),) @@ -62,6 +96,8 @@ else ifeq ($(db_id),oracle) @echo '#define DATABASE_ORACLE 1' >>$@ else ifeq ($(db_id),mssql) @echo '#define DATABASE_MSSQL 1' >>$@ +else ifeq ($(db_id),common) + @echo '#define DATABASE_COMMON 1' >>$@ endif ifeq ($(cxx_standard),c++11) @echo '#define HAVE_CXX11 1' >>$@ |