2
0

SQLiteConnection.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * SQLiteConnection.cpp, 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. #include "StdInc.h"
  11. #include "SQLiteConnection.h"
  12. #include <sqlite3.h>
  13. [[noreturn]] static void handleSQLiteError(sqlite3 * connection)
  14. {
  15. const char * message = sqlite3_errmsg(connection);
  16. throw std::runtime_error(std::string("SQLite error: ") + message);
  17. }
  18. static void checkSQLiteError(sqlite3 * connection, int result)
  19. {
  20. if(result != SQLITE_OK)
  21. handleSQLiteError(connection);
  22. }
  23. SQLiteStatement::SQLiteStatement(SQLiteInstance & instance, sqlite3_stmt * statement)
  24. : m_instance(instance)
  25. , m_statement(statement)
  26. {
  27. }
  28. SQLiteStatement::~SQLiteStatement()
  29. {
  30. int result = sqlite3_finalize(m_statement);
  31. checkSQLiteError(m_instance.m_connection, result);
  32. }
  33. bool SQLiteStatement::execute()
  34. {
  35. int result = sqlite3_step(m_statement);
  36. switch(result)
  37. {
  38. case SQLITE_DONE:
  39. return false;
  40. case SQLITE_ROW:
  41. return true;
  42. default:
  43. checkSQLiteError(m_instance.m_connection, result);
  44. return false;
  45. }
  46. }
  47. void SQLiteStatement::reset()
  48. {
  49. int result = sqlite3_reset(m_statement);
  50. checkSQLiteError(m_instance.m_connection, result);
  51. }
  52. void SQLiteStatement::clear()
  53. {
  54. int result = sqlite3_clear_bindings(m_statement);
  55. checkSQLiteError(m_instance.m_connection, result);
  56. }
  57. void SQLiteStatement::setBindSingle(size_t index, const double & value)
  58. {
  59. int result = sqlite3_bind_double(m_statement, static_cast<int>(index), value);
  60. checkSQLiteError(m_instance.m_connection, result);
  61. }
  62. void SQLiteStatement::setBindSingle(size_t index, const bool & value)
  63. {
  64. int result = sqlite3_bind_int(m_statement, static_cast<int>(value), value);
  65. checkSQLiteError(m_instance.m_connection, result);
  66. }
  67. void SQLiteStatement::setBindSingle(size_t index, const uint8_t & value)
  68. {
  69. int result = sqlite3_bind_int(m_statement, static_cast<int>(index), value);
  70. checkSQLiteError(m_instance.m_connection, result);
  71. }
  72. void SQLiteStatement::setBindSingle(size_t index, const uint16_t & value)
  73. {
  74. int result = sqlite3_bind_int(m_statement, static_cast<int>(index), value);
  75. checkSQLiteError(m_instance.m_connection, result);
  76. }
  77. void SQLiteStatement::setBindSingle(size_t index, const uint32_t & value)
  78. {
  79. int result = sqlite3_bind_int(m_statement, static_cast<int>(index), value);
  80. checkSQLiteError(m_instance.m_connection, result);
  81. }
  82. void SQLiteStatement::setBindSingle(size_t index, const int32_t & value)
  83. {
  84. int result = sqlite3_bind_int(m_statement, static_cast<int>(index), value);
  85. checkSQLiteError(m_instance.m_connection, result);
  86. }
  87. void SQLiteStatement::setBindSingle(size_t index, const int64_t & value)
  88. {
  89. int result = sqlite3_bind_int64(m_statement, static_cast<int>(index), value);
  90. checkSQLiteError(m_instance.m_connection, result);
  91. }
  92. void SQLiteStatement::setBindSingle(size_t index, const std::string & value)
  93. {
  94. int result = sqlite3_bind_text(m_statement, static_cast<int>(index), value.data(), static_cast<int>(value.size()), SQLITE_STATIC);
  95. checkSQLiteError(m_instance.m_connection, result);
  96. }
  97. void SQLiteStatement::setBindSingle(size_t index, const char * value)
  98. {
  99. int result = sqlite3_bind_text(m_statement, static_cast<int>(index), value, -1, SQLITE_STATIC);
  100. checkSQLiteError(m_instance.m_connection, result);
  101. }
  102. void SQLiteStatement::getColumnSingle(size_t index, double & value)
  103. {
  104. value = sqlite3_column_double(m_statement, static_cast<int>(index));
  105. }
  106. void SQLiteStatement::getColumnSingle(size_t index, bool & value)
  107. {
  108. value = sqlite3_column_int(m_statement, static_cast<int>(index)) != 0;
  109. }
  110. void SQLiteStatement::getColumnSingle(size_t index, uint8_t & value)
  111. {
  112. value = static_cast<uint8_t>(sqlite3_column_int(m_statement, static_cast<int>(index)));
  113. }
  114. void SQLiteStatement::getColumnSingle(size_t index, uint16_t & value)
  115. {
  116. value = static_cast<uint16_t>(sqlite3_column_int(m_statement, static_cast<int>(index)));
  117. }
  118. void SQLiteStatement::getColumnSingle(size_t index, int32_t & value)
  119. {
  120. value = sqlite3_column_int(m_statement, static_cast<int>(index));
  121. }
  122. void SQLiteStatement::getColumnSingle(size_t index, uint32_t & value)
  123. {
  124. value = sqlite3_column_int(m_statement, static_cast<int>(index));
  125. }
  126. void SQLiteStatement::getColumnSingle(size_t index, int64_t & value)
  127. {
  128. value = sqlite3_column_int64(m_statement, static_cast<int>(index));
  129. }
  130. void SQLiteStatement::getColumnSingle(size_t index, std::string & value)
  131. {
  132. const auto * value_raw = sqlite3_column_text(m_statement, static_cast<int>(index));
  133. value = reinterpret_cast<const char *>(value_raw);
  134. }
  135. SQLiteInstancePtr SQLiteInstance::open(const boost::filesystem::path & db_path, bool allow_write)
  136. {
  137. int flags = allow_write ? (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE) : SQLITE_OPEN_READONLY;
  138. sqlite3 * connection;
  139. int result = sqlite3_open_v2(db_path.c_str(), &connection, flags, nullptr);
  140. if(result == SQLITE_OK)
  141. return SQLiteInstancePtr(new SQLiteInstance(connection));
  142. sqlite3_close(connection);
  143. handleSQLiteError(connection);
  144. }
  145. SQLiteInstance::SQLiteInstance(sqlite3 * connection)
  146. : m_connection(connection)
  147. {
  148. }
  149. SQLiteInstance::~SQLiteInstance()
  150. {
  151. int result = sqlite3_close(m_connection);
  152. checkSQLiteError(m_connection, result);
  153. }
  154. SQLiteStatementPtr SQLiteInstance::prepare(const std::string & sql_text)
  155. {
  156. sqlite3_stmt * statement;
  157. int result = sqlite3_prepare_v2(m_connection, sql_text.data(), static_cast<int>(sql_text.size()), &statement, nullptr);
  158. if(result == SQLITE_OK)
  159. return SQLiteStatementPtr(new SQLiteStatement(*this, statement));
  160. sqlite3_finalize(statement);
  161. handleSQLiteError(m_connection);
  162. }