lithium.cc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #include "lithium_http_backend.hh"
  2. #include "lithium_mysql.hh"
  3. #include "symbols.hh"
  4. using namespace li;
  5. std::string escape_html_entities(const std::string& data)
  6. {
  7. std::string buffer;
  8. buffer.reserve(data.size());
  9. for(size_t pos = 0; pos != data.size(); ++pos) {
  10. switch(data[pos]) {
  11. case '&': buffer.append("&"); break;
  12. case '\"': buffer.append("""); break;
  13. case '\'': buffer.append("'"); break;
  14. case '<': buffer.append("&lt;"); break;
  15. case '>': buffer.append("&gt;"); break;
  16. default: buffer.append(&data[pos], 1); break;
  17. }
  18. }
  19. return std::move(buffer);
  20. }
  21. int main(int argc, char* argv[]) {
  22. if (argc != 4)
  23. {
  24. std::cerr << "Usage: " << argv[0] << " mysql_host port nprocs" << std::endl;
  25. return 1;
  26. }
  27. int port = atoi(argv[2]);
  28. int nprocs = atoi(argv[3]);
  29. auto mysql_db =
  30. mysql_database(s::host = argv[1], s::database = "hello_world", s::user = "benchmarkdbuser",
  31. s::password = "benchmarkdbpass", s::port = 3306, s::charset = "utf8");
  32. int mysql_max_connection = mysql_db.connect()("SELECT @@GLOBAL.max_connections;").read<int>() * 0.75;
  33. li::max_mysql_connections_per_thread = (mysql_max_connection / nprocs);
  34. auto fortunes = sql_orm_schema(mysql_db, "Fortune").fields(
  35. s::id(s::auto_increment, s::primary_key) = int(),
  36. s::message = std::string());
  37. auto random_numbers = sql_orm_schema(mysql_db, "World").fields(
  38. s::id(s::auto_increment, s::primary_key) = int(),
  39. s::randomNumber = int());
  40. http_api my_api;
  41. my_api.get("/plaintext") = [&](http_request& request, http_response& response) {
  42. response.set_header("Content-Type", "text/plain");
  43. response.write("Hello, World!");
  44. };
  45. my_api.get("/json") = [&](http_request& request, http_response& response) {
  46. response.write_json(s::message = "Hello, World!");
  47. };
  48. my_api.get("/db") = [&](http_request& request, http_response& response) {
  49. response.write_json(random_numbers.connect(request.yield).find_one(s::id = 1234).value());
  50. };
  51. my_api.get("/queries") = [&](http_request& request, http_response& response) {
  52. std::string N_str = request.get_parameters(s::N = std::optional<std::string>()).N.value_or("1");
  53. int N = atoi(N_str.c_str());
  54. N = std::max(1, std::min(N, 500));
  55. auto c = random_numbers.connect(request.yield);
  56. std::vector<decltype(random_numbers.all_fields())> numbers(N);
  57. for (int i = 0; i < N; i++)
  58. numbers[i] = c.find_one(s::id = 1 + rand() % 9999).value();
  59. response.write_json(numbers);
  60. };
  61. my_api.get("/updates") = [&](http_request& request, http_response& response) {
  62. std::string N_str = request.get_parameters(s::N = std::optional<std::string>()).N.value_or("1");
  63. int N = atoi(N_str.c_str());
  64. N = std::max(1, std::min(N, 500));
  65. auto c = random_numbers.connect(request.yield);
  66. std::vector<decltype(random_numbers.all_fields())> numbers(N);
  67. for (int i = 0; i < N; i++)
  68. {
  69. numbers[i] = c.find_one(s::id = 1 + rand() % 9999).value();
  70. numbers[i].randomNumber = 1 + rand() % 9999;
  71. c.update(numbers[i]);
  72. }
  73. response.write_json(numbers);
  74. };
  75. my_api.get("/fortunes") = [&](http_request& request, http_response& response) {
  76. typedef decltype(fortunes.all_fields()) fortune;
  77. std::vector<fortune> table;
  78. auto c = fortunes.connect(request.yield);
  79. c.forall([&] (auto f) { table.push_back(f); });
  80. table.push_back(fortune(0, std::string("Additional fortune added at request time.")));
  81. std::sort(table.begin(), table.end(),
  82. [] (const fortune& a, const fortune& b) { return a.message < b.message; });
  83. std::stringstream ss;
  84. ss << "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>";
  85. for(auto& f : table)
  86. ss << "<tr><td>" << f.id << "</td><td>" << escape_html_entities(f.message) << "</td></tr>";
  87. ss << "</table></body></html>";
  88. response.set_header("Content-Type", "text/html; charset=utf-8");
  89. response.write(ss.str());
  90. };
  91. http_serve(my_api, port, s::nthreads = nprocs);
  92. return 0;
  93. }