C++DB is the database layer that was designed to work with C++CMS. This customized version is used within Ye Ol' Pi Shack.
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.
 
 
 
 
 

179 lines
4.4 KiB

  1. //////////////////////////////////////////////////////////////////////
  2. // This tests MySQL backend for opt_reconnect operation
  3. // Written by Jonathan A. Foster <jon@jfpossibilities.com>
  4. // Started March 31st, 2021
  5. // Copyright JF Possibilities, Inc. All rights reserved.
  6. //
  7. // This will make several queries, KILL its own connection and then
  8. // remake the same queries in the hopes of reusing cached, prepared
  9. // statements. Flip opt_reconnect to try it with and without.
  10. //
  11. // Test passed: 2021-03-31 v0.3.1-j3
  12. //////////////////////////////////////////////////////////////////////
  13. #include <iostream>
  14. #include <string>
  15. #include <stdexcept>
  16. #include <cppdb/frontend.h>
  17. using namespace std;
  18. using namespace cppdb;
  19. //////////////////////////////////////////////////////////////////////
  20. // GLOBALS
  21. //////////////////////////////////////////////////////////////////////
  22. session db;
  23. string pid;
  24. //////////////////////////////////////////////////////////////////////
  25. // Simple R/O queries
  26. //
  27. // We're hoping these statements get cached...
  28. //////////////////////////////////////////////////////////////////////
  29. // Get our connection ID, stash it in "pid" and return a reference
  30. string &qPid() {
  31. result q = db << "select connection_id()";
  32. while(q.next()) q >> pid;
  33. cout << pid << endl;
  34. return pid;
  35. }
  36. // dump process list
  37. void qProcesses() {
  38. string id, user, host, dbn, command/*, time, state*/;
  39. result q = db << "show processlist";
  40. while(q.next()) {
  41. q >> id >> user >> host >> dbn >> command;
  42. cout << id << '\t' << user << '\t' << host << '\t' << dbn << '\t'
  43. << command << endl;
  44. }
  45. }
  46. //////////////////////////////////////////////////////////////////////
  47. // A parameratized write query
  48. //////////////////////////////////////////////////////////////////////
  49. struct cUser {
  50. int id;
  51. string name;
  52. string phone;
  53. bool keep_private;
  54. };
  55. ostream &operator<<(ostream &o, const cUser &u) {
  56. o << u.id << ": " << u.name << '\t' << u.phone;
  57. if(u.keep_private) o << " **PRIVATE**";
  58. return o;
  59. }
  60. struct cUserTable {
  61. cUserTable &create() {
  62. db <<
  63. "CREATE TABLE user ("
  64. "id int not null primary key auto_increment,"
  65. "name char(64) not null,"
  66. "phone char(24) not null,"
  67. "keep_private tinyint(1) unsigned not null default 0"
  68. ")" << exec;
  69. return *this;
  70. }
  71. cUserTable &drop() {
  72. db <<
  73. "DROP TABLE IF EXISTS user" << exec;
  74. return *this;
  75. }
  76. cUserTable &operator<<(cUser &u) {
  77. statement q =
  78. db << "INSERT INTO user (name, phone, keep_private) VALUES (?,?,?)"
  79. << u.name << u.phone << u.keep_private
  80. << exec;
  81. u.id = q.last_insert_id();
  82. return *this;
  83. }
  84. cUserTable &operator>>(cUser &u) {
  85. result q = db << "SELECT id, name, phone, keep_private FROM user WHERE id=?" << u.id;
  86. if(q.next())
  87. q >> u.id >> u.name >> u.phone >> u.keep_private;
  88. else
  89. throw runtime_error("User "+to_string(u.id)+" not found");
  90. return *this;
  91. }
  92. };
  93. //////////////////////////////////////////////////////////////////////
  94. // MAIN() - put it all together
  95. //////////////////////////////////////////////////////////////////////
  96. cUser jon {0, "jon", "555-555-5550", false},
  97. carol {0, "carol", "555-555-5551", true},
  98. goliath{0, "goliath", "555-555-5552", false},
  99. kevin {0, "kevin", "555-555-5554", false},
  100. kelly {0, "kelly", "555-555-5555", true},
  101. ivy {0, "ivy", "555-555-5556", false};
  102. int main(int argct, char **args) {
  103. result q;
  104. cUserTable tbl;
  105. /// SETUP ///
  106. try {
  107. db.open(
  108. "mysql:"
  109. "user=testing;"
  110. "password=testing;"
  111. "database=test_cppdb;"
  112. "opt_reconnect=1" // isn't needed with my auto-auto-reconnect patch
  113. );
  114. qPid();
  115. qProcesses();
  116. tbl.drop();
  117. tbl.create();
  118. tbl << jon << carol << goliath;
  119. tbl >> jon >> carol >> goliath;
  120. cout << jon << '\n' << carol << '\n' << goliath << endl;
  121. /// BREAK ///
  122. try {
  123. db << "kill ?" << pid << exec;
  124. } catch(const cppdb_error &e) {
  125. cout << " Expected error: " << e.what() << "\n";
  126. }
  127. /// TEST ///
  128. tbl << kevin << kelly << ivy;
  129. tbl >> kevin >> kelly >> ivy;
  130. cout << kevin << '\n' << kelly << '\n' << ivy << endl;
  131. qProcesses();
  132. qPid();
  133. /// FAIL ///
  134. } catch(const std::exception &e) {
  135. cerr << "EXCEPTION: " << e.what() << endl;
  136. return 2;
  137. }
  138. /// PASS ///
  139. cout << "\n\n*** PASS ***\n";
  140. return 0;
  141. }