#include "database.hpp" #include namespace db { // Объект работы с БД static sqlite3* DB; void databaseInit(std::string filename) { db_path = filename; } int databaseOpen() { return sqlite3_open(db_path.c_str(), &DB); } void databaseClose() { sqlite3_close(DB); } // Для каждого запроса на создание таблиц из массива quieries мы вызываем // sqlite3_exec. Если запрос провалится, выводим сообщение об ошибке void createTables() { char* message_error; int status; std::array queries = { "CREATE TABLE IF NOT EXISTS \"author\" (\ \"id\" INTEGER,\ \"yt_id\" TEXT,\ \"name\" TEXT,\ PRIMARY KEY(\"id\" AUTOINCREMENT)\ )", "CREATE TABLE IF NOT EXISTS \"video\" (\ \"id\" INTEGER,\ \"yt_id\" TEXT,\ \"title\" TEXT NOT NULL,\ \"description\" TEXT NOT NULL,\ \"author_id\" INTEGER NOT NULL,\ \"published_at\" DATETIME NOT NULL,\ \"dur_h\" INTEGER NOT NULL DEFAULT 0,\ \"dur_m\" INTEGER NOT NULL DEFAULT 0,\ \"dur_s\" INTEGER NOT NULL DEFAULT 0,\ \"views_count\" INTEGER NOT NULL DEFAULT 0,\ \"likes_count\" INTEGER NOT NULL DEFAULT 0,\ \"rate_status\" INTEGER NOT NULL DEFAULT 0,\ PRIMARY KEY(\"id\" AUTOINCREMENT)\ )", "PRAGMA journal_mode=WAL" }; databaseOpen(); for (int i = 0; i < 3; i++) { status = sqlite3_exec(DB, queries[i].c_str(), NULL, 0, &message_error); if (status != SQLITE_OK) { std::cerr << "Error creating tables" << std::endl; sqlite3_free(message_error); databaseClose(); return; } } databaseClose(); } bool getVideoByYTID(std::string yt_id, video* output) { sqlite3_stmt* stmt; std::string query = "SELECT v.id, v.yt_id, v.title, v.description, a.id, a.yt_id, a.name," " v.published_at, v.views_count, v.rate_status" " FROM video v LEFT JOIN author a ON v.author_id=a.id" " WHERE v.yt_id=?"; databaseOpen(); author video_author; // Подготовка sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr); // Привязка данных sqlite3_bind_text(stmt, 1, yt_id.c_str(), yt_id.length(), SQLITE_STATIC); // Выполнение int result = sqlite3_step(stmt); if (result == SQLITE_DONE) { // Видео не найдено databaseClose(); return false; } // Заполнение данными // unsigned const char* конвертируется в std::string // https://stackoverflow.com/a/804131 video_author.id = sqlite3_column_int(stmt, 4); video_author.yt_id = std::string(reinterpret_cast( sqlite3_column_text(stmt, 5) )); video_author.name = Glib::ustring(reinterpret_cast( sqlite3_column_text(stmt, 6) )); output->id = sqlite3_column_int(stmt, 0); output->yt_id = std::string(reinterpret_cast( sqlite3_column_text(stmt, 1) )); output->title = Glib::ustring(reinterpret_cast( sqlite3_column_text(stmt, 2) )); output->description = Glib::ustring(reinterpret_cast( sqlite3_column_text(stmt, 3) )); output->published_at = std::string(reinterpret_cast( sqlite3_column_text(stmt, 7) )); output->views_count = sqlite3_column_int(stmt, 8); output->rate_status = sqlite3_column_int(stmt, 9); output->author_obj = video_author; // Завершение sqlite3_finalize(stmt); databaseClose(); return true; } bool getAuthorByYTID(std::string yt_id, author* output) { sqlite3_stmt* stmt; std::string query = "SELECT a.id, a.name" " FROM author a" " WHERE a.yt_id=?"; databaseOpen(); // Подготовка sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr); // Привязка данных sqlite3_bind_text(stmt, 1, yt_id.c_str(), yt_id.length(), SQLITE_STATIC); // Выполнение int result = sqlite3_step(stmt); if (result == SQLITE_DONE) { // Автор не найден databaseClose(); return false; } // Заполнение данными output->id = sqlite3_column_int(stmt, 0); output->name = std::string(reinterpret_cast( sqlite3_column_text(stmt, 1) )); // Завершение sqlite3_finalize(stmt); databaseClose(); return true; } void addAuthor(author* a) { sqlite3_stmt* stmt; std::string query = "INSERT INTO author (yt_id, name) VALUES(?, ?)"; databaseOpen(); sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr); sqlite3_bind_text(stmt, 1, a->yt_id.c_str(), a->yt_id.length(), SQLITE_STATIC); sqlite3_bind_text(stmt, 2, a->name.c_str(), a->name.bytes(), SQLITE_STATIC); sqlite3_step(stmt); a->id = sqlite3_last_insert_rowid(DB); sqlite3_finalize(stmt); databaseClose(); } void addVideo(video* v) { sqlite3_stmt* stmt; std::string query = "INSERT INTO video (yt_id, title, description, author_id, published_at," " views_count, rate_status)" " VALUES(?, ?, ?, ?, ?, ?, ?)"; databaseOpen(); sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr); sqlite3_bind_text(stmt, 1, v->yt_id.c_str(), v->yt_id.length(), SQLITE_STATIC); sqlite3_bind_text(stmt, 2, v->title.c_str(), v->title.bytes(), SQLITE_STATIC); sqlite3_bind_text(stmt, 3, v->description.c_str(), v->description.bytes(), SQLITE_STATIC); sqlite3_bind_int(stmt, 4, v->author_obj.id); sqlite3_bind_text(stmt, 5, v->published_at.c_str(), v->published_at.length(), SQLITE_STATIC); sqlite3_bind_int(stmt, 6, v->views_count); sqlite3_bind_int(stmt, 7, static_cast(v->rate_status)); sqlite3_step(stmt); v->id = sqlite3_last_insert_rowid(DB); sqlite3_finalize(stmt); databaseClose(); } void setVideoRating(std::string yt_id, int rating) { sqlite3_stmt* stmt; std::string query = "UPDATE video SET rate_status=? WHERE yt_id=?"; databaseOpen(); sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr); sqlite3_bind_int(stmt, 1, rating); sqlite3_bind_text(stmt, 2, yt_id.c_str(), yt_id.length(), SQLITE_STATIC); std::cout << sqlite3_step(stmt); sqlite3_finalize(stmt); databaseClose(); } int getVideoRating(std::string yt_id) { sqlite3_stmt* stmt; std::string query = "SELECT v.rate_status" " FROM video v" " WHERE v.yt_id=?"; databaseOpen(); sqlite3_prepare_v2(DB, query.c_str(), query.length(), &stmt, nullptr); sqlite3_bind_text(stmt, 1, yt_id.c_str(), yt_id.length(), SQLITE_STATIC); // Выполнение int output; int result = sqlite3_step(stmt); if (result == SQLITE_DONE) { // Видео не найдено output = 3; } output = sqlite3_column_int(stmt, 0); databaseClose(); return output; } }