database.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #include "database.hpp"
  2. namespace db {
  3. // Объект работы с БД
  4. static sqlite3* DB;
  5. void databaseInit(std::string filename) {
  6. db_path = filename;
  7. }
  8. int databaseOpen() {
  9. return sqlite3_open(db_path.c_str(), &DB);
  10. }
  11. void databaseClose() {
  12. sqlite3_close(DB);
  13. }
  14. // Для каждого запроса на создание таблиц из массива quieries мы вызываем
  15. // sqlite3_exec. Если запрос провалится, выводим сообщение об ошибке
  16. void createTables() {
  17. char* message_error;
  18. int status;
  19. std::array<std::string, 2> queries = {
  20. "CREATE TABLE IF NOT EXISTS \"author\" (\
  21. \"id\" INTEGER,\
  22. \"yt_id\" TEXT,\
  23. \"name\" TEXT,\
  24. PRIMARY KEY(\"id\" AUTOINCREMENT)\
  25. )",
  26. "CREATE TABLE IF NOT EXISTS \"video\" (\
  27. \"id\" INTEGER,\
  28. \"yt_id\" TEXT,\
  29. \"title\" TEXT NOT NULL,\
  30. \"description\" TEXT,\
  31. \"author_id\" INTEGER NOT NULL,\
  32. \"published_at\" TEXT NOT NULL,\
  33. PRIMARY KEY(\"id\" AUTOINCREMENT)\
  34. )"
  35. };
  36. databaseOpen();
  37. for (int i = 0; i < 2; i++) {
  38. status = sqlite3_exec(DB, queries[i].c_str(), NULL, 0, &message_error);
  39. if (status != SQLITE_OK) {
  40. std::cerr << "Error creating tables" << std::endl;
  41. sqlite3_free(message_error);
  42. return;
  43. }
  44. }
  45. databaseClose();
  46. }
  47. bool getVideoByYTID(std::string yt_id, video* output) {
  48. sqlite3_stmt* stmt;
  49. std::string query =
  50. "SELECT v.id,v.yt_id,v.title,v.description,a.id,a.yt_id,a.name,v.published_at"
  51. " FROM video v LEFT JOIN author a ON v.author_id=a.id"
  52. " WHERE v.yt_id=?";
  53. databaseOpen();
  54. author video_author;
  55. // Подготовка
  56. sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr);
  57. // Привязка данных
  58. sqlite3_bind_text(stmt, 1, yt_id.c_str(), yt_id.length(), SQLITE_STATIC);
  59. // Выполнение
  60. int result = sqlite3_step(stmt);
  61. if (result == SQLITE_DONE) {
  62. // Видео не найдено
  63. return false;
  64. }
  65. // Заполнение данными
  66. // unsigned const char* конвертируется в std::string
  67. // https://stackoverflow.com/a/804131
  68. video_author.id = sqlite3_column_int(stmt, 4);
  69. video_author.yt_id = std::string(reinterpret_cast<const char*>(
  70. sqlite3_column_text(stmt, 5)
  71. ));
  72. video_author.name = Glib::ustring(reinterpret_cast<const char*>(
  73. sqlite3_column_text(stmt, 6)
  74. ));
  75. output->id = sqlite3_column_int(stmt, 0);
  76. output->yt_id = std::string(reinterpret_cast<const char*>(
  77. sqlite3_column_text(stmt, 1)
  78. ));
  79. output->title = Glib::ustring(reinterpret_cast<const char*>(
  80. sqlite3_column_text(stmt, 2)
  81. ));
  82. output->description = Glib::ustring(reinterpret_cast<const char*>(
  83. sqlite3_column_text(stmt, 3)
  84. ));
  85. output->published_at = std::string(reinterpret_cast<const char*>(
  86. sqlite3_column_text(stmt, 7)
  87. ));
  88. output->author_obj = video_author;
  89. // Завершение
  90. sqlite3_finalize(stmt);
  91. databaseClose();
  92. return true;
  93. }
  94. bool getAuthorByYTID(std::string yt_id, author* output) {
  95. sqlite3_stmt* stmt;
  96. std::string query =
  97. "SELECT a.id, a.name"
  98. " FROM author a"
  99. " WHERE a.yt_id=?";
  100. databaseOpen();
  101. // Подготовка
  102. sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr);
  103. // Привязка данных
  104. sqlite3_bind_text(stmt, 1, yt_id.c_str(), yt_id.length(), SQLITE_STATIC);
  105. // Выполнение
  106. int result = sqlite3_step(stmt);
  107. if (result == SQLITE_DONE) {
  108. // Видео не найдено
  109. return false;
  110. }
  111. // Заполнение данными
  112. output->id = sqlite3_column_int(stmt, 0);
  113. output->name = std::string(reinterpret_cast<const char*>(
  114. sqlite3_column_text(stmt, 1)
  115. ));
  116. // Завершение
  117. sqlite3_finalize(stmt);
  118. databaseClose();
  119. return true;
  120. }
  121. void addAuthor(author* a) {
  122. sqlite3_stmt* stmt;
  123. std::string query =
  124. "INSERT INTO author (yt_id, name) VALUES(?, ?)";
  125. databaseOpen();
  126. sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr);
  127. sqlite3_bind_text(stmt, 1, a->yt_id.c_str(), a->yt_id.length(), SQLITE_STATIC);
  128. sqlite3_bind_text(stmt, 2, a->name.c_str(), a->name.length(), SQLITE_STATIC);
  129. sqlite3_step(stmt);
  130. a->id = sqlite3_last_insert_rowid(DB);
  131. sqlite3_finalize(stmt);
  132. databaseClose();
  133. }
  134. void addVideo(video* v) {
  135. sqlite3_stmt* stmt;
  136. std::string query =
  137. "INSERT INTO video (yt_id, title, description, author_id, published_at)"
  138. " VALUES(?, ?, ?, ?, ?)";
  139. databaseOpen();
  140. sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr);
  141. sqlite3_bind_text(stmt, 1, v->yt_id.c_str(), v->yt_id.length(), SQLITE_STATIC);
  142. sqlite3_bind_text(stmt, 2, v->title.c_str(), v->title.length(), SQLITE_STATIC);
  143. sqlite3_bind_text(stmt, 3, v->description.c_str(), v->description.length(), SQLITE_STATIC);
  144. sqlite3_bind_int(stmt, 4, v->author_obj.id);
  145. sqlite3_bind_text(stmt, 5, v->published_at.c_str(), v->published_at.length(), SQLITE_STATIC);
  146. sqlite3_step(stmt);
  147. v->id = sqlite3_last_insert_rowid(DB);
  148. sqlite3_finalize(stmt);
  149. databaseClose();
  150. }
  151. }