From 6cd8b9f561b912f264ba4f723845935c40a3cb95 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 21 Jun 2013 10:39:59 +0200 Subject: Add support for running tests in dynamic multi-database mode Only possible in the development build system at this stage. --- libcommon/common/common.cxx | 314 ++++++++++++++++++++++++++++++------------ libcommon/common/common.hxx | 13 +- libcommon/common/concrete.hxx | 9 ++ libcommon/common/makefile | 44 +++++- libcommon/makefile | 4 - 5 files changed, 284 insertions(+), 100 deletions(-) (limited to 'libcommon') 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 // std::move #include -#include - #include -#if defined(DATABASE_MYSQL) -# include -# include -#elif defined(DATABASE_SQLITE) -# include -# include -# include -# include -# include -#elif defined(DATABASE_PGSQL) -# include -# include -#elif defined(DATABASE_ORACLE) -# include -# include -#elif defined(DATABASE_MSSQL) -# include -# include -#else -# error unknown database -#endif - +#include #include 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 -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 db; +#include +#include -#if defined(DATABASE_MYSQL) +static auto_ptr +create_mysql_database (int& argc, char* argv[], bool, size_t max_connections) +{ + namespace mysql = odb::mysql; #ifdef HAVE_CXX11 unique_ptr 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 ( + 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 +#include +#include +#include +#include + +static auto_ptr +create_sqlite_database (int& argc, + char* argv[], + bool schema, + size_t max_connections) +{ + namespace sqlite = odb::sqlite; #ifdef HAVE_CXX11 unique_ptr 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 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 +#include + +static auto_ptr +create_pgsql_database (int& argc, char* argv[], bool, size_t max_connections) +{ + namespace pgsql = odb::pgsql; #ifdef HAVE_CXX11 unique_ptr 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 ( + 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 +#include + +static auto_ptr +create_oracle_database (int& argc, char* argv[], bool, size_t max_connections) +{ + namespace oracle = odb::oracle; #ifdef HAVE_CXX11 unique_ptr 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 ( + 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 +#include + +static auto_ptr +create_mssql_database (int& argc, char* argv[], bool, size_t max_connections) +{ + namespace mssql = odb::mssql; #ifdef HAVE_CXX11 unique_ptr 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 ( + 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 +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] << " [options]" << endl; + exit (1); + } +#endif + + if (argn != 0 && *argp == string ("--help")) + { +#if defined(DATABASE_COMMON) + cout << "Usage: " << argv[0] << " [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 (); +#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 -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 std::auto_ptr -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 r ( - create_database (argc, argv, create_schema, max_connections)); + create_database (argc, argv, + create_schema, + max_connections, + T::database_id)); + return std::auto_ptr (&dynamic_cast (*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 +#include + +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' >>$@ diff --git a/libcommon/makefile b/libcommon/makefile index 9d9b6e9..cade0e7 100644 --- a/libcommon/makefile +++ b/libcommon/makefile @@ -6,10 +6,6 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make dirs := common -default := $(out_base)/ -dist := $(out_base)/.dist -clean := $(out_base)/.clean - $(default): $(addprefix $(out_base)/,$(addsuffix /,$(dirs))) $(dist): export dirs := $(dirs) -- cgit v1.1