database.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #include "database.hpp"
  2. #include <iostream>
  3. namespace db {
  4. // Объект работы с БД
  5. static sqlite3* DB;
  6. void databaseInit(std::string filename) {
  7. db_path = filename;
  8. }
  9. int databaseOpen() {
  10. return sqlite3_open(db_path.c_str(), &DB);
  11. }
  12. void databaseClose() {
  13. sqlite3_close(DB);
  14. }
  15. // Для каждого запроса на создание таблиц из массива quieries мы вызываем
  16. // sqlite3_exec. Если запрос провалится, выводим сообщение об ошибке
  17. void createTables() {
  18. char* message_error;
  19. int status;
  20. std::array<std::string, 3> queries = {
  21. "CREATE TABLE IF NOT EXISTS \"author\" (\
  22. \"id\" INTEGER,\
  23. \"ytid\" TEXT,\
  24. \"name\" TEXT,\
  25. PRIMARY KEY(\"id\" AUTOINCREMENT)\
  26. )",
  27. "CREATE TABLE IF NOT EXISTS \"video\" (\
  28. \"id\" INTEGER,\
  29. \"ytid\" TEXT,\
  30. \"title\" TEXT NOT NULL,\
  31. \"description\" TEXT NOT NULL,\
  32. \"author_id\" INTEGER NOT NULL,\
  33. \"published_at\" DATETIME NOT NULL,\
  34. \"dur_h\" INTEGER NOT NULL DEFAULT 0,\
  35. \"dur_m\" INTEGER NOT NULL DEFAULT 0,\
  36. \"dur_s\" INTEGER NOT NULL DEFAULT 0,\
  37. \"views_count\" INTEGER NOT NULL DEFAULT 0,\
  38. \"likes_count\" INTEGER NOT NULL DEFAULT 0,\
  39. \"rate_status\" INTEGER NOT NULL DEFAULT 0,\
  40. \"big_thumbnail\" TEXT NOT NULL,\
  41. PRIMARY KEY(\"id\" AUTOINCREMENT)\
  42. )",
  43. "PRAGMA journal_mode=WAL"
  44. };
  45. databaseOpen();
  46. for (int i = 0; i < 3; i++) {
  47. status = sqlite3_exec(DB, queries[i].c_str(), NULL, 0, &message_error);
  48. if (status != SQLITE_OK) {
  49. std::cerr << "Error creating tables: " << status << std::endl;
  50. sqlite3_free(message_error);
  51. databaseClose();
  52. return;
  53. }
  54. }
  55. databaseClose();
  56. }
  57. bool getVideoByYTID(std::string ytid, video* output) {
  58. sqlite3_stmt* stmt;
  59. std::string query =
  60. "SELECT v.id, v.ytid, v.title, v.description, a.id, a.ytid, a.name,"
  61. " v.published_at, v.views_count, v.rate_status, v.big_thumbnail"
  62. " FROM video v LEFT JOIN author a ON v.author_id=a.id"
  63. " WHERE v.ytid=?";
  64. databaseOpen();
  65. author video_author;
  66. // Подготовка
  67. sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr);
  68. // Привязка данных
  69. sqlite3_bind_text(stmt, 1, ytid.c_str(), ytid.length(), SQLITE_STATIC);
  70. // Выполнение
  71. int result = sqlite3_step(stmt);
  72. if (result == SQLITE_DONE) {
  73. // Видео не найдено
  74. databaseClose();
  75. return false;
  76. }
  77. // Заполнение данными
  78. // unsigned const char* конвертируется в std::string
  79. // https://stackoverflow.com/a/804131
  80. video_author.id = sqlite3_column_int(stmt, 4);
  81. video_author.ytid = std::string(reinterpret_cast<const char*>(
  82. sqlite3_column_text(stmt, 5)
  83. ));
  84. video_author.name = Glib::ustring(reinterpret_cast<const char*>(
  85. sqlite3_column_text(stmt, 6)
  86. ));
  87. output->id = sqlite3_column_int(stmt, 0);
  88. output->ytid = std::string(reinterpret_cast<const char*>(
  89. sqlite3_column_text(stmt, 1)
  90. ));
  91. output->title = Glib::ustring(reinterpret_cast<const char*>(
  92. sqlite3_column_text(stmt, 2)
  93. ));
  94. output->description = Glib::ustring(reinterpret_cast<const char*>(
  95. sqlite3_column_text(stmt, 3)
  96. ));
  97. output->published_at = std::string(reinterpret_cast<const char*>(
  98. sqlite3_column_text(stmt, 7)
  99. ));
  100. output->views_count = sqlite3_column_int(stmt, 8);
  101. output->rate_status = sqlite3_column_int(stmt, 9);
  102. output->big_thumbnail = std::string(reinterpret_cast<const char*>(
  103. sqlite3_column_text(stmt, 10)
  104. ));
  105. output->author_obj = video_author;
  106. // Завершение
  107. sqlite3_finalize(stmt);
  108. databaseClose();
  109. return true;
  110. }
  111. bool getAuthorByYTID(std::string ytid, author* output) {
  112. sqlite3_stmt* stmt;
  113. std::string query =
  114. "SELECT a.id, a.name"
  115. " FROM author a"
  116. " WHERE a.ytid=?";
  117. databaseOpen();
  118. // Подготовка
  119. sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr);
  120. // Привязка данных
  121. sqlite3_bind_text(stmt, 1, ytid.c_str(), ytid.length(), SQLITE_STATIC);
  122. // Выполнение
  123. int result = sqlite3_step(stmt);
  124. if (result == SQLITE_DONE) {
  125. // Автор не найден
  126. databaseClose();
  127. return false;
  128. }
  129. // Заполнение данными
  130. output->id = sqlite3_column_int(stmt, 0);
  131. output->name = std::string(reinterpret_cast<const char*>(
  132. sqlite3_column_text(stmt, 1)
  133. ));
  134. // Завершение
  135. sqlite3_finalize(stmt);
  136. databaseClose();
  137. return true;
  138. }
  139. void addAuthor(author* a) {
  140. sqlite3_stmt* stmt;
  141. std::string query =
  142. "INSERT INTO author (ytid, name) VALUES(?, ?)";
  143. databaseOpen();
  144. sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr);
  145. sqlite3_bind_text(stmt, 1, a->ytid.c_str(), a->ytid.length(), SQLITE_STATIC);
  146. sqlite3_bind_text(stmt, 2, a->name.c_str(), a->name.bytes(), SQLITE_STATIC);
  147. sqlite3_step(stmt);
  148. a->id = sqlite3_last_insert_rowid(DB);
  149. sqlite3_finalize(stmt);
  150. databaseClose();
  151. }
  152. void addVideo(video* v)
  153. {
  154. sqlite3_stmt* stmt;
  155. std::string query =
  156. "INSERT INTO video (ytid, title, description, author_id, published_at,"
  157. " views_count, rate_status, big_thumbnail)"
  158. " VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
  159. databaseOpen();
  160. sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr);
  161. sqlite3_bind_text(stmt, 1, v->ytid.c_str(), v->ytid.length(), SQLITE_STATIC);
  162. sqlite3_bind_text(stmt, 2, v->title.c_str(), v->title.bytes(), SQLITE_STATIC);
  163. sqlite3_bind_text(stmt, 3, v->description.c_str(), v->description.bytes(), SQLITE_STATIC);
  164. sqlite3_bind_int(stmt, 4, v->author_obj.id);
  165. sqlite3_bind_text(stmt, 5, v->published_at.c_str(), v->published_at.length(), SQLITE_STATIC);
  166. sqlite3_bind_int(stmt, 6, v->views_count);
  167. sqlite3_bind_int(stmt, 7, v->rate_status);
  168. sqlite3_bind_text(stmt, 8, v->big_thumbnail.c_str(), v->big_thumbnail.length(), SQLITE_STATIC);
  169. sqlite3_step(stmt);
  170. v->id = sqlite3_last_insert_rowid(DB);
  171. sqlite3_finalize(stmt);
  172. databaseClose();
  173. }
  174. void setVideoRating(std::string ytid, int rating)
  175. {
  176. sqlite3_stmt* stmt;
  177. std::string query =
  178. "UPDATE video SET rate_status=? WHERE ytid=?";
  179. databaseOpen();
  180. sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr);
  181. sqlite3_bind_int(stmt, 1, rating);
  182. sqlite3_bind_text(stmt, 2, ytid.c_str(), ytid.length(), SQLITE_STATIC);
  183. sqlite3_finalize(stmt);
  184. databaseClose();
  185. }
  186. int getVideoRating(std::string ytid)
  187. {
  188. sqlite3_stmt* stmt;
  189. std::string query =
  190. "SELECT v.rate_status"
  191. " FROM video v"
  192. " WHERE v.ytid=?";
  193. databaseOpen();
  194. sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr);
  195. sqlite3_bind_text(stmt, 1, ytid.c_str(), ytid.length(), SQLITE_STATIC);
  196. // Выполнение
  197. int output;
  198. int result = sqlite3_step(stmt);
  199. if (result == SQLITE_DONE) {
  200. // Видео не найдено
  201. output = 3;
  202. }
  203. output = sqlite3_column_int(stmt, 0);
  204. databaseClose();
  205. return output;
  206. }
  207. }