summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2019-05-09 20:35:52 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2019-05-09 20:35:52 +0100
commit712960df1826305def34df4b6dd5c4343b8ec09d (patch)
treea09bf67202ed0c96415f2b5fd97be22986efa6a8
parentGet server version into a const local on construction (diff)
downloadlibdbpp-postgresql-712960df1826305def34df4b6dd5c4343b8ec09d.tar.bz2
libdbpp-postgresql-712960df1826305def34df4b6dd5c4343b8ec09d.tar.xz
libdbpp-postgresql-712960df1826305def34df4b6dd5c4343b8ec09d.zip
Create mock databases in a temporary directory
Requires v9.3 server for COPY ... TO PROGRAM ... support, which is used to get the server to create a directory with suitable permissions. This directory is created in the system temporary directory and used as the default tablespace for the mock database.
-rw-r--r--libpqpp/pq-mock.cpp44
-rw-r--r--libpqpp/pq-mock.h3
2 files changed, 44 insertions, 3 deletions
diff --git a/libpqpp/pq-mock.cpp b/libpqpp/pq-mock.cpp
index 99128c3..499d839 100644
--- a/libpqpp/pq-mock.cpp
+++ b/libpqpp/pq-mock.cpp
@@ -12,11 +12,18 @@ namespace PQ {
Mock::Mock(const std::string & masterdb, const std::string & name, const std::vector<std::filesystem::path> & ss) :
MockServerDatabase(masterdb, name, "postgresql"),
+ tablespacePath(std::filesystem::temp_directory_path() / testDbName),
serverVersion(std::static_pointer_cast<Connection>(master)->serverVersion())
{
- CreateNewDatabase();
- PlaySchemaScripts(ss);
- SetTablesToUnlogged();
+ try {
+ CreateNewDatabase();
+ PlaySchemaScripts(ss);
+ SetTablesToUnlogged();
+ }
+ catch (...) {
+ DropDatabase();
+ throw;
+ }
}
AdHocFormatter(MockConnStr, "user=postgres dbname=%?");
@@ -66,6 +73,33 @@ Mock::~Mock()
Mock::DropDatabase();
}
+bool
+Mock::hasCopyToProgram() const
+{
+ // v9.3 server required to use COPY ... TO PROGRAM ...
+ return (serverVersion >= 90300);
+}
+
+AdHocFormatter(MockCreateTablespaceDir, "COPY (SELECT 1) TO PROGRAM 'mkdir -p %?'");
+AdHocFormatter(MockCreateTablespace, "CREATE TABLESPACE %? LOCATION '%?'");
+AdHocFormatter(MockCreateDatabase, "CREATE DATABASE %? TABLESPACE %?");
+AdHocFormatter(MockDropTablespace, "DROP TABLESPACE IF EXISTS %?");
+AdHocFormatter(MockDropTablespaceDir, "COPY (SELECT 1) TO PROGRAM 'rm -rf %?'");
+
+void
+Mock::CreateNewDatabase() const
+{
+ if (hasCopyToProgram()) {
+ DropDatabase();
+ master->execute(MockCreateTablespaceDir::get(tablespacePath));
+ master->execute(MockCreateTablespace::get(testDbName, tablespacePath.string()));
+ master->execute(MockCreateDatabase::get(testDbName, testDbName));
+ }
+ else {
+ MockServerDatabase::CreateNewDatabase();
+ }
+}
+
void
Mock::DropDatabase() const
{
@@ -73,6 +107,10 @@ Mock::DropDatabase() const
t->bindParamS(0, testDbName);
t->execute();
MockServerDatabase::DropDatabase();
+ if (hasCopyToProgram()) {
+ master->execute(MockDropTablespace::get(testDbName));
+ master->execute(MockDropTablespaceDir::get(tablespacePath));
+ }
}
}
diff --git a/libpqpp/pq-mock.h b/libpqpp/pq-mock.h
index c802080..b5f4f24 100644
--- a/libpqpp/pq-mock.h
+++ b/libpqpp/pq-mock.h
@@ -15,8 +15,11 @@ namespace PQ {
DB::ConnectionPtr openConnection() const override;
protected:
+ void CreateNewDatabase() const override;
void DropDatabase() const override;
void SetTablesToUnlogged() const;
+ bool hasCopyToProgram() const;
+ const std::filesystem::path tablespacePath;
const int serverVersion;
};
}