fortunetest.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #include "fortunetest.h"
  2. #include <Cutelyst/Plugins/Utils/Sql>
  3. #include <Cutelyst/View>
  4. #include <apool.h>
  5. #include <aresult.h>
  6. #include <apreparedquery.h>
  7. #include <QSqlQuery>
  8. using namespace ASql;
  9. FortuneTest::FortuneTest(QObject *parent) : Controller(parent)
  10. {
  11. }
  12. void FortuneTest::fortunes_raw_p(Context *c)
  13. {
  14. ASync async(c);
  15. static thread_local auto db = APool::database();
  16. db.exec(APreparedQueryLiteral(u8"SELECT id, message FROM fortune"), c, [c, async, this] (AResult &result) {
  17. if (Q_UNLIKELY(result.error() && !result.size())) {
  18. c->res()->setStatus(Response::InternalServerError);
  19. return;
  20. }
  21. FortuneList fortunes;
  22. fortunes.reserve(result.size());
  23. auto it = result.begin();
  24. while (it != result.end()) {
  25. fortunes.emplace_back(Fortune{it[0].toInt(), it[1].toString()});
  26. ++it;
  27. }
  28. fortunes.emplace_back(Fortune{0, QStringLiteral("Additional fortune added at request time.")});
  29. std::sort(fortunes.begin(), fortunes.end(), [] (const Fortune &a1, const Fortune &a2) {
  30. return a1.message < a2.message;
  31. });
  32. renderRaw(c, fortunes);
  33. });
  34. }
  35. void FortuneTest::fortunes_raw_postgres(Context *c)
  36. {
  37. QSqlQuery query = CPreparedSqlQueryThreadForDB(
  38. QLatin1String("SELECT id, message FROM fortune"),
  39. QStringLiteral("postgres"));
  40. auto fortunes = processQuery(c, query);
  41. renderRaw(c, fortunes);
  42. }
  43. void FortuneTest::fortunes_raw_mysql(Context *c)
  44. {
  45. QSqlQuery query = CPreparedSqlQueryThreadForDB(
  46. QLatin1String("SELECT id, message FROM fortune"),
  47. QStringLiteral("mysql"));
  48. auto fortunes = processQuery(c, query);
  49. renderRaw(c, fortunes);
  50. }
  51. void FortuneTest::fortunes_c_p(Context *c)
  52. {
  53. ASync async(c);
  54. static thread_local auto db = APool::database();
  55. db.exec(APreparedQueryLiteral(u8"SELECT id, message FROM fortune"), c, [c, async] (AResult &result) {
  56. if (Q_UNLIKELY(result.error() && !result.size())) {
  57. c->res()->setStatus(Response::InternalServerError);
  58. return;
  59. }
  60. QVariantList fortunes;
  61. fortunes.reserve(result.size());
  62. auto it = result.begin();
  63. while (it != result.end()) {
  64. fortunes.append(QVariant::fromValue(QVariantList{
  65. {it[0].toInt(), it[1].toString()},
  66. }));
  67. ++it;
  68. }
  69. fortunes.append(QVariant::fromValue(QVariantList{
  70. {0, QStringLiteral("Additional fortune added at request time.")},
  71. }));
  72. std::sort(fortunes.begin(), fortunes.end(), [] (const QVariant &a1, const QVariant &a2) {
  73. return a1.toList()[1].toString() < a2.toList()[1].toString();
  74. });
  75. c->setStash(QStringLiteral("template"), QStringLiteral("fortunes.html"));
  76. c->setStash(QStringLiteral("fortunes"), fortunes);
  77. static thread_local View *view = c->view();
  78. view->execute(c);
  79. c->response()->setContentType(QStringLiteral("text/html; charset=UTF-8"));
  80. });
  81. }
  82. void FortuneTest::fortunes_cutelee_postgres(Context *c)
  83. {
  84. QSqlQuery query = CPreparedSqlQueryThreadForDB(
  85. QLatin1String("SELECT id, message FROM fortune"),
  86. QStringLiteral("postgres"));
  87. if (query.exec()) {
  88. QVariantList fortunes = Sql::queryToList(query);
  89. fortunes.append(QVariant::fromValue(QVariantList{
  90. {0, QStringLiteral("Additional fortune added at request time.")},
  91. }));
  92. std::sort(fortunes.begin(), fortunes.end(), [] (const QVariant &a1, const QVariant &a2) {
  93. return a1.toList()[1].toString() < a2.toList()[1].toString();
  94. });
  95. c->setStash(QStringLiteral("template"), QStringLiteral("fortunes.html"));
  96. c->setStash(QStringLiteral("fortunes"), fortunes);
  97. static thread_local View *view = c->view();
  98. view->execute(c);
  99. c->response()->setContentType(QStringLiteral("text/html; charset=UTF-8"));
  100. }
  101. }
  102. void FortuneTest::fortunes_cutelee_mysql(Context *c)
  103. {
  104. QSqlQuery query = CPreparedSqlQueryThreadForDB(
  105. QLatin1String("SELECT id, message FROM fortune"),
  106. QStringLiteral("mysql"));
  107. if (query.exec()) {
  108. QVariantList fortunes = Sql::queryToList(query);
  109. fortunes.append(QVariant::fromValue(QVariantList{
  110. {0, QStringLiteral("Additional fortune added at request time.")},
  111. }));
  112. std::sort(fortunes.begin(), fortunes.end(), [] (const QVariant &a1, const QVariant &a2) {
  113. return a1.toList()[1].toString() < a2.toList()[1].toString();
  114. });
  115. c->setStash(QStringLiteral("template"), QStringLiteral("fortunes.html"));
  116. c->setStash(QStringLiteral("fortunes"), fortunes);
  117. static thread_local View *view = c->view();
  118. view->execute(c);
  119. c->response()->setContentType(QStringLiteral("text/html; charset=UTF-8"));
  120. }
  121. }
  122. FortuneList FortuneTest::processQuery(Context *c, QSqlQuery &query)
  123. {
  124. FortuneList fortunes;
  125. if (Q_UNLIKELY(!query.exec())) {
  126. c->res()->setStatus(Response::InternalServerError);
  127. return fortunes;
  128. }
  129. fortunes.reserve(query.size());
  130. while (query.next()) {
  131. fortunes.push_back({query.value(0).toInt(), query.value(1).toString()});
  132. }
  133. fortunes.push_back({0, QStringLiteral("Additional fortune added at request time.")});
  134. std::sort(fortunes.begin(), fortunes.end(), [] (const Fortune &a1, const Fortune &a2) {
  135. return a1.message < a2.message;
  136. });
  137. return fortunes;
  138. }
  139. void FortuneTest::renderRaw(Context *c, const FortuneList &fortunes) const
  140. {
  141. QByteArray out;
  142. out.append("<!DOCTYPE html>"
  143. "<html>"
  144. "<head><title>Fortunes</title></head>"
  145. "<body>"
  146. "<table>"
  147. "<tr><th>id</th><th>message</th></tr>");
  148. out.reserve(4096);
  149. for (const Fortune &fortune : fortunes) {
  150. out.append("<tr><td>")
  151. .append(QByteArray::number(fortune.id))
  152. .append("</td><td>")
  153. .append(fortune.message.toHtmlEscaped().toUtf8())
  154. .append("</td></tr>");
  155. }
  156. out.append("</table></body></html>");
  157. auto response = c->response();
  158. response->setBody(out);
  159. response->setContentType(QStringLiteral("text/html; charset=UTF-8"));
  160. }