1 // Copyright (C) 2016-2020 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 #include <string>
9 #include <pgsql/pgsql_connection.h>
10 #include <pgsql/testutils/pgsql_schema.h>
11 #include <exceptions/exceptions.h>
12 
13 #include <libpq-fe.h>
14 
15 #include <fstream>
16 #include <iostream>
17 #include <sstream>
18 #include <stdlib.h>
19 
20 using namespace std;
21 
22 namespace isc {
23 namespace db {
24 namespace test {
25 
26 const char* PGSQL_VALID_TYPE = "type=postgresql";
27 
28 string
validPgSQLConnectionString()29 validPgSQLConnectionString() {
30     return (connectionString(PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST,
31                              VALID_USER, VALID_PASSWORD));
32 }
33 
destroyPgSQLSchema(bool show_err,bool force)34 void destroyPgSQLSchema(bool show_err, bool force) {
35     // If force is true or wipePgSQLData() fails, destroy the schema.
36     if (force || (!softWipeEnabled()) || wipePgSQLData(show_err)) {
37         runPgSQLScript(DATABASE_SCRIPTS_DIR, "pgsql/dhcpdb_drop.pgsql", show_err);
38     }
39 }
40 
createPgSQLSchema(bool show_err,bool force)41 void createPgSQLSchema(bool show_err, bool force) {
42     // If force is true or wipePgSQLData() fails, recreate the schema.
43     if (force || (!softWipeEnabled()) || wipePgSQLData(show_err)) {
44         destroyPgSQLSchema(show_err, true);
45         runPgSQLScript(DATABASE_SCRIPTS_DIR, "pgsql/dhcpdb_create.pgsql", show_err);
46     }
47 }
48 
wipePgSQLData(bool show_err)49 bool wipePgSQLData(bool show_err) {
50     std::ostringstream cmd;
51 
52     // Pass psql the password via environment variable.
53     cmd << "export PGPASSWORD=keatest;";
54 
55     // Add in the wipe shell script invocation.
56     cmd << " sh " << DATABASE_SCRIPTS_DIR << "/pgsql/wipe_data.sh";
57 
58     // Add expected schema version as the wipe script's first argument.
59     cmd  << " " << PG_SCHEMA_VERSION_MAJOR  << "." << PG_SCHEMA_VERSION_MINOR;
60 
61     // Now add command line arguments for psql.
62     cmd  << " --set ON_ERROR_STOP=1 -A -t -h localhost -q -U keatest -d keatest";
63 
64     // Suppress error output.
65     if (!show_err) {
66         cmd << " 2>/dev/null ";
67     }
68 
69     // Execute the command string.
70     int retval = ::system(cmd.str().c_str());
71     if (retval) {
72         std::cerr << "wipePgSQLData failed:[" << cmd.str() << "]" << std::endl;
73     }
74 
75     return(retval);
76 }
77 
runPgSQLScript(const std::string & path,const std::string & script_name,bool show_err)78 void runPgSQLScript(const std::string& path, const std::string& script_name,
79                     bool show_err) {
80     std::ostringstream cmd;
81 
82     cmd << "export PGPASSWORD=keatest; cat ";
83     if (!path.empty()) {
84         cmd << " < " << path << "/";
85     }
86 
87     cmd << script_name
88         << " | psql --set ON_ERROR_STOP=1 -A -t -h localhost -q -U keatest -d keatest";
89 
90     if (!show_err) {
91         cmd << " 2>/dev/null ";
92     }
93 
94     int retval = ::system(cmd.str().c_str());
95     if (retval) {
96         std::cerr << "runPgSQLSchema failed: " << cmd.str() << std::endl;
97         isc_throw(Unexpected, "runPgSQLSchema failed: " << cmd.str());
98     }
99 }
100 
101 }  // namespace test
102 }  // namespace dhcp
103 }  // namespace isc
104