#include #include #include #include #include #include #include #include #include using namespace std; using namespace PGSTD; using namespace pqxx; namespace { //a very simple StopWatch class to measure time between issuing query and cancelling query class CStopWatch { public: CStopWatch(); void Start(); double Stop(); double Get() const { return elapsed_time; } void Reset() { elapsed_time = 0.0; start = end = 0; } private: clock_t start, end; long int clktck; double elapsed_time; }; //class to generate a SIGALRM which activates cancel_query after a defined time class CSigAlrmTimer { public: CSigAlrmTimer(double time_period, void(*sig_handler)(int)); ~CSigAlrmTimer(); static void alarm_handler(int signum); private: sigset_t oset; struct sigaction oact; }; //definiton of global alarm handler class //IT NEEDS A GLOBAL CNX, NEED TO RESTRUCTURE THE CODE TO DO THIS void alarm_handler(int signum); //YOU NEED A GLOBAL Connection_base variable instead of 'cnx' here //instead of a local cnx for the signal handler to cancel the query // I DON'T ENOUGH ABOUT THE TEST FRAMEWORK TO RESTRUCTURE THIS TEST // TO DO THIS. void test_cancel_query(connection_base & cnx, transaction_base &trans) { string sql_cmd; sql_cmd = "SELECT * FROM pg_sleep(2) "; //cout << "sql_cmd is: \n" << sql_cmd << endl; CStopWatch stopwatch; stopwatch.Start(); try { CSigAlrmTimer sigAlrmTimer(1.0, alarm_handler); trans.exec(sql_cmd, "Sleep for 2s\n"); } catch(sql_error& e) { stopwatch.Stop(); cerr << "SQL error: " << e.what() << endl << "Query was: '" << e.query() << "'" << endl; if(stopwatch.Get() < 1.1) cout << "PASS: alarm interrupted sleeping after " << stopwatch.Get() << " seconds\n"; else cout << "FAIL: alarm interrupted sleeping after " << stopwatch.Get() << " seconds\n"; return; } stopwatch.Stop(); cout << "FAILURE: Failed to cancel sleeping " << stopwatch.Get() << " seconds\n"; return; } //definitons of CStopWatch class CStopWatch::CStopWatch() :clktck(0) { errno = 0; if((clktck = sysconf(_SC_CLK_TCK)) < 0) { cout << "sysconf failed with: " << strerror(errno) << endl; return; //