Changeset 1378
- Timestamp:
- 08/13/08 16:22:42 (5 months ago)
- Files:
-
- trunk/ChangeLog (modified) (1 diff)
- trunk/test/test072.cxx (modified) (1 diff)
- trunk/test/test073.cxx (modified) (1 diff)
- trunk/test/test074.cxx (modified) (1 diff)
- trunk/test/test075.cxx (modified) (2 diffs)
- trunk/test/test076.cxx (modified) (2 diffs)
- trunk/test/test077.cxx (modified) (2 diffs)
- trunk/test/test078.cxx (modified) (4 diffs)
- trunk/test/test079.cxx (modified) (3 diffs)
- trunk/test/test080.cxx (modified) (2 diffs)
- trunk/test/test082.cxx (modified) (2 diffs)
- trunk/test/test083.cxx (modified) (2 diffs)
- trunk/test/test084.cxx (modified) (4 diffs)
- trunk/test/test085.cxx (modified) (4 diffs)
- trunk/test/test086.cxx (modified) (1 diff)
- trunk/test/test087.cxx (modified) (4 diffs)
- trunk/test/test088.cxx (modified) (2 diffs)
- trunk/test/test089.cxx (modified) (4 diffs)
- trunk/test/test090.cxx (modified) (4 diffs)
- trunk/test/test092.cxx (modified) (1 diff)
- trunk/test/test093.cxx (modified) (2 diffs)
- trunk/test/test094.cxx (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/ChangeLog
r1377 r1378 1 2008-08-14 Jeroen T. Vermeulen <jtv@xs4all.nl> 2 test/test072.cxx, test/test073.cxx, test/test074.cxx, test/test075.cxx, 3 test/test076.cxx, test/test077.cxx, test/test078.cxx, test/test079.cxx, 4 test/test080.cxx, test/test082.cxx, test/test083.cxx, test/test084.cxx, 5 test/test085.cxx, test/test086.cxx, test/test087.cxx, test/test088.cxx, 6 test/test090.cxx, test/test092.cxx, test/test093.cxx, test/test094.cxx: 7 - Converted to test framework 8 - All tests done now! 1 9 2008-08-13 Jeroen T. Vermeulen <jtv@xs4all.nl> 2 10 test/test001.cxx, test/test013.cxx, test/test016.cxx, test/test017.cxx, trunk/test/test072.cxx
r1175 r1378 6 6 #include <pqxx/pipeline> 7 7 8 #include "test_helpers.hxx" 9 8 10 using namespace PGSTD; 9 11 using namespace pqxx; 10 12 13 11 14 // Test program for libpqxx. Test error handling for pipeline. 12 // 13 // Usage: test072 [connect-string] 14 // 15 // Where connect-string is a set of connection options in Postgresql's 16 // PQconnectdb() format, eg. "dbname=template1" to select from a database 17 // called template1, or "host=foo.bar.net user=smith" to connect to a backend 18 // running on host foo.bar.net, logging in as user smith. 19 int main(int, char *argv[]) 15 namespace 20 16 { 21 try 17 void test_072(connection_base &C, transaction_base &W) 18 { 19 pipeline P(W); 20 21 // Ensure all queries are issued at once to make the test more interesting 22 P.retain(); 23 24 // The middle query should fail; the surrounding two should succeed 25 const pipeline::query_id id_1 = P.insert("SELECT 1"); 26 const pipeline::query_id id_f = P.insert("SELECT * FROM pg_nonexist"); 27 const pipeline::query_id id_2 = P.insert("SELECT 2"); 28 29 // See that we can process the queries without stumbling over the error 30 P.complete(); 31 32 // We should be able to get the first result, which preceeds the error 33 cout << "Retrieving initial result..." << endl; 34 const int res_1 = P.retrieve(id_1).at(0).at(0).as<int>(); 35 cout << " - result was " << res_1 << endl; 36 PQXX_CHECK_EQUAL(res_1, 1, "Got wrong result from pipeline."); 37 38 // We should *not* get a result for the query behind the error 39 cout << "Retrieving post-error result..." << endl; 22 40 { 23 asyncconnection C(argv[1]); 24 nontransaction W(C, "test72"); 25 pipeline P(W); 26 27 // Ensure all queries are issued at once to make the test more interesting 28 P.retain(); 29 30 // The middle query should fail; the surrounding two should succeed 31 const pipeline::query_id id_1 = P.insert("SELECT 1"); 32 const pipeline::query_id id_f = P.insert("SELECT * FROM pg_nonexist"); 33 const pipeline::query_id id_2 = P.insert("SELECT 2"); 34 35 // See that we can process the queries without stumbling over the error 36 P.complete(); 37 38 // We should be able to get the first result, which preceeds the error 39 cout << "Retrieving initial result..." << endl; 40 const int res_1 = P.retrieve(id_1).at(0).at(0).as<int>(); 41 cout << " - result was " << res_1 << endl; 42 if (res_1 != 1) throw logic_error("Expected 1, got " + to_string(res_1)); 43 44 // We should *not* get a result for the query behind the error 45 cout << "Restrieving post-error result..." << endl; 46 bool failed = true; 47 try 48 { 49 disable_noticer d(C); 50 P.retrieve(id_2).at(0).at(0).as<int>(); 51 failed = false; 52 } 53 catch (const exception &e) 54 { 55 cout << "(Expected) " << e.what() << endl; 56 } 57 if (!failed) throw logic_error("Pipeline wrongly resumed after SQL error"); 58 59 // Now see that we get an exception when we touch the failed result 60 cout << "Retrieving result for failed query..." << endl; 61 try 62 { 63 P.retrieve(id_f); 64 failed = false; 65 } 66 catch (const exception &e) 67 { 68 cout << "(Expected) " << e.what() << endl; 69 failed = true; 70 } 71 if (!failed) throw logic_error("Pipeline failed to register SQL error"); 72 } 73 catch (const sql_error &e) 74 { 75 cerr << "Database error: " << e.what() << endl 76 << "Query was: " << e.query() << endl; 77 return 2; 78 } 79 catch (const exception &e) 80 { 81 cerr << "Exception: " << e.what() << endl; 82 return 2; 83 } 84 catch (...) 85 { 86 cerr << "Unhandled exception" << endl; 87 return 100; 41 disable_noticer d(C); 42 PQXX_CHECK_THROWS( 43 P.retrieve(id_2).at(0).at(0).as<int>(), 44 runtime_error, 45 "Pipeline wrongly resumed after SQL error."); 88 46 } 89 47 90 return 0; 48 // Now see that we get an exception when we touch the failed result 49 cout << "Retrieving result for failed query..." << endl; 50 { 51 disable_noticer d(C); 52 PQXX_CHECK_THROWS( 53 P.retrieve(id_f), 54 sql_error, 55 "Pipeline failed to register SQL error."); 56 } 91 57 } 58 } // namespace 92 59 60 PQXX_REGISTER_TEST_CT(test_072, asyncconnection, nontransaction) trunk/test/test073.cxx
r1175 r1378 6 6 #include <pqxx/pipeline> 7 7 8 #include "test_helpers.hxx" 9 8 10 using namespace PGSTD; 9 11 using namespace pqxx; 10 12 11 // Test program for libpqxx. Test pipeline's handling of SQL syntax errors. 12 // 13 // Usage: test073 [connect-string] 14 // 15 // Where connect-string is a set of connection options in Postgresql's 16 // PQconnectdb() format, eg. "dbname=template1" to select from a database 17 // called template1, or "host=foo.bar.net user=smith" to connect to a backend 18 // running on host foo.bar.net, logging in as user smith. 19 int main(int, char *argv[]) 13 14 // Test program for libpqxx. Test pipeline's handling of SQL syntax errors on a 15 // more exotic connection type. Using nontransaction so the pipeline gets to 16 // trigger the setup of the real connection. 17 namespace 20 18 { 21 try 22 { 23 asyncconnection C(argv[1]); 24 nontransaction W(C, "test73"); 25 pipeline P(W, "pipe73"); 19 void test_073(connection_base &C, transaction_base &W) 20 { 21 pipeline P(W, "pipe73"); 26 22 27 // Ensure all queries are issued at once to make the test more interesting28 P.retain();23 // Ensure all queries are issued at once to make the test more interesting 24 P.retain(); 29 25 30 cout << "Opened " << P.classname() << " " << P.name() << ": "31 << P.description()32 << endl;26 cout << "Opened " << P.classname() << " " << P.name() << ": " 27 << P.description() 28 << endl; 33 29 34 // The middle query should fail; the surrounding two should succeed35 const pipeline::query_id id_1 = P.insert("SELECT 1");36 const pipeline::query_id id_f = P.insert("DELIBERATE SYNTAX ERROR");37 const pipeline::query_id id_2 = P.insert("SELECT 2");30 // The middle query should fail; the surrounding two should succeed 31 const pipeline::query_id id_1 = P.insert("SELECT 1"); 32 const pipeline::query_id id_f = P.insert("DELIBERATE SYNTAX ERROR"); 33 const pipeline::query_id id_2 = P.insert("SELECT 2"); 38 34 39 // See that we can process the queries without stumbling over the error40 P.complete();35 // See that we can process the queries without stumbling over the error 36 P.complete(); 41 37 42 // We should be able to get the first result, which preceeds the error43 cout << "Retrieving initial result..." << endl;44 const int res_1 = P.retrieve(id_1).at(0).at(0).as<int>();45 cout << " - result was " << res_1 << endl;46 if (res_1 != 1) throw logic_error("Expected 1, got " + to_string(res_1));38 // We should be able to get the first result, which preceeds the error 39 cout << "Retrieving initial result..." << endl; 40 const int res_1 = P.retrieve(id_1).at(0).at(0).as<int>(); 41 cout << " - result was " << res_1 << endl; 42 PQXX_CHECK_EQUAL(res_1, 1, "Got bad result from pipeline."); 47 43 48 // We should *not* get a result for the query behind the error 49 cout << "Retrieving post-error result..." << endl; 50 bool failed = true; 51 try 52 { 53 disable_noticer d(C); 54 P.retrieve(id_2).at(0).at(0).as<int>(); 55 failed = false; 56 } 57 catch (const exception &e) 58 { 59 cout << "(Expected) " << e.what() << endl; 60 } 61 if (!failed) throw logic_error("Pipeline wrongly resumed after SQL error"); 44 // We should *not* get a result for the query behind the error 45 cout << "Retrieving post-error result..." << endl; 46 disable_noticer d(C); 47 PQXX_CHECK_THROWS( 48 P.retrieve(id_2).at(0).at(0).as<int>(), 49 runtime_error, 50 "Pipeline wrongly resumed after SQL error."); 62 51 63 // Now see that we get an exception when we touch the failed result 64 cout << "Retrieving result for failed query..." << endl; 65 try 66 { 67 P.retrieve(id_f); 68 failed = false; 69 } 70 catch (const exception &e) 71 { 72 cout << "(Expected) " << e.what() << endl; 73 failed = true; 74 } 75 if (!failed) throw logic_error("Pipeline failed to register SQL error"); 76 } 77 catch (const sql_error &e) 78 { 79 cerr << "Database error: " << e.what() << endl 80 << "Query was: " << e.query() << endl; 81 return 2; 82 } 83 catch (const exception &e) 84 { 85 cerr << "Exception: " << e.what() << endl; 86 return 2; 87 } 88 catch (...) 89 { 90 cerr << "Unhandled exception" << endl; 91 return 100; 92 } 52 // Now see that we get an exception when we touch the failed result 53 cout << "Retrieving result for failed query..." << endl; 54 PQXX_CHECK_THROWS( 55 P.retrieve(id_f), 56 sql_error, 57 "Pipeline failed to register SQL error."); 58 } 59 } // namespace 93 60 94 return 0; 95 } 96 61 PQXX_REGISTER_TEST_CT(test_073, asyncconnection, nontransaction) trunk/test/test074.cxx
r1273 r1378 7 7 #include <pqxx/transaction> 8 8 9 #include "test_helpers.hxx" 10 9 11 using namespace PGSTD; 10 12 using namespace pqxx; 11 13 14 12 15 // Test program for libpqxx. Test fieldstream. 13 // 14 // Usage: test074 [connect-string] 15 // 16 // Where connect-string is a set of connection options in Postgresql's 17 // PQconnectdb() format, eg. "dbname=template1" to select from a database 18 // called template1, or "host=foo.bar.net user=smith" to connect to a backend 19 // running on host foo.bar.net, logging in as user smith. 20 int main(int, char *argv[]) 16 namespace 21 17 { 22 try 23 { 24 connection C(argv[1]); 25 work W(C, "test74"); 26 result R = W.exec("SELECT * FROM pg_tables"); 27 const string sval = R.at(0).at(1).c_str(); 28 string sval2; 29 fieldstream fs1(R.front()[1]); 30 fs1 >> sval2; 31 if (sval2 != sval) 32 throw logic_error("Got '" + sval + "' from field, " 33 "but '" + sval2 + "' from fieldstream"); 18 void test_074(connection_base &, transaction_base &W) 19 { 20 result R = W.exec("SELECT * FROM pg_tables"); 21 const string sval = R.at(0).at(1).c_str(); 22 string sval2; 23 fieldstream fs1(R.front()[1]); 24 fs1 >> sval2; 25 PQXX_CHECK_EQUAL(sval2, sval, "fieldstream returned wrong value."); 34 26 35 R = W.exec("SELECT count(*) FROM pg_tables"); 36 int ival; 37 fieldstream fs2(R.at(0).at(0)); 38 fs2 >> ival; 39 if (ival != R.front().front().as<int>()) 40 throw logic_error("Got int " + to_string(ival) + " from fieldstream, " 41 "but " + to_string(R.front().front().as<int>()) + " from field"); 27 R = W.exec("SELECT count(*) FROM pg_tables"); 28 int ival; 29 fieldstream fs2(R.at(0).at(0)); 30 fs2 >> ival; 31 PQXX_CHECK_EQUAL( 32 ival, 33 R.front().front().as<int>(), 34 "fieldstream::front() is broken."); 42 35 43 double dval; 44 (fieldstream(R.at(0).at(0))) >> dval; 45 if (fabs(dval - R[0][0].as<double>()) > 0.1) 46 throw logic_error("Got double " + to_string(dval) + " from fieldstream, " 47 "but " + to_string(R[0][0].as<double>()) + " from field"); 36 double dval; 37 (fieldstream(R.at(0).at(0))) >> dval; 38 PQXX_CHECK_BOUNDS( 39 dval, 40 R[0][0].as<double>() - 0.1, 41 R[0][0].as<double>() + 0.1, 42 "Got wrong double from fieldstream."); 48 43 49 const float roughpi = static_cast<float>(3.1415926435); 50 R = W.exec("SELECT " + to_string(roughpi)); 51 float pival; 52 (fieldstream(R.at(0).at(0))) >> pival; 53 if (fabs(pival - roughpi) > 0.001) 54 throw logic_error("Pi approximation came back as " + to_string(roughpi)); 44 const float roughpi = static_cast<float>(3.1415926435); 45 R = W.exec("SELECT " + to_string(roughpi)); 46 float pival; 47 (fieldstream(R.at(0).at(0))) >> pival; 48 PQXX_CHECK_BOUNDS( 49 pival, 50 roughpi - 0.001, 51 roughpi + 0.001, 52 "Pi approximation came back wrong from fieldstream."); 55 53 56 if (to_string(R[0][0]) != R[0][0].c_str()) 57 throw logic_error("to_string(result::field) " 58 "inconsistent with to_string(const char[])"); 54 PQXX_CHECK_EQUAL( 55 to_string(R[0][0]), 56 R[0][0].c_str(), 57 "to_string(result::field) is inconsistent with c_str()."); 59 58 60 float float_pi; 61 from_string(to_string(roughpi), float_pi); 62 if (fabs(float_pi-roughpi) > 0.00001) 63 throw logic_error("Float changes in conversion"); 59 float float_pi; 60 from_string(to_string(roughpi), float_pi); 61 PQXX_CHECK_BOUNDS( 62 float_pi, 63 roughpi - 0.00001, 64 roughpi + 0.00001, 65 "Float changed in conversion."); 64 66 65 double double_pi; 66 from_string(to_string(double(roughpi)), double_pi); 67 if (fabs(double_pi-roughpi) > 0.00001) 68 throw logic_error("Double changes in conversion"); 67 double double_pi; 68 from_string(to_string(double(roughpi)), double_pi); 69 PQXX_CHECK_BOUNDS( 70 double_pi, 71 roughpi - 0.00001, 72 roughpi + 0.00001, 73 "Double changed in conversion."); 69 74 70 75 #if defined(PQXX_HAVE_LONG_DOUBLE) 71 const long double ld = roughpi; 72 long double long_double_pi; 73 from_string(to_string(ld), long_double_pi); 74 if (fabs(long_double_pi-roughpi) > 0.00001) 75 throw logic_error("Long double changes in conversion"); 76 const long double ld = roughpi; 77 long double long_double_pi; 78 from_string(to_string(ld), long_double_pi); 79 PQXX_CHECK_BOUNDS( 80 long_double_pi, 81 roughpi - 0.00001, 82 roughpi + 0.00001, 83 "long double changed in conversion."); 76 84 #endif 77 } 78 catch (const sql_error &e) 79 { 80 cerr << "Database error: " << e.what() << endl 81 << "Query was: " << e.query() << endl; 82 return 2; 83 } 84 catch (const exception &e) 85 { 86 cerr << "Exception: " << e.what() << endl; 87 return 2; 88 } 89 catch (...) 90 { 91 cerr << "Unhandled exception" << endl; 92 return 100; 93 } 85 } 86 } // namespace 94 87 95 return 0; 96 } 97 88 PQXX_REGISTER_TEST(test_074) trunk/test/test075.cxx
r968 r1378 8 8 #include <pqxx/result> 9 9 10 #include "test_helpers.hxx" 11 10 12 using namespace PGSTD; 11 13 using namespace pqxx; … … 14 16 // Test program for libpqxx. Compare const_reverse_iterator iteration of a 15 17 // result to a regular, const_iterator iteration. 16 // 17 // Usage: test075 [connect-string] 18 // 19 // Where connect-string is a set of connection options in Postgresql's 20 // PQconnectdb() format, eg. "dbname=template1" to select from a database 21 // called template1, or "host=foo.bar.net user=smith" to connect to a 22 // backend running on host foo.bar.net, logging in as user smith. 18 namespace 19 { 20 void test_075(connection_base &, transaction_base &W) 21 { 22 const result R( W.exec("SELECT year FROM pqxxevents") ); 23 23 24 int main(int, char *argv[]) 25 { 26 try 27 { 28 connection C(argv[1]); 29 work W(C, "test75"); 30 const result R( W.exec("SELECT year FROM pqxxevents") ); 24 if (R.empty()) throw runtime_error("No events found, can't test!"); 31 25 32 if (R.empty()) throw runtime_error("No events found, can't test!"); 26 PQXX_CHECK_EQUAL(R[0], R.at(0), "Inconsistent result indexing."); 27 PQXX_CHECK(!(R[0] != R.at(0)), "result::tuple::operator!=() is broken."); 33 28 34 if (!(R[0] == R.at(0)))35 throw logic_error("result[0] == result.at(0) doesn't hold!");36 if (R[0] != R.at(0)) 37 throw logic_error("Something wrong with result::tuple::operator!=");29 PQXX_CHECK_EQUAL(R[0][0], R[0].at(0), "Inconsistent row indexing."); 30 PQXX_CHECK( 31 !(R[0][0] != R[0].at(0)), 32 "result::field::operator!=() is broken."); 38 33 39 if (!(R[0][0] == R[0].at(0)))40 throw logic_error("tuple[0] == tuple.at(0) doesn't hold!");41 if (R[0][0] != R[0].at(0))42 throw logic_error("Something wrong with result::field::operator!=");34 vector<string> contents; 35 for (result::const_iterator i=R.begin(); i!=R.end(); ++i) 36 contents.push_back(i->at(0).as<string>()); 37 cout << to_string(contents.size()) << " years read" << endl; 43 38 44 vector<string> contents;45 for (result::const_iterator i=R.begin(); i!=R.end(); ++i) 46 contents.push_back(i->at(0).as<string>()); 47 cout << to_string(contents.size()) << " years read" << endl;39 PQXX_CHECK_EQUAL( 40 contents.size(), 41 vector<string>::size_type(R.size()), 42 "Number of values does not match result size."); 48 43 49 if (contents.size() != vector<string>::size_type(R.size())) 50 throw logic_error("Got " + to_string(contents.size()) + " values " 51 "out of result with size " + to_string(R.size())); 44 for (result::size_type i=0; i<R.size(); ++i) 45 PQXX_CHECK_EQUAL( 46 contents[i], 47 R.at(i).at(0).c_str(), 48 "Inconsistent iteration."); 52 49 53 for (result::size_type i=0; i<R.size(); ++i) 54 if (contents[i] != R.at(i).at(0).c_str()) 55 throw logic_error("Inconsistent iteration: '" + contents[i] + "' " 56 "became '" + R[i][0].as<string>()); 57 cout << to_string(R.size()) << " years checked" << endl; 50 cout << to_string(R.size()) << " years checked" << endl; 58 51 59 52 #ifdef PQXX_HAVE_REVERSE_ITERATOR 60 // Thorough test for result::const_reverse_iterator61 result::const_reverse_iterator ri1(R.rbegin()), ri2(ri1), ri3(R.end());62 ri2 = R.rbegin();53 // Thorough test for result::const_reverse_iterator 54 result::const_reverse_iterator ri1(R.rbegin()), ri2(ri1), ri3(R.end()); 55 ri2 = R.rbegin(); 63 56 64 if (!(ri1 == ri2)) 65 throw logic_error("Copy-constructed reverse_iterator " 66 "not identical to assigned one"); 67 if (ri2 != ri3) 68 throw logic_error("result:end() does not generate rbegin()"); 69 if (ri2 - ri3) 70 throw logic_error("Distance between identical const_reverse_iterators " 71 "is nonzero: " + to_string(ri2 - ri3)); 72 if (ri2 != ri3 + 0) 73 throw logic_error("reverse_iterator+0 gives strange result"); 74 if (ri2 != ri3 - 0) 75 throw logic_error("reverse_iterator-0 gives strange result"); 76 if (ri3 < ri2) 77 throw logic_error("Equality with reverse_iterator operator < wrong"); 78 if (!(ri2 <= ri3)) 79 throw logic_error("Equality with reverse_iterator operator <= wrong"); 57 PQXX_CHECK(ri2 == ri1, "reverse_iterator copy constructor is broken."); 58 PQXX_CHECK(ri3 == ri2, "result::end() does not generate rbegin()."); 59 PQXX_CHECK_EQUAL( 60 ri2 - ri3, 61 0, 62 "const_reverse_iterator is at nonzero distance from its own copy."); 80 63 81 if (ri3++ != ri2) 82 throw logic_error("reverse_iterator postfix ++ returns wrong result"); 64 PQXX_CHECK(ri2 == ri3 + 0, "reverse_iterator+0 gives strange result."); 65 PQXX_CHECK(ri2 == ri3 - 0, "reverse_iterator-0 gives strange result."); 66 PQXX_CHECK(!(ri3 < ri2), "operator<() breaks on equal reverse_iterators."); 67 PQXX_CHECK(ri2 <= ri3, "operator<=() breaks on equal reverse_iterators."); 83 68 84 if (ri3 - ri2 != 1) 85 throw logic_error("Nonzero reverse_iterator distance came out at " + 86 to_string(ri3 - ri2) + ", " 87 "expected 1"); 88 if (!(ri3 > ri2)) 89 throw logic_error("Something wrong with reverse_iterator operator >"); 90 if (!(ri3 >= ri2)) 91 throw logic_error("Something wrong with reverse_iterator operator >="); 92 if (!(ri2 < ri3)) 93 throw logic_error("Something wrong with reverse_iterator operator <"); 94 if (!(ri2 <= ri3)) 95 throw logic_error("Something wrong with reverse_iterator operator <="); 96 if (ri3 != ri2 + 1) 97 throw logic_error("Adding number to reverse_iterator goes wrong"); 98 if (ri2 != ri3 - 1) 99 throw logic_error("Subtracting from reverse_iterator goes wrong"); 69 PQXX_CHECK(ri3++ == ri2, "reverse_iterator post-increment is broken."); 100 70 101 if (ri3 != ++ri2) 102 throw logic_error("reverse_iterator prefix ++ returns wrong result"); 103 if (!(ri3 >= ri2)) 104 throw logic_error("Equality with reverse_iterator operator >= failed"); 105 if (!(ri3 >= ri2)) 106 throw logic_error("Equality with reverse_iterator operator <= failed"); 107 if (ri3.base() != R.back()) 108 throw logic_error("reverse_iterator does not arrive at back()"); 109 if (ri1->at(0) != (*ri1).at(0)) 110 throw logic_error("reverse_iterator -> differs from * operator"); 71 PQXX_CHECK_EQUAL(ri3 - ri2, 1, "Wrong nonzero reverse_iterator distance."); 72 PQXX_CHECK(ri3 > ri2, "reverse_iterator operator>() is broken."); 73 PQXX_CHECK(ri3 >= ri2, "reverse_iterator operator>=() is broken."); 74 PQXX_CHECK(ri2 < ri3, "reverse_iterator operator<() is broken."); 75 PQXX_CHECK(ri2 <= ri3, "reverse_iterator operator<=() is broken."); 76 PQXX_CHECK(ri3 == ri2 + 1, "Adding int to reverse_iterator is broken."); 77 PQXX_CHECK( 78 ri2 == ri3 - 1, 79 "Subtracting int from reverse_iterator is broken."); 111 80 112 if (ri2-- != ri3) 113 throw logic_error("reverse_iterator postfix -- returns wrong result"); 114 if (ri2 != --ri3) 115 throw logic_error("reverse_iterator prefix -- returns wrong result"); 81 PQXX_CHECK(ri3 == ++ri2, "reverse_iterator pre-increment is broken."); 82 PQXX_CHECK(ri3 >= ri2, "operator>=() breaks on equal reverse_iterators."); 83 PQXX_CHECK(ri3 >= ri2, "operator<=() breaks on equal reverse_iterators."); 116 84 117 if (ri2 != R.rbegin()) 118 throw logic_error("Something wrong with reverse_iterator -- operator"); 85 PQXX_CHECK( 86 ri3.base() == R.back(), 87 "reverse_iterator does not arrive at back()."); 119 88 120 ri2 += 1; 121 ri3 -= -1; 89 PQXX_CHECK( 90 ri1->at(0) == (*ri1).at(0), 91 "reverse_iterator operator->() is inconsistent with operator*()."); 122 92 123 if (ri2 == R.rbegin()) 124 throw logic_error("Adding to reverse_iterator doesn't work"); 125 if (ri3 != ri2) 126 throw logic_error("reverse_iterator -= broken for negative numbers?"); 93 PQXX_CHECK(ri2-- == ri3, "reverse_iterator post-decrement is broken."); 94 PQXX_CHECK(ri2 == --ri3, "reverse_iterator pre-decrement is broken."); 95 PQXX_CHECK(ri2 == R.rbegin(), "reverse_iterator decrement is broken."); 127 96 128 ri2 -= 1; 129 if (ri2 != R.rbegin()) 130 throw logic_error("reverse_iterator += and -= do not cancel out"); 97 ri2 += 1; 98 ri3 -= -1; 131 99 100 PQXX_CHECK(ri2 != R.rbegin(), "Adding to reverse_iterator does not work."); 101 PQXX_CHECK( 102 ri3 == ri2, 103 "reverse_iterator operator-=() breaks on negative distances."); 132 104 133 // Now verify that reverse iterator also sees the same results... 134 vector<string>::reverse_iterator l = contents.rbegin(); 135 for (result::const_reverse_iterator i = R.rbegin(); i != R.rend(); ++i, ++l) 136 { 137 if (*l != i->at(0).c_str()) 138 throw logic_error("Inconsistent reverse iteration: " 139 "'" + *l + "' became '" + (*i)[0].as<string>() + "'"); 140 } 105 ri2 -= 1; 106 PQXX_CHECK( 107 ri2 == R.rbegin(), 108 "reverse_iterator operator+=() and operator-=() do not cancel out."); 141 109 142 if (l != contents.rend()) 143 throw logic_error("Reverse iteration of result ended too soon"); 110 // Now verify that reverse iterator also sees the same results... 111 vector<string>::reverse_iterator l = contents.rbegin(); 112 for (result::const_reverse_iterator i = R.rbegin(); i != R.rend(); ++i, ++l) 113 PQXX_CHECK_EQUAL( 114 *l, 115 i->at(0).c_str(), 116 "Inconsistent reverse iteration."); 117 118 PQXX_CHECK(l == contents.rend(), "Reverse iteration ended too soon."); 144 119 #endif // PQXX_HAVE_REVERSE_ITERATOR 145 120 146 if (R.empty()) 147 throw runtime_error("No years found in events table, can't test!"); 148 } 149 catch (const sql_error &e) 150 { 151 cerr << "SQL error: " << e.what() << endl 152 << "Query was: '" << e.query() << "'" << endl; 153 return 1; 154 } 155 catch (const exception &e) 156 { 157 // All exceptions thrown by libpqxx are derived from std::exception 158 cerr << "Exception: " << e.what() << endl; 159 return 2; 160 } 161 catch (...) 162 { 163 // This is really unexpected (see above) 164 cerr << "Unhandled exception" << endl; 165 return 100; 166 } 121 PQXX_CHECK(!R.empty(), "No events found in table, cannot test."); 122 } 123 } // namespace 167 124 168 return 0; 169 } 170 125 PQXX_REGISTER_TEST(test_075) trunk/test/test076.cxx
r1138 r1378 7 7 #include <pqxx/result> 8 8 9 #include "test_helpers.hxx" 10 9 11 using namespace PGSTD; 10 12 using namespace pqxx; … … 12 14 13 15 // Simple test program for libpqxx. Test string conversion routines. 14 // 15 // Usage: test076 [connect-string] 16 // 17 // Where connect-string is a set of connection options in Postgresql's 18 // PQconnectdb() format, eg. "dbname=template1" to select from a database 19 // called template1, or "host=foo.bar.net user=smith" to connect to a 20 // backend running on host foo.bar.net, logging in as user smith. 16 namespace 17 { 18 void test_076(connection_base &, transaction_base &T) 19 { 20 result RFalse = T.exec("SELECT 1=0"), 21 RTrue = T.exec("SELECT 1=1"); 22 bool False, True; 23 from_string(RFalse[0][0], False); 24 from_string(RTrue[0][0], True); 25 PQXX_CHECK(!False, "False bool converted to true."); 26 PQXX_CHECK(True, "True bool converted to false."); 21 27 22 int main(int, char *argv[]) 23 { 24 try 28 RFalse = T.exec("SELECT " + to_string(False)); 29 RTrue = T.exec("SELECT " + to_string(True)); 30 from_string(RFalse[0][0], False); 31 from_string(RTrue[0][0], True); 32 PQXX_CHECK(!False, "False bool converted to true."); 33 PQXX_CHECK(True, "True bool converted to false."); 34 35 const short svals[] = { -1, 1, 999, -32767, -32768, 32767, 0 }; 36 for (int i=0; svals[i]; ++i) 25 37 { 26 connection C(argv[1]); 27 nontransaction T(C, "test76"); 28 result RFalse = T.exec("SELECT 1=0"), 29 RTrue = T.exec("SELECT 1=1"); 30 bool False, True; 31 from_string(RFalse[0][0], False); 32 from_string(RTrue[0][0], True); 33 if (False) throw runtime_error("False bool converted to true"); 34 if (!True) throw runtime_error("True bool converted to false"); 35 36 RFalse = T.exec("SELECT " + to_string(False)); 37 RTrue = T.exec("SELECT " + to_string(True)); 38 from_string(RFalse[0][0], False); 39 from_string(RTrue[0][0], True); 40 if (False) throw runtime_error("False constant converted to true"); 41 if (!True) throw runtime_error("True constant converted to false"); 42 43 const short svals[] = { -1, 1, 999, -32767, -32768, 32767, 0 }; 44 for (int i=0; svals[i]; ++i) 45 { 46 short s; 47 from_string(to_string(svals[i]), s); 48 if (s != svals[i]) 49 throw runtime_error("Short/string conversion not bijective"); 50 from_string(T.exec("SELECT " + to_string(svals[i]))[0][0].c_str(), s); 51 if (s != svals[i]) 52 throw runtime_error("Feeding " + to_string(svals[i]) + " " 53 "through the backend yielded " + to_string(s)); 54 } 55 56 const unsigned short uvals[] = { 1, 999, 32767, 32768, 65535, 0 }; 57 for (int i=0; uvals[i]; ++i) 58 { 59 unsigned short u; 60 from_string(to_string(uvals[i]), u); 61 if (u != uvals[i]) 62 throw runtime_error("Unsigned short/string conversion not bijective"); 63 from_string(T.exec("SELECT " + to_string(uvals[i]))[0][0].c_str(), u); 64 if (u != uvals[i]) 65 throw runtime_error("Feeding unsigned " + to_string(uvals[i]) + " " 66 "through the backend yielded " + to_string(u)); 67 } 68 } 69 catch (const sql_error &e) 70 { 71 cerr << "SQL error: " << e.what() << endl 72 << "Query was: '" << e.query() << "'" << endl; 73 return 1; 74 } 75 catch (const exception &e) 76 { 77 // All exceptions thrown by libpqxx are derived from std::exception 78 cerr << "Exception: " << e.what() << endl; 79 return 2; 80 } 81 catch (...) 82 { 83 // This is really unexpected (see above) 84 cerr << "Unhandled exception" << endl; 85 return 100; 38 short s; 39 from_string(to_string(svals[i]), s); 40 PQXX_CHECK_EQUAL(s, svals[i], "short/string conversion not bijective."); 41 from_string(T.exec("SELECT " + to_string(svals[i]))[0][0].c_str(), s); 42 PQXX_CHECK_EQUAL(s, svals[i], "Roundtrip through backend changed short."); 86 43 } 87 44 88 return 0; 45 const unsigned short uvals[] = { 1, 999, 32767, 32768, 65535, 0 }; 46 for (int i=0; uvals[i]; ++i) 47 { 48 unsigned short u; 49 from_string(to_string(uvals[i]), u); 50 PQXX_CHECK_EQUAL( 51 u, 52 uvals[i], 53 "unsigned short/string conversion not bijective."); 54 55 from_string(T.exec("SELECT " + to_string(uvals[i]))[0][0].c_str(), u); 56 PQXX_CHECK_EQUAL( 57 u, 58 uvals[i], 59 "Roundtrip through backend changed unsigned short."); 60 } 89 61 } 62 } // namespace 90 63 64 PQXX_REGISTER_TEST_T(test_076, nontransaction) trunk/test/test077.cxx
r1138 r1378 7 7 #include <pqxx/result> 8 8 9 #include "test_helpers.hxx" 10 9 11 using namespace PGSTD; 10 12 using namespace pqxx; … … 12 14 13 15 // Test program for libpqxx. Test result::swap() 14 // 15 // Usage: test077 [connect-string] 16 // 17 // Where connect-string is a set of connection options in Postgresql's 18 // PQconnectdb() format, eg. "dbname=template1" to select from a database 19 // called template1, or "host=foo.bar.net user=smith" to connect to a 20 // backend running on host foo.bar.net, logging in as user smith. 16 namespace 17 { 18 void test_077(connection_base &, transaction_base &T) 19 { 20 result RFalse = T.exec("SELECT 1=0"), 21 RTrue = T.exec("SELECT 1=1"); 22 bool f, t; 23 from_string(RFalse[0][0], f); 24 from_string(RTrue[0][0], t); 25 PQXX_CHECK(!f && t, "Booleans converted incorrectly; can't trust this test."); 21 26 22 int main(int, char *argv[]) 23 { 24 try 25 { 26 connection C(argv[1]); 27 nontransaction T(C, "test77"); 28 result RFalse = T.exec("SELECT 1=0"), 29 RTrue = T.exec("SELECT 1=1"); 30 bool f, t; 31 from_string(RFalse[0][0], f); 32 from_string(RTrue[0][0], t); 33 if (f || !t) 34 throw runtime_error("Booleans converted incorrectly"); 27 RFalse.swap(RTrue); 28 from_string(RFalse[0][0], f); 29 from_string(RTrue[0][0], t); 30 PQXX_CHECK(f && !t, "result::swap() is broken."); 31 } 32 } // namespace 35 33 36 RFalse.swap(RTrue); 37 from_string(RFalse[0][0], f); 38 from_string(RTrue[0][0], t); 39 if (!f || t) throw runtime_error("result::swap() failed"); 40 } 41 catch (const sql_error &e) 42 { 43 cerr << "SQL error: " << e.what() << endl 44 << "Query was: '" << e.query() << "'" << endl; 45 return 1; 46 } 47 catch (const exception &e) 48 { 49 // All exceptions thrown by libpqxx are derived from std::exception 50 cerr << "Exception: " << e.what() << endl; 51 return 2; 52 } 53 catch (...) 54 { 55 // This is really unexpected (see above) 56 cerr << "Unhandled exception" << endl; 57 return 100; 58 } 59 60 return 0; 61 } 62 34 PQXX_REGISTER_TEST_T(test_077, nontransaction) trunk/test/test078.cxx
r1258 r1378 9 9 #include <pqxx/result> 10 10 11 #include "test_helpers.hxx" 11 12 12 13 using namespace PGSTD; … … 16 17 // Example program for libpqxx. Send notification to self, using a notification 17 18 // name with unusal characters, and without polling. 18 //19 // Usage: test07820 21 22 19 namespace 23 20 { 24 25 21 // Sample implementation of notification listener 26 22 class TestListener : public notify_listener … … 37 33 { 38 34 m_Done = true; 39 if (be_pid != Conn().backendpid()) 40 throw logic_error("Expected notification from backend process " + 41 to_string(Conn().backendpid()) + 42 ", but got one from " + 43 to_string(be_pid)); 35 PQXX_CHECK_EQUAL( 36 be_pid, 37 Conn().backendpid(), 38 "Got notification from wrong backend process."); 44 39 45 40 cout << "Received notification: " << name() << " pid=" << be_pid << endl; … … 77 72 }; 78 73 74 75 void test_078(connection_base &C, transaction_base &orgT) 76 { 77 orgT.abort(); 78 79 const string NotifName = "my listener"; 80 cout << "Adding listener..." << endl; 81 TestListener L(C, NotifName); 82 83 cout << "Sending notification..." << endl; 84 C.perform(Notify(L.name())); 85 86 int notifs = 0; 87 for (int i=0; (i < 20) && !L.Done(); ++i) 88 { 89 PQXX_CHECK_EQUAL(notifs, 0, "Got unexpected notifications."); 90 cout << "."; 91 notifs = C.await_notification(); 92 } 93 cout << endl; 94 95 PQXX_CHECK(L.Done(), "No notification received."); 96 PQXX_CHECK_EQUAL(notifs, 1, "Got unexpected number of notifications."); 97 } 79 98 } // namespace 80 99 81 int main() 82 { 83 try 84 { 85 const string NotifName = "my listener"; 86 connection C; 87 cout << "Adding listener..." << endl; 88 TestListener L(C, NotifName); 89 90 cout << "Sending notification..." << endl; 91 C.perform(Notify(L.name())); 92 93 int notifs = 0; 94 for (int i=0; (i < 20) && !L.Done(); ++i) 95 { 96 if (notifs) 97 throw logic_error("Got " + to_string(notifs) + " " 98 "unexpected notification(s)!"); 99 cout << "."; 100 notifs = C.await_notification(); 101 } 102 cout << endl; 103 104 if (!L.Done()) 105 { 106 cout << "No notification received!" << endl; 107 return 1; 108 } 109 if (notifs != 1) 110 throw logic_error("Expected 1 notification, got " + to_string(notifs)); 111 } 112 catch (const sql_error &e) 113 { 114 cerr << "SQL error: " << e.what() << endl 115 << "Query was: '" << e.query() << "'" << endl; 116 return 1; 117 } 118 catch (const exception &e) 119 { 120 // All exceptions thrown by libpqxx are derived from std::exception 121 cerr << "Exception: " << e.what() << endl; 122 return 2; 123 } 124 catch (...) 125 { 126 // This is really unexpected (see above) 127 cerr << "Unhandled exception" << endl; 128 return 100; 129 } 130 131 return 0; 132 } 133 100 PQXX_REGISTER_TEST_T(test_078, nontransaction) trunk/test/test079.cxx
r1258 r1378 9 9 #include <pqxx/result> 10 10 11 #include "test_helpers.hxx" 11 12 12 13 using namespace PGSTD; … … 15 16 16 17 // Example program for libpqxx. Test waiting for notification with timeout. 17 //18 // Usage: test07919 20 18 namespace 21 19 { 22 23 20 // Sample implementation of notification listener 24 21 class TestListener : public notify_listener … … 75 72 }; 76 73 74 75 void test_079(connection_base &C, transaction_base &orgT) 76 { 77 orgT.abort(); 78 79 const string NotifName = "mylistener"; 80 cout << "Adding listener..." << endl; 81 TestListener L(C, NotifName); 82 83 // First see if the timeout really works: we're not expecting any notifs 84 int notifs = C.await_notification(0, 1); 85 PQXX_CHECK_EQUAL(notifs, 0, "Got unexpected notification."); 86 87 cout << "Sending notification..." << endl; 88 C.perform(Notify(L.name())); 89 90 for (int i=0; (i < 20) && !L.Done(); ++i) 91 { 92 PQXX_CHECK_EQUAL(notifs, 0, "Got notifications, but no handler called."); 93 &
