db.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include "db.h"
  2. #include <SQLiteCpp/VariadicBind.h>
  3. #include <iomanip>
  4. #include <iostream>
  5. #include <sstream>
  6. // configuration settings access
  7. #include "yaml-cpp/yaml.h"
  8. extern YAML::Node config;
  9. /*
  10. The database access is slow.
  11. So, make sure you set it up so that you do your writes right
  12. before you collect user input. That way, the user won't see
  13. the lags.
  14. */
  15. DBData::DBData(void)
  16. : db("space-data.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE) {
  17. init();
  18. stmt_getSet = std::make_unique<SQLite::Statement>(
  19. db, "SELECT value FROM settings WHERE username=? AND setting=?");
  20. stmt_setSet = std::make_unique<SQLite::Statement>(
  21. db, "REPLACE INTO settings(username, setting, value) VALUES(?,?,?);");
  22. }
  23. // DBData::DBData(void) : sql(std::string(DB_CONNECT_STRING)) {}
  24. DBData::~DBData() {}
  25. void DBData::init(void) {
  26. db.exec("CREATE TABLE IF NOT EXISTS \
  27. settings(username TEXT, setting TEXT, value TEXT, \
  28. PRIMARY KEY(username, setting));");
  29. db.exec("CREATE TABLE IF NOT EXISTS \
  30. scores ( \"username\" TEXT, \"when\" INTEGER, \
  31. \"date\" INTEGER, \"hand\" INTEGER, \"score\" INTEGER, \
  32. PRIMARY KEY(\"username\", \"date\", \"hand\"));");
  33. }
  34. void DBData::setUser(std::string currentUser) { user = currentUser; }
  35. std::string DBData::getSetting(const std::string &setting,
  36. std::string ifMissing) {
  37. stmt_getSet->reset();
  38. stmt_getSet->bind(1, user);
  39. stmt_getSet->bind(2, setting);
  40. if (stmt_getSet->executeStep()) {
  41. std::string value = stmt_getSet->getColumn(0);
  42. return value;
  43. };
  44. return ifMissing;
  45. }
  46. void DBData::setSetting(const std::string &setting, const std::string &value) {
  47. stmt_setSet->reset();
  48. stmt_setSet->bind(1, user);
  49. stmt_setSet->bind(2, setting);
  50. stmt_setSet->bind(3, value);
  51. stmt_setSet->exec();
  52. }
  53. void DBData::save_score(time_t when, time_t date, int hand, int score) {
  54. SQLite::Statement stmt(db,
  55. "INSERT INTO scores( \"username\", \"when\", "
  56. "\"date\", \"hand\", \"score\") VALUES(?,?,?,?,?);");
  57. stmt.bind(1, user);
  58. stmt.bind(2, when);
  59. stmt.bind(3, date);
  60. stmt.bind(4, hand);
  61. stmt.bind(5, score);
  62. stmt.exec();
  63. }
  64. int DBData::has_played_day(time_t day) {
  65. // get date from this
  66. // std::stringstream ss;
  67. // ss << std::put_time(std::localtime(&day), "%Y/%0m/%0d");
  68. SQLite::Statement stmt(
  69. db, "SELECT COUNT(*) FROM scores WHERE \"username\"=? AND \"DATE\"=?;");
  70. stmt.bind(1, user);
  71. stmt.bind(2, day);
  72. int count = -1;
  73. if (stmt.executeStep()) {
  74. count = stmt.getColumn(0);
  75. };
  76. return count;
  77. }
  78. std::string make_date(time_t tt) {
  79. std::stringstream ss;
  80. if (config["date_score"]) {
  81. std::string custom_format = config["date_score"].as<std::string>();
  82. ss << std::put_time(std::localtime(&tt), custom_format.c_str());
  83. } else {
  84. ss << std::put_time(std::localtime(&tt), "%Y/%0m/%0d");
  85. }
  86. std::string date = ss.str();
  87. return date;
  88. }
  89. void standard_date(time_t &tt, int hour) {
  90. std::tm *local_tm = localtime(&tt);
  91. // adjust date to 2:00:00 AM
  92. tt -= (local_tm->tm_min * 60) + local_tm->tm_sec;
  93. while (local_tm->tm_hour < hour) {
  94. ++local_tm->tm_hour;
  95. tt += 60 * 60;
  96. }
  97. if (local_tm->tm_hour > hour) {
  98. tt -= (60 * 60) * (local_tm->tm_hour - hour);
  99. }
  100. }