techempower.hh 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include <unistd.h>
  2. #include <iostream>
  3. #include <silicon/api.hh>
  4. #include <silicon/middleware_factories.hh>
  5. #include <silicon/middlewares/mysql_connection.hh>
  6. #include <silicon/middlewares/mysql_orm.hh>
  7. #include "symbols.hh"
  8. using namespace s;
  9. using namespace sl;
  10. typedef decltype(D(_id(_auto_increment, _primary_key) = int(),
  11. _randomNumber = int())) random_number;
  12. typedef decltype(D(_id(_auto_increment, _primary_key) = int(),
  13. _message = std::string())) fortune;
  14. typedef mysql_orm_factory<random_number> rn_orm_factory;
  15. typedef mysql_orm<random_number> rn_orm;
  16. typedef mysql_orm_factory<fortune> fortune_orm_factory;
  17. typedef mysql_orm<fortune> fortune_orm;
  18. std::string escape_html_entities(std::string& data)
  19. {
  20. std::string buffer;
  21. buffer.reserve(data.size());
  22. for(size_t pos = 0; pos != data.size(); ++pos) {
  23. switch(data[pos]) {
  24. case '&': buffer.append("&amp;"); break;
  25. case '\"': buffer.append("&quot;"); break;
  26. case '\'': buffer.append("&apos;"); break;
  27. case '<': buffer.append("&lt;"); break;
  28. case '>': buffer.append("&gt;"); break;
  29. default: buffer.append(&data[pos], 1); break;
  30. }
  31. }
  32. return std::move(buffer);
  33. }
  34. auto techempower_api = http_api(
  35. GET / _plaintext = [] () { return response(_content_type = string_ref("text/plain"),
  36. _body = string_ref("Hello, World!")); },
  37. GET / _json = [] () { return response(_content_type = string_ref("application/json"),
  38. _body = D(_message = "Hello, World!")); },
  39. GET / _db = [] (rn_orm& orm) {
  40. random_number r;
  41. orm.find_by_id(1245, r);
  42. return response(_content_type = "application/json",
  43. _body = r);
  44. },
  45. GET / _queries * get_parameters(_queries = optional(std::string("1"))) = [] (auto param, rn_orm& orm) {
  46. int N = atoi(param.queries.c_str());
  47. N = std::max(1, std::min(N, 500));
  48. std::vector<random_number> qs(N);
  49. for (int i = 0; i < N; i++)
  50. orm.find_by_id(1 + rand() % 9999, qs[i]);
  51. return response(_content_type = "application/json",
  52. _body = std::move(qs));
  53. },
  54. GET / _updates * get_parameters(_queries = optional(std::string("1"))) = [] (auto param, rn_orm& orm) {
  55. int N = atoi(param.queries.c_str());
  56. N = std::max(1, std::min(N, 500));
  57. std::vector<random_number> qs(N);
  58. for (int i = 0; i < N; i++)
  59. {
  60. orm.find_by_id(1 + rand() % 9999, qs[i]);
  61. qs[i].randomNumber = 1 + rand() % 9999;
  62. orm.update(qs[i]);
  63. }
  64. return response(_content_type = "application/json",
  65. _body = std::move(qs));
  66. },
  67. GET / _fortunes = [] (fortune_orm& orm) {
  68. std::vector<fortune> table;
  69. orm.forall([&] (fortune& f) { table.push_back(f); });
  70. table.push_back(fortune(0, "Additional fortune added at request time."));
  71. std::sort(table.begin(), table.end(),
  72. [] (const fortune& a, const fortune& b) { return a.message < b.message; });
  73. std::stringstream ss;
  74. ss << "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>";
  75. for(auto& f : table)
  76. ss << "<tr><td>" << f.id << "</td><td>" << escape_html_entities(f.message) << "</td></tr>";
  77. ss << "</table></body></html>";
  78. return response(_content_type = "text/html; charset=utf-8",
  79. _body = ss.str());
  80. }
  81. );