SQLiteConnection.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. * SQLiteConnection.h, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #pragma once
  11. using sqlite3 = struct sqlite3;
  12. using sqlite3_stmt = struct sqlite3_stmt;
  13. class SQLiteInstance;
  14. class SQLiteStatement;
  15. using SQLiteInstancePtr = std::unique_ptr<SQLiteInstance>;
  16. using SQLiteStatementPtr = std::unique_ptr<SQLiteStatement>;
  17. class SQLiteStatement : boost::noncopyable
  18. {
  19. public:
  20. friend class SQLiteInstance;
  21. bool execute();
  22. void reset();
  23. void clear();
  24. ~SQLiteStatement();
  25. template<typename... Args>
  26. void executeOnce(const Args &... args)
  27. {
  28. setBinds(args...);
  29. execute();
  30. reset();
  31. }
  32. template<typename... Args>
  33. void setBinds(const Args &... args)
  34. {
  35. setBindSingle(1, args...); // The leftmost SQL parameter has an index of 1
  36. }
  37. template<typename... Args>
  38. void getColumns(Args &... args)
  39. {
  40. getColumnSingle(0, args...); // The leftmost column of the result set has the index 0
  41. }
  42. private:
  43. void setBindSingle(size_t index, const double & value);
  44. void setBindSingle(size_t index, const bool & value);
  45. void setBindSingle(size_t index, const uint8_t & value);
  46. void setBindSingle(size_t index, const uint16_t & value);
  47. void setBindSingle(size_t index, const uint32_t & value);
  48. void setBindSingle(size_t index, const int32_t & value);
  49. void setBindSingle(size_t index, const int64_t & value);
  50. void setBindSingle(size_t index, const std::string & value);
  51. void setBindSingle(size_t index, const char * value);
  52. void getColumnSingle(size_t index, double & value);
  53. void getColumnSingle(size_t index, bool & value);
  54. void getColumnSingle(size_t index, uint8_t & value);
  55. void getColumnSingle(size_t index, uint16_t & value);
  56. void getColumnSingle(size_t index, uint32_t & value);
  57. void getColumnSingle(size_t index, int32_t & value);
  58. void getColumnSingle(size_t index, int64_t & value);
  59. void getColumnSingle(size_t index, std::string & value);
  60. template < typename T, typename std::enable_if_t < std::is_enum_v<T>, int > = 0 >
  61. void getColumnSingle(size_t index, T & value)
  62. {
  63. using Integer = std::underlying_type_t<T>;
  64. Integer result;
  65. getColumnSingle(index, result);
  66. value = static_cast<T>(result);
  67. }
  68. template<typename Rep, typename Period>
  69. void getColumnSingle(size_t index, std::chrono::duration<Rep, Period> & value)
  70. {
  71. int64_t durationValue = 0;
  72. getColumnSingle(index, durationValue);
  73. value = std::chrono::duration<Rep, Period>(durationValue);
  74. }
  75. SQLiteStatement(SQLiteInstance & instance, sqlite3_stmt * statement);
  76. template<typename T, typename... Args>
  77. void setBindSingle(size_t index, T const & arg, const Args &... args)
  78. {
  79. setBindSingle(index, arg);
  80. setBindSingle(index + 1, args...);
  81. }
  82. template<typename T, typename... Args>
  83. void getColumnSingle(size_t index, T & arg, Args &... args)
  84. {
  85. getColumnSingle(index, arg);
  86. getColumnSingle(index + 1, args...);
  87. }
  88. SQLiteInstance & m_instance;
  89. sqlite3_stmt * m_statement;
  90. };
  91. class SQLiteInstance : boost::noncopyable
  92. {
  93. public:
  94. friend class SQLiteStatement;
  95. static SQLiteInstancePtr open(const boost::filesystem::path & db_path, bool allow_write);
  96. ~SQLiteInstance();
  97. SQLiteStatementPtr prepare(const std::string & statement);
  98. private:
  99. explicit SQLiteInstance(sqlite3 * connection);
  100. sqlite3 * m_connection;
  101. };