diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2019-05-09 20:35:52 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2019-05-09 20:35:52 +0100 |
commit | 712960df1826305def34df4b6dd5c4343b8ec09d (patch) | |
tree | a09bf67202ed0c96415f2b5fd97be22986efa6a8 | |
parent | Get server version into a const local on construction (diff) | |
download | libdbpp-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.cpp | 44 | ||||
-rw-r--r-- | libpqpp/pq-mock.h | 3 |
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; }; } |