You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. //
  2. // Created by robin on 4/6/16.
  3. //
  4. #include <fstream>
  5. #include <string.h>
  6. #include <unistd.h>
  7. #include "PgSql.h"
  8. #define tmpTemplate "/tmp/pdns-slave.XXXXXX"
  9. PgSql::PgSql(const SqlConfiguration &masterConfig, const SqlConfiguration &slaveConfig)
  10. : AbstractSql(masterConfig, slaveConfig)
  11. {
  12. }
  13. PgSql::~PgSql()
  14. {
  15. if (!_dumpFilePath.empty())
  16. {
  17. unlink(_dumpFilePath.c_str());
  18. _dumpFilePath = "";
  19. }
  20. if (!_overrideFilePath.empty())
  21. {
  22. unlink(_overrideFilePath.c_str());
  23. _overrideFilePath = "";
  24. }
  25. }
  26. BResult PgSql::dump()
  27. {
  28. BResult res;
  29. _dumpFilePath = getTempFile();
  30. auto command = std::string("PGPASSWORD='" + _masterConfig.getPassword() + "' "
  31. + "pg_dump -h '" + _masterConfig.getHost() + "' "
  32. + "-U '" + _masterConfig.getUser() + "' "
  33. + "-w -c -x -O '" + _masterConfig.getDatabase() + "' "
  34. + "> '" + _dumpFilePath + "'");
  35. std::cout << command << std::endl;
  36. int status = system(command.c_str());
  37. if (status == 0)
  38. return res.ok(true);
  39. return res.error("pg_dump exited with code " + std::to_string(status));
  40. }
  41. const std::string PgSql::getTempFile()
  42. {
  43. char tmp[sizeof(tmpTemplate)];
  44. strcpy(tmp, tmpTemplate);
  45. mkstemp(tmp);
  46. return std::string(tmp);
  47. }
  48. BResult PgSql::insert()
  49. {
  50. return insertSlave(_dumpFilePath);
  51. }
  52. BResult PgSql::override(const std::string &sql)
  53. {
  54. _overrideFilePath = getTempFile();
  55. std::ofstream file(_overrideFilePath);
  56. if (!file)
  57. return BResult().error("Could not open temp file " + _overrideFilePath);
  58. file << sql;
  59. file.close();
  60. return insertSlave(_overrideFilePath);
  61. }
  62. BResult PgSql::insertSlave(const std::string &file)
  63. {
  64. BResult res;
  65. auto command = std::string("cat '" + file + "' | PGPASSWORD='" + _slaveConfig.getPassword() + "' "
  66. + "psql -h '" + _slaveConfig.getHost() + "' "
  67. + "-U '" + _slaveConfig.getUser() + "' "
  68. + "-w -d '" + _slaveConfig.getDatabase() + "' > /dev/null");
  69. std::cout << command << std::endl;
  70. int status = system(command.c_str());
  71. if (status == 0)
  72. return res.ok(true);
  73. return res.error("psql exited with code " + std::to_string(status));
  74. }