summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2015-09-22 21:36:18 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2015-09-22 21:36:18 +0100
commitf071b65bd8deb230a771a64aab5024f5cc55fd91 (patch)
tree5f33ae4c8c25679abb65682d70d363d7bbce6b93
parentMigrate SQL script parser and add support for executing a script on a connection (diff)
downloadlibdbpp-f071b65bd8deb230a771a64aab5024f5cc55fd91.tar.bz2
libdbpp-f071b65bd8deb230a771a64aab5024f5cc55fd91.tar.xz
libdbpp-f071b65bd8deb230a771a64aab5024f5cc55fd91.zip
Database mocking base classes migrated in.
-rw-r--r--libdbpp/mockDatabase.cpp114
-rw-r--r--libdbpp/mockDatabase.h49
2 files changed, 163 insertions, 0 deletions
diff --git a/libdbpp/mockDatabase.cpp b/libdbpp/mockDatabase.cpp
new file mode 100644
index 0000000..3ef8728
--- /dev/null
+++ b/libdbpp/mockDatabase.cpp
@@ -0,0 +1,114 @@
+#include "mockDatabase.h"
+#include <buffer.h>
+#include <fstream>
+#include <modifycommand.h>
+
+namespace DB {
+
+unsigned int MockDatabase::mocked = 0;
+
+MockDatabase::MockDatabase(const std::string & name) :
+ mockName(name)
+{
+}
+
+MockDatabase::~MockDatabase()
+{
+}
+
+void
+MockDatabase::PlaySchemaScripts(const std::vector<boost::filesystem::path> & ss) const
+{
+ DB::Connection * conn = openConnection();
+ try {
+ CreateStatusTable(conn);
+ for (auto s : ss) {
+ conn->beginTx();
+ PlaySchemaScript(conn, s);
+ conn->commitTx();
+ }
+ DropStatusTable(conn);
+ delete conn;
+ }
+ catch (...) {
+ if (conn->inTx()) {
+ conn->rollbackTx();
+ }
+ delete conn;
+ DropDatabase();
+ throw;
+ }
+}
+
+void
+MockDatabase::PlaySchemaScript(DB::Connection * conn, const boost::filesystem::path & s) const
+{
+ UpdateStatusTable(conn, s);
+ std::ifstream f;
+ f.open(s.string());
+ if (!f.good()) {
+ throw std::runtime_error("Failed to open mock script: " + s.string());
+ }
+ conn->executeScript(f, s.parent_path());
+ f.close();
+}
+
+void
+MockDatabase::CreateStatusTable(DB::Connection * conn) const
+{
+ conn->execute(
+ "CREATE TABLE _p2_teststatus( \
+ pid int, \
+ script varchar(256), \
+ scriptdir varchar(256))");
+ auto ins = conn->newModifyCommand(
+ "INSERT INTO _p2_teststatus(pid) VALUES(?)");
+ ins->bindParamI(0, getpid());
+ ins->execute();
+ delete ins;
+}
+
+void
+MockDatabase::DropStatusTable(DB::Connection * conn) const
+{
+ conn->execute("DROP TABLE _p2_teststatus");
+}
+
+void
+MockDatabase::UpdateStatusTable(DB::Connection * conn, const boost::filesystem::path & script) const
+{
+ auto upd = conn->newModifyCommand(
+ "UPDATE _p2_teststatus SET script = ?, scriptdir = ?");
+ upd->bindParamS(0, script.string());
+ upd->bindParamS(1, script.parent_path().string());
+ upd->execute();
+ delete upd;
+}
+
+MockServerDatabase::MockServerDatabase(const std::string & masterdb, const std::string & name, const std::string & type) :
+ MockDatabase(name),
+ master(DB::ConnectionFactory::create(type, masterdb)),
+ testDbName(stringbf("test_%d_%d", getpid(), ++mocked))
+{
+}
+
+MockServerDatabase::~MockServerDatabase()
+{
+ delete master;
+}
+
+void
+MockServerDatabase::CreateNewDatabase() const
+{
+ DropDatabase();
+ master->execute("CREATE DATABASE " + testDbName);
+}
+
+void
+MockServerDatabase::DropDatabase() const
+{
+ master->execute("DROP DATABASE IF EXISTS " + testDbName);
+}
+
+}
+
diff --git a/libdbpp/mockDatabase.h b/libdbpp/mockDatabase.h
new file mode 100644
index 0000000..e314b84
--- /dev/null
+++ b/libdbpp/mockDatabase.h
@@ -0,0 +1,49 @@
+#ifndef MOCKDATABASE_H
+#define MOCKDATABASE_H
+
+#include <string>
+#include <vector>
+#include <boost/filesystem/path.hpp>
+#include "connection.h"
+
+namespace DB {
+
+class MockDatabase {
+ public:
+ MockDatabase(const std::string & mockName);
+ virtual ~MockDatabase();
+
+ virtual DB::Connection * openConnection() const = 0;
+
+ protected:
+ virtual void CreateNewDatabase() const = 0;
+ virtual void PlaySchemaScripts(const std::vector<boost::filesystem::path> & ss) const;
+ virtual void PlaySchemaScript(DB::Connection *, const boost::filesystem::path & s) const;
+ virtual void DropDatabase() const = 0;
+ virtual void UpdateStatusTable(DB::Connection *, const boost::filesystem::path &) const;
+
+ const std::string mockName;
+ static unsigned int mocked;
+
+ private:
+ void CreateStatusTable(DB::Connection *) const;
+ void DropStatusTable(DB::Connection *) const;
+};
+
+class MockServerDatabase : public MockDatabase {
+ public:
+ MockServerDatabase(const std::string & masterdb, const std::string & name, const std::string & type);
+ virtual ~MockServerDatabase();
+
+ protected:
+ virtual void CreateNewDatabase() const override;
+ virtual void DropDatabase() const override;
+
+ DB::Connection * master;
+ const std::string testDbName;
+};
+
+}
+
+#endif
+