summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2015-12-31 04:04:31 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2017-05-04 20:44:40 +0100
commitdb1e2f066393af3e58814417de5bbe7ea08a145d (patch)
tree9d01e48d8ef7d63fbcca6aced2461b3f1e234dfd
parentBeginnings of embbeded MySQL (diff)
downloadlibdbpp-mysql-db1e2f066393af3e58814417de5bbe7ea08a145d.tar.bz2
libdbpp-mysql-db1e2f066393af3e58814417de5bbe7ea08a145d.tar.xz
libdbpp-mysql-db1e2f066393af3e58814417de5bbe7ea08a145d.zip
Basics working, could do with a tidy up around mocking
-rw-r--r--libmysqlpp/embeddedmy-connection.cpp64
-rw-r--r--libmysqlpp/embeddedmy-connection.h7
-rw-r--r--libmysqlpp/embeddedmy-mock.cpp30
-rw-r--r--libmysqlpp/embeddedmy-mock.h30
-rw-r--r--libmysqlpp/embeddedmy-server.cpp83
-rw-r--r--libmysqlpp/embeddedmy-server.h45
-rw-r--r--libmysqlpp/my-connection.cpp41
-rw-r--r--libmysqlpp/my-connection.h3
-rw-r--r--libmysqlpp/my-opts.cpp34
-rw-r--r--libmysqlpp/my-opts.h22
-rw-r--r--libmysqlpp/unittests/Jamfile.jam2
-rw-r--r--libmysqlpp/unittests/test.impl.h (renamed from libmysqlpp/unittests/testMain.cpp)77
-rw-r--r--libmysqlpp/unittests/testmysql.cpp45
-rw-r--r--libmysqlpp/unittests/testmysqle.cpp18
14 files changed, 371 insertions, 130 deletions
diff --git a/libmysqlpp/embeddedmy-connection.cpp b/libmysqlpp/embeddedmy-connection.cpp
index f0bb24d..2a21450 100644
--- a/libmysqlpp/embeddedmy-connection.cpp
+++ b/libmysqlpp/embeddedmy-connection.cpp
@@ -1,16 +1,74 @@
#include "embeddedmy-connection.h"
+#include "my-opts.h"
+#include <nvpParse.h>
NAMEDFACTORY("embeddedmysql", MySQL::Embedded::Connection, DB::ConnectionFactory);
namespace MySQL {
namespace Embedded {
- Connection::Connection(const std::string &)
+ class Opts {
+ public:
+ boost::filesystem::path path;
+ MySQL::OptString database;
+ MySQL::OptString options;
+ std::vector<std::string> serverOptions;
+ };
+
+ using namespace AdHoc;
+ NvpTarget(Opts) OptsTargetMap {
+ NvpValue(Opts, path),
+ NvpValue(Opts, database),
+ NvpValue(Opts, options),
+ NvpValue(Opts, serverOptions),
+ };
+
+ Connection::Connection(const std::string & str)
{
+ std::stringstream i(str);
+ Opts o;
+ NvpParse::parse(i, OptsTargetMap, o);
mysql_init(&conn);
+ if (o.options) {
+ mysql_options(&conn, MYSQL_READ_DEFAULT_GROUP, ~o.options);
+ }
mysql_options(&conn, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
- if (mysql_real_connect(&conn, NULL, NULL, NULL, "database1", 0, NULL, 0)) {
- throw MySQL::Error(&conn);
+ server = Server::get(o.path, o.serverOptions);
+ if (mysql_real_connect(&conn, NULL, NULL, NULL, ~o.database,
+ 0, NULL, CLIENT_LOCAL_FILES | CLIENT_MULTI_STATEMENTS) == NULL) {
+ throw MySQL::ConnectionError(&conn);
+ }
+ if (mysql_set_character_set(&conn, "utf8")) {
+ throw MySQL::ConnectionError(&conn);
+ }
+ }
+
+ Connection::Connection(Server *, const std::string & db)
+ {
+ mysql_init(&conn);
+ mysql_options(&conn, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
+ if (mysql_real_connect(&conn, NULL, NULL, NULL, db.c_str(),
+ 0, NULL, CLIENT_LOCAL_FILES | CLIENT_MULTI_STATEMENTS) == NULL) {
+ throw MySQL::ConnectionError(&conn);
+ }
+ if (mysql_set_character_set(&conn, "utf8")) {
+ throw MySQL::ConnectionError(&conn);
}
}
+
+ void Connection::beginBulkUpload(const char * t, const char * e)
+ {
+ DB::Connection::beginBulkUpload(t, e);
+ }
+
+ void Connection::endBulkUpload(const char * msg)
+ {
+ DB::Connection::endBulkUpload(msg);
+ }
+
+ size_t Connection::bulkUploadData(const char * b, size_t s) const
+ {
+ return DB::Connection::bulkUploadData(b, s);
+ }
+
}
}
diff --git a/libmysqlpp/embeddedmy-connection.h b/libmysqlpp/embeddedmy-connection.h
index 3ceba2f..c94d86a 100644
--- a/libmysqlpp/embeddedmy-connection.h
+++ b/libmysqlpp/embeddedmy-connection.h
@@ -2,6 +2,7 @@
#define EMBEDDEDMY_CONNECTION_H
#include "my-connection.h"
+#include "embeddedmy-server.h"
#include "my-error.h"
#include <mysql.h>
@@ -10,8 +11,14 @@ namespace MySQL {
class Connection : public ::MySQL::Connection {
public:
Connection(const std::string &);
+ Connection(Server *, const std::string &);
+
+ void beginBulkUpload(const char *, const char *) override;
+ void endBulkUpload(const char *) override;
+ size_t bulkUploadData(const char *, size_t) const override;
private:
+ ServerPtr server;
};
}
}
diff --git a/libmysqlpp/embeddedmy-mock.cpp b/libmysqlpp/embeddedmy-mock.cpp
index 0ad0cc5..9e66bb3 100644
--- a/libmysqlpp/embeddedmy-mock.cpp
+++ b/libmysqlpp/embeddedmy-mock.cpp
@@ -1,5 +1,6 @@
#include "embeddedmy-connection.h"
#include "embeddedmy-mock.h"
+#include "embeddedmy-server.h"
#include <boost/filesystem/convenience.hpp>
#include <buffer.h>
@@ -8,7 +9,7 @@ namespace MySQL {
Mock::Mock(const std::string & name, const std::vector<boost::filesystem::path> & ss) :
MockDatabase(name),
- testDbPath(boost::filesystem::path("/tmp") / stringbf("embeddedmysql-%d-%d", getpid(), ++DB::MockDatabase::mocked))
+ dbname(stringbf("test_%d_%d", getpid(), ++DB::MockDatabase::mocked))
{
CreateNewDatabase();
PlaySchemaScripts(ss);
@@ -22,30 +23,29 @@ namespace MySQL {
DB::Connection *
Mock::openConnection() const
{
- return new Connection(testDbPath.string());
+ return new Connection(stringbf("path=%s;database=%s", mockDbPath(), dbname));
}
void
Mock::CreateNewDatabase() const
{
- boost::filesystem::create_directories(testDbPath);
- const auto datadir = stringbf("--datadir=%s", testDbPath.string());
- static const char * opts[] = {
- typeid(this).name(),
- datadir.c_str(),
- "--bootstrap",
- NULL
- };
- static const char * groups[] = { NULL };
- mysql_library_init(3, (char**)opts, (char**)groups);
- sleep(20);
+ auto path = mockDbPath();
+ embeddedServer = Server::getMock(path);
+ Connection initialize(embeddedServer.get(), "mysql");
+ initialize.execute("CREATE DATABASE " + dbname);
}
void
Mock::DropDatabase() const
{
- mysql_library_end();
- boost::filesystem::remove_all(testDbPath);
+ Connection initialize(embeddedServer.get(), "mysql");
+ initialize.execute("DROP DATABASE " + dbname);
+ }
+
+ boost::filesystem::path
+ Mock::mockDbPath()
+ {
+ return boost::filesystem::temp_directory_path() / stringbf("mysql-mock-%d", getpid());
}
}
}
diff --git a/libmysqlpp/embeddedmy-mock.h b/libmysqlpp/embeddedmy-mock.h
index 0b90b4b..cad10eb 100644
--- a/libmysqlpp/embeddedmy-mock.h
+++ b/libmysqlpp/embeddedmy-mock.h
@@ -4,26 +4,30 @@
#include <mockDatabase.h>
#include <boost/filesystem/path.hpp>
#include <visibility.h>
+#include <boost/shared_ptr.hpp>
+#include "embeddedmy-server.h"
namespace MySQL {
-namespace Embedded {
+ namespace Embedded {
+ class DLL_PUBLIC Mock : public DB::MockDatabase {
+ public:
+ Mock(const std::string & name, const std::vector<boost::filesystem::path> & ss);
+ ~Mock();
-class DLL_PUBLIC Mock : public DB::MockDatabase {
- public:
- Mock(const std::string & name, const std::vector<boost::filesystem::path> & ss);
- ~Mock();
+ protected:
+ void DropDatabase() const override;
+ void CreateNewDatabase() const override;
- protected:
- void DropDatabase() const override;
- void CreateNewDatabase() const override;
+ DB::Connection * openConnection() const override;
- DB::Connection * openConnection() const override;
+ private:
+ static boost::filesystem::path mockDbPath();
- private:
- const boost::filesystem::path testDbPath;
-};
+ std::string dbname;
+ mutable ServerPtr embeddedServer;
+ };
-}
+ }
}
#endif
diff --git a/libmysqlpp/embeddedmy-server.cpp b/libmysqlpp/embeddedmy-server.cpp
new file mode 100644
index 0000000..a0fc3e3
--- /dev/null
+++ b/libmysqlpp/embeddedmy-server.cpp
@@ -0,0 +1,83 @@
+#include "embeddedmy-server.h"
+#include "embeddedmy-connection.h"
+#include <stdexcept>
+#include <buffer.h>
+#include <mysql.h>
+#include <boost/filesystem/convenience.hpp>
+#include <fstream>
+
+namespace MySQL {
+ namespace Embedded {
+ ServerPtr
+ Server::get(const boost::filesystem::path & path, const std::vector<std::string> & extraOpts)
+ {
+ if (instance) {
+ if (path == instance->path) {
+ return instance;
+ }
+ throw std::runtime_error(stringbf("Only one embedded server per process. [old=%s, new=%s]", instance->path, path));
+ }
+ instance = new Server(path, extraOpts);
+ return instance;
+ }
+
+ ServerPtr
+ Server::getMock(const boost::filesystem::path & path)
+ {
+ boost::filesystem::create_directories(path / "mysql");
+ if (instance) {
+ if (path == instance->path && dynamic_cast<MockServer *>(instance)) {
+ return instance;
+ }
+ throw std::runtime_error(stringbf("Only one embedded server per process. [old=%s, new=%s]", instance->path, path));
+ }
+ auto i = new MockServer(path);
+ i->initialize();
+ return (instance = i);
+ }
+
+ Server::Server(const boost::filesystem::path & p, const std::vector<std::string> & extraOpts) :
+ path(p)
+ {
+ const auto datadir = stringbf("--datadir=%s", path.string());
+ std::vector<const char *> opts;
+ opts.push_back(typeid(this).name());
+ opts.push_back(datadir.c_str());
+ for (auto & opt : extraOpts) {
+ opts.push_back(opt.c_str());
+ }
+ opts.push_back(nullptr);
+ static const char * groups[] = { NULL };
+ mysql_library_init(opts.size() - 1, (char**)&opts.front(), (char**)groups);
+ }
+
+ Server::~Server()
+ {
+ mysql_library_end();
+ instance = nullptr;
+ }
+
+ MockServer::MockServer(const boost::filesystem::path & p) :
+ Server(p, { "--bootstrap" })
+ {
+ }
+
+ void
+ MockServer::initialize()
+ {
+ Connection initialize(this, "mysql");
+ std::ifstream sql1("/usr/share/mysql/mysql_system_tables.sql");
+ initialize.executeScript(sql1, path);
+ std::ifstream sql2("/usr/share/mysql/mysql_system_tables_data.sql");
+ initialize.executeScript(sql2, path);
+ }
+
+ MockServer::~MockServer()
+ {
+ boost::filesystem::remove_all(path);
+ }
+
+ Server * Server::instance = nullptr;
+ }
+}
+
diff --git a/libmysqlpp/embeddedmy-server.h b/libmysqlpp/embeddedmy-server.h
new file mode 100644
index 0000000..a1fa7fb
--- /dev/null
+++ b/libmysqlpp/embeddedmy-server.h
@@ -0,0 +1,45 @@
+#ifndef MYSQL_EMBEDDED_SERVER_H
+#define MYSQL_EMBEDDED_SERVER_H
+
+#include <string>
+#include <vector>
+#include <boost/filesystem/path.hpp>
+#include <intrusivePtrBase.h>
+#include <boost/intrusive_ptr.hpp>
+
+namespace MySQL {
+ namespace Embedded {
+ class Server;
+
+ typedef boost::intrusive_ptr<Server> ServerPtr;
+
+ class Server : public IntrusivePtrBase {
+ public:
+ virtual ~Server();
+
+ static ServerPtr get(const boost::filesystem::path &, const std::vector<std::string> &);
+ static ServerPtr getMock(const boost::filesystem::path &);
+
+ protected:
+ Server(const boost::filesystem::path &, const std::vector<std::string> &);
+
+ const boost::filesystem::path path;
+
+ private:
+ static Server * instance;
+ };
+
+ class MockServer : public Server {
+ public:
+ MockServer(const boost::filesystem::path &);
+
+ void initialize();
+
+ public:
+ ~MockServer();
+ };
+ }
+}
+
+#endif
+
diff --git a/libmysqlpp/my-connection.cpp b/libmysqlpp/my-connection.cpp
index 04c1f8c..2be253b 100644
--- a/libmysqlpp/my-connection.cpp
+++ b/libmysqlpp/my-connection.cpp
@@ -2,6 +2,7 @@
#include "my-error.h"
#include "my-selectcommand.h"
#include "my-modifycommand.h"
+#include "my-opts.h"
#include <nvpParse.h>
#include <runtimeContext.h>
#include <ucontext.h>
@@ -18,35 +19,15 @@ MySQL::ConnectionError::ConnectionError(MYSQL * m) :
class Opts {
public:
Opts() { port = 3306; }
- typedef boost::optional<std::string> OptString;
- OptString server;
- OptString user;
- OptString password;
- OptString database;
+ MySQL::OptString server;
+ MySQL::OptString user;
+ MySQL::OptString password;
+ MySQL::OptString database;
unsigned int port;
- OptString unix_socket;
- OptString options;
+ MySQL::OptString unix_socket;
+ MySQL::OptString options;
};
-const char *
-operator~(const Opts::OptString & os)
-{
- if (os) {
- return os->c_str();
- }
- return NULL;
-}
-
-namespace std {
- template <typename T>
- std::istream &
- operator>>(std::istream & s, boost::optional<T> & o)
- {
- o = T();
- return (s >> *o);
- }
-}
-
using namespace AdHoc;
NvpTarget(Opts) OptsTargetMap {
NvpValue(Opts, server),
@@ -143,6 +124,14 @@ MySQL::Connection::newModifyCommand(const std::string & sql, const DB::CommandOp
return new ModifyCommand(this, sql);
}
+void
+MySQL::Connection::execute(const std::string & sql)
+{
+ if (mysql_query(&conn, sql.c_str())) {
+ throw Error(&conn);
+ }
+}
+
namespace MySQL {
class LoadContext : public AdHoc::System::RuntimeContext {
public:
diff --git a/libmysqlpp/my-connection.h b/libmysqlpp/my-connection.h
index fdc3e5a..36e9388 100644
--- a/libmysqlpp/my-connection.h
+++ b/libmysqlpp/my-connection.h
@@ -8,7 +8,7 @@
#include <boost/shared_ptr.hpp>
namespace MySQL {
- class ConnectionError : public virtual Error, public virtual DB::ConnectionError {
+ class DLL_PUBLIC ConnectionError : public virtual Error, public virtual DB::ConnectionError {
public:
ConnectionError(MYSQL *);
};
@@ -35,6 +35,7 @@ namespace MySQL {
size_t bulkUploadData(const char *, size_t) const override;
int64_t insertId() override;
+ void execute(const std::string &) override;
mutable MYSQL conn;
diff --git a/libmysqlpp/my-opts.cpp b/libmysqlpp/my-opts.cpp
new file mode 100644
index 0000000..b0a777d
--- /dev/null
+++ b/libmysqlpp/my-opts.cpp
@@ -0,0 +1,34 @@
+#include "my-opts.h"
+
+namespace MySQL {
+ const char *
+ operator~(const OptString & os)
+ {
+ if (os) {
+ return os->c_str();
+ }
+ return NULL;
+ }
+}
+
+namespace std {
+ template <typename T>
+ std::istream &
+ operator>>(std::istream & s, std::vector<T> & o)
+ {
+ o.push_back(T());
+ return (s >> o.back());
+ }
+
+ template <typename T>
+ std::istream &
+ operator>>(std::istream & s, boost::optional<T> & o)
+ {
+ o = T();
+ return (s >> *o);
+ }
+
+ template std::istream & operator>>(std::istream & s, boost::optional<std::string> & o);
+ template std::istream & operator>>(std::istream & s, std::vector<std::string> & o);
+}
+
diff --git a/libmysqlpp/my-opts.h b/libmysqlpp/my-opts.h
new file mode 100644
index 0000000..e444fa8
--- /dev/null
+++ b/libmysqlpp/my-opts.h
@@ -0,0 +1,22 @@
+#ifndef MYSQL_OPTS_H
+#define MYSQL_OPTS_H
+
+#include <boost/optional.hpp>
+#include <string>
+#include <visibility.h>
+
+namespace MySQL {
+ typedef boost::optional<std::string> OptString;
+
+ DLL_PUBLIC const char * operator~(const OptString & os);
+}
+
+namespace std {
+ template <typename T>
+ DLL_PUBLIC std::istream & operator>>(std::istream & s, boost::optional<T> & o);
+ template <typename T>
+ DLL_PUBLIC std::istream & operator>>(std::istream & s, std::vector<T> & o);
+}
+
+#endif
+
diff --git a/libmysqlpp/unittests/Jamfile.jam b/libmysqlpp/unittests/Jamfile.jam
index c7bf637..d4014ea 100644
--- a/libmysqlpp/unittests/Jamfile.jam
+++ b/libmysqlpp/unittests/Jamfile.jam
@@ -24,7 +24,7 @@ run
run
testmysqle.cpp
- : : :
+ : --log_level=all : :
<define>ROOT=\"$(me)\"
<define>BOOST_TEST_DYN_LINK
<library>..//dbpp-mysql-embedded
diff --git a/libmysqlpp/unittests/testMain.cpp b/libmysqlpp/unittests/test.impl.h
index 0811d5c..13ae738 100644
--- a/libmysqlpp/unittests/testMain.cpp
+++ b/libmysqlpp/unittests/test.impl.h
@@ -1,17 +1,19 @@
+#include <boost/test/unit_test.hpp>
#include <modifycommand.h>
#include <selectcommand.h>
+#include <connection.h>
+#include <mockDatabase.h>
#include <column.h>
#include <testCore.h>
#include <fstream>
#include <boost/date_time/posix_time/posix_time.hpp>
-
-BOOST_GLOBAL_FIXTURE( StandardMockDatabase );
+#include <definedDirs.h>
BOOST_FIXTURE_TEST_SUITE( Core, DB::TestCore );
BOOST_AUTO_TEST_CASE( transactions )
{
- auto ro = DB::MockDatabase::openConnectionTo("mysqlmock");
+ auto ro = DB::ConnectionPtr(DB::MockDatabase::openConnectionTo("mysqlmock"));
BOOST_REQUIRE_EQUAL(false, ro->inTx());
ro->beginTx();
@@ -23,15 +25,13 @@ BOOST_AUTO_TEST_CASE( transactions )
BOOST_REQUIRE_EQUAL(true, ro->inTx());
ro->commitTx();
BOOST_REQUIRE_EQUAL(false, ro->inTx());
-
- delete ro;
}
BOOST_AUTO_TEST_CASE( bindAndSend )
{
- auto rw = DB::MockDatabase::openConnectionTo("mysqlmock");
+ auto rw = DB::ConnectionPtr(DB::MockDatabase::openConnectionTo("mysqlmock"));
- auto mod = rw->newModifyCommand("INSERT INTO test VALUES(?, ?, ?, ?, ?, ?)");
+ auto mod = rw->modify("INSERT INTO test VALUES(?, ?, ?, ?, ?, ?)");
mod->bindParamI(0, testInt);
mod->bindParamF(1, testDouble);
mod->bindParamS(2, testString);
@@ -39,15 +39,13 @@ BOOST_AUTO_TEST_CASE( bindAndSend )
mod->bindParamT(4, testDateTime);
mod->bindParamT(5, testInterval);
mod->execute();
- delete mod;
- delete rw;
}
BOOST_AUTO_TEST_CASE( bindAndSelect )
{
- auto ro = DB::MockDatabase::openConnectionTo("mysqlmock");
+ auto ro = DB::ConnectionPtr(DB::MockDatabase::openConnectionTo("mysqlmock"));
- auto select = ro->newSelectCommand("SELECT * FROM test WHERE id = ?");
+ auto select = ro->select("SELECT * FROM test WHERE id = ?");
select->bindParamI(0, testInt);
select->execute();
int rows = 0;
@@ -60,16 +58,14 @@ BOOST_AUTO_TEST_CASE( bindAndSelect )
assertColumnValueHelper(*select, 5, testInterval);
rows += 1;
}
- delete select;
BOOST_REQUIRE_EQUAL(1, rows);
- delete ro;
}
BOOST_AUTO_TEST_CASE( bindAndSelectOther )
{
- auto ro = DB::MockDatabase::openConnectionTo("mysqlmock");
+ auto ro = DB::ConnectionPtr(DB::MockDatabase::openConnectionTo("mysqlmock"));
- auto select = ro->newSelectCommand("SELECT * FROM test WHERE id != ?");
+ auto select = ro->select("SELECT * FROM test WHERE id != ?");
select->bindParamI(0, testInt);
select->execute();
int rows = 0;
@@ -82,54 +78,13 @@ BOOST_AUTO_TEST_CASE( bindAndSelectOther )
assertColumnValueHelper(*select, 5, boost::posix_time::time_duration(38, 13, 12));
rows += 1;
}
- delete select;
BOOST_REQUIRE_EQUAL(1, rows);
- delete ro;
-}
-
-BOOST_AUTO_TEST_CASE( bulkload )
-{
- auto ro = DB::MockDatabase::openConnectionTo("mysqlmock");
-
- auto count = ro->newSelectCommand("SELECT COUNT(*) FROM bulktest");
- // Test empty
- ro->beginBulkUpload("bulktest", "");
- ro->endBulkUpload(NULL);
- assertScalarValueHelper(*count, 0);
- // Test sample file
- ro->beginBulkUpload("bulktest", "");
- std::ifstream in((rootDir / "bulk.sample").string());
- if (!in.good()) throw std::runtime_error("Couldn't open bulk.sample");
- char buf[BUFSIZ];
- for (std::streamsize r; (r = in.readsome(buf, sizeof(buf))) > 0; ) {
- ro->bulkUploadData(buf, r);
- }
- ro->endBulkUpload(NULL);
- assertScalarValueHelper(*count, 800);
-
- delete count;
- delete ro;
-}
-
-BOOST_AUTO_TEST_CASE( bigIterate )
-{
- auto ro = DB::MockDatabase::openConnectionTo("mysqlmock");
-
- auto count = ro->newSelectCommand("SELECT * FROM bulktest");
- unsigned int rows = 0;
- while (count->fetch()) {
- rows += 1;
- }
- BOOST_REQUIRE_EQUAL(800, rows);
-
- delete count;
- delete ro;
}
BOOST_AUTO_TEST_CASE( insertId )
{
- auto ro = DB::MockDatabase::openConnectionTo("mysqlmock");
- auto ins = ro->newModifyCommand("INSERT INTO inserts(num) VALUES(?)");
+ auto ro = DB::ConnectionPtr(DB::MockDatabase::openConnectionTo("mysqlmock"));
+ auto ins = ro->modify("INSERT INTO inserts(num) VALUES(?)");
ins->bindParamI(0, 4);
ins->execute();
BOOST_REQUIRE_EQUAL(1, ro->insertId());
@@ -139,18 +94,14 @@ BOOST_AUTO_TEST_CASE( insertId )
ins->bindParamI(0, -4);
ins->execute();
BOOST_REQUIRE_EQUAL(3, ro->insertId());
- delete ins;
- delete ro;
}
BOOST_AUTO_TEST_CASE( errors )
{
- auto ro = DB::MockDatabase::openConnectionTo("mysqlmock");
+ auto ro = DB::ConnectionPtr(DB::MockDatabase::openConnectionTo("mysqlmock"));
BOOST_REQUIRE_THROW(ro->execute("nonsense"), DB::Error);
- delete ro;
BOOST_REQUIRE_THROW(DB::ConnectionFactory::createNew("mysql", "server=nohost"), DB::ConnectionError);
}
BOOST_AUTO_TEST_SUITE_END();
-
diff --git a/libmysqlpp/unittests/testmysql.cpp b/libmysqlpp/unittests/testmysql.cpp
index d363716..fd29485 100644
--- a/libmysqlpp/unittests/testmysql.cpp
+++ b/libmysqlpp/unittests/testmysql.cpp
@@ -1,6 +1,3 @@
-#define BOOST_TEST_MODULE TestMySQL
-#include <boost/test/unit_test.hpp>
-
#include <my-mock.h>
#include <definedDirs.h>
@@ -12,5 +9,45 @@ class StandardMockDatabase : public MySQL::Mock {
}
};
-#include "testMain.cpp"
+#define BOOST_TEST_MODULE TestMySQL
+
+#include "test.impl.h"
+BOOST_GLOBAL_FIXTURE( StandardMockDatabase );
+
+BOOST_FIXTURE_TEST_SUITE( Core, DB::TestCore );
+
+BOOST_AUTO_TEST_CASE( bulkload )
+{
+ auto ro = DB::ConnectionPtr(DB::MockDatabase::openConnectionTo("mysqlmock"));
+
+ auto count = ro->select("SELECT COUNT(*) FROM bulktest");
+ // Test empty
+ ro->beginBulkUpload("bulktest", "");
+ ro->endBulkUpload(NULL);
+ assertScalarValueHelper(*count, 0);
+ // Test sample file
+ ro->beginBulkUpload("bulktest", "");
+ std::ifstream in((rootDir / "bulk.sample").string());
+ if (!in.good()) throw std::runtime_error("Couldn't open bulk.sample");
+ char buf[BUFSIZ];
+ for (std::streamsize r; (r = in.readsome(buf, sizeof(buf))) > 0; ) {
+ ro->bulkUploadData(buf, r);
+ }
+ ro->endBulkUpload(NULL);
+ assertScalarValueHelper(*count, 800);
+}
+
+BOOST_AUTO_TEST_CASE( bigIterate )
+{
+ auto ro = DB::ConnectionPtr(DB::MockDatabase::openConnectionTo("mysqlmock"));
+
+ auto count = ro->select("SELECT * FROM bulktest");
+ unsigned int rows = 0;
+ while (count->fetch()) {
+ rows += 1;
+ }
+ BOOST_REQUIRE_EQUAL(800, rows);
+}
+
+BOOST_AUTO_TEST_SUITE_END();
diff --git a/libmysqlpp/unittests/testmysqle.cpp b/libmysqlpp/unittests/testmysqle.cpp
index 0d1defb..659433b 100644
--- a/libmysqlpp/unittests/testmysqle.cpp
+++ b/libmysqlpp/unittests/testmysqle.cpp
@@ -1,6 +1,3 @@
-#define BOOST_TEST_MODULE TestEmbeddedMySQL
-#include <boost/test/unit_test.hpp>
-
#include <embeddedmy-mock.h>
#include <definedDirs.h>
@@ -12,5 +9,18 @@ class StandardMockDatabase : public MySQL::Embedded::Mock {
}
};
-#include "testMain.cpp"
+#define BOOST_TEST_MODULE TestEmbeddedMySQL
+
+#include "test.impl.h"
+BOOST_GLOBAL_FIXTURE( StandardMockDatabase );
+
+BOOST_FIXTURE_TEST_SUITE( Core, DB::TestCore );
+
+BOOST_AUTO_TEST_CASE( bulkload )
+{
+ auto ro = DB::ConnectionPtr(DB::MockDatabase::openConnectionTo("mysqlmock"));
+ BOOST_REQUIRE_THROW(ro->beginBulkUpload("any", nullptr), DB::BulkUploadNotSupported);
+}
+
+BOOST_AUTO_TEST_SUITE_END();