#include "database.h" #include #include #include #include #include #include Database& Database::instance() { static Database instance; return instance; } bool Database::initialize() { m_db = QSqlDatabase::addDatabase("QSQLITE", "StationDB"); QString dbPath = QDir::currentPath() + "/station.db"; m_db.setDatabaseName(dbPath); if (!m_db.open()) { qDebug() << QDir::currentPath() + "/station.db"; qDebug() << "Database open error:" << m_db.lastError().text(); return false; } QSqlQuery query(m_db); query.exec("CREATE TABLE IF NOT EXISTS users (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "username TEXT UNIQUE NOT NULL, " "password TEXT NOT NULL, " "role TEXT NOT NULL)"); query.exec("CREATE TABLE IF NOT EXISTS routes (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "route_name TEXT NOT NULL, " "departure_time TEXT NOT NULL, " "price REAL NOT NULL, " "total_seats INTEGER NOT NULL, " "available_seats INTEGER NOT NULL)"); query.exec("CREATE TABLE IF NOT EXISTS tickets (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "route_id INTEGER NOT NULL, " "passenger_name TEXT NOT NULL, " "document_number TEXT NOT NULL, " "seat_count INTEGER NOT NULL, " "total_price REAL NOT NULL, " "seller_id INTEGER NOT NULL, " "sale_date TEXT NOT NULL, " "FOREIGN KEY (route_id) REFERENCES routes(id), " "FOREIGN KEY (seller_id) REFERENCES users(id))"); query.exec("SELECT COUNT(*) FROM users WHERE role = 'admin'"); if (query.next() && query.value(0).toInt() == 0) { addUser("admin", "admin123", "admin"); } return true; } QString Database::hashPassword(const QString& password) { QByteArray hash = QCryptographicHash::hash( password.toUtf8(), QCryptographicHash::Sha256); return hash.toHex(); } bool Database::authenticate(const QString& username, const QString& password) { QSqlQuery query(m_db); query.prepare("SELECT password FROM users WHERE username = ?"); query.addBindValue(username); if (query.exec() && query.next()) { return query.value(0).toString() == hashPassword(password); } return false; } User Database::getUser(const QString& username) { User user; QSqlQuery query(m_db); query.prepare("SELECT id, username, password, role FROM users WHERE username = ?"); query.addBindValue(username); if (query.exec() && query.next()) { user.id = query.value(0).toInt(); user.username = query.value(1).toString(); user.password = query.value(2).toString(); user.role = query.value(3).toString(); } return user; } QVector Database::getAllUsers() { QVector users; QSqlQuery query("SELECT id, username, password, role FROM users", m_db); while (query.next()) { User user; user.id = query.value(0).toInt(); user.username = query.value(1).toString(); user.password = query.value(2).toString(); user.role = query.value(3).toString(); users.append(user); } return users; } bool Database::addUser(const QString& username, const QString& password, const QString& role) { QSqlQuery query(m_db); query.prepare("INSERT INTO users (username, password, role) VALUES (?, ?, ?)"); query.addBindValue(username); query.addBindValue(hashPassword(password)); query.addBindValue(role); return query.exec(); } bool Database::deleteUser(int id) { QSqlQuery query(m_db); query.prepare("DELETE FROM users WHERE id = ? AND role != 'admin'"); query.addBindValue(id); return query.exec(); } QVector Database::getAllRoutes() { QVector routes; QSqlQuery query("SELECT id, route_name, departure_time, price, total_seats, available_seats FROM routes", m_db); while (query.next()) { Route route; route.id = query.value(0).toInt(); route.routeName = query.value(1).toString(); route.departureTime = query.value(2).toString(); route.price = query.value(3).toDouble(); route.totalSeats = query.value(4).toInt(); route.availableSeats = query.value(5).toInt(); routes.append(route); } return routes; } Route Database::getRoute(int id) { Route route; QSqlQuery query(m_db); query.prepare("SELECT id, route_name, departure_time, price, total_seats, available_seats FROM routes WHERE id = ?"); query.addBindValue(id); if (query.exec() && query.next()) { route.id = query.value(0).toInt(); route.routeName = query.value(1).toString(); route.departureTime = query.value(2).toString(); route.price = query.value(3).toDouble(); route.totalSeats = query.value(4).toInt(); route.availableSeats = query.value(5).toInt(); } return route; } bool Database::addRoute(const QString& routeName, const QString& departureTime, double price, int totalSeats) { QSqlQuery query(m_db); query.prepare("INSERT INTO routes (route_name, departure_time, price, total_seats, available_seats) " "VALUES (?, ?, ?, ?, ?)"); query.addBindValue(routeName); query.addBindValue(departureTime); query.addBindValue(price); query.addBindValue(totalSeats); query.addBindValue(totalSeats); return query.exec(); } bool Database::updateRoute(const Route& route) { QSqlQuery query(m_db); query.prepare("UPDATE routes SET route_name = ?, departure_time = ?, price = ?, " "total_seats = ?, available_seats = ? WHERE id = ?"); query.addBindValue(route.routeName); query.addBindValue(route.departureTime); query.addBindValue(route.price); query.addBindValue(route.totalSeats); query.addBindValue(route.availableSeats); query.addBindValue(route.id); return query.exec(); } bool Database::deleteRoute(int id) { QSqlQuery query(m_db); query.prepare("DELETE FROM routes WHERE id = ?"); query.addBindValue(id); return query.exec(); } bool Database::updateAvailableSeats(int routeId, int change) { QSqlQuery query(m_db); query.prepare("UPDATE routes SET available_seats = available_seats + ? WHERE id = ?"); query.addBindValue(change); query.addBindValue(routeId); return query.exec(); } QVector Database::getTicketsByRoute(int routeId) { QVector tickets; QSqlQuery query(m_db); query.prepare("SELECT t.id, t.route_id, r.route_name, t.passenger_name, " "t.document_number, t.seat_count, t.total_price, t.seller_id, " "u.username, t.sale_date " "FROM tickets t " "JOIN routes r ON t.route_id = r.id " "JOIN users u ON t.seller_id = u.id " "WHERE t.route_id = :route_id"); query.bindValue(":route_id", routeId); query.exec(); while (query.next()) { Ticket ticket; ticket.id = query.value(0).toInt(); ticket.routeId = query.value(1).toInt(); ticket.routeName = query.value(2).toString(); ticket.passengerName = query.value(3).toString(); ticket.documentNumber = query.value(4).toString(); ticket.seatCount = query.value(5).toInt(); ticket.totalPrice = query.value(6).toDouble(); ticket.sellerId = query.value(7).toInt(); ticket.sellerName = query.value(8).toString(); ticket.saleDate = query.value(9).toString(); tickets.append(ticket); } return tickets; } QVector Database::getAllTickets() { QVector tickets; QSqlQuery query("SELECT t.id, t.route_id, r.route_name, t.passenger_name, " "t.document_number, t.seat_count, t.total_price, t.seller_id, " "u.username, t.sale_date " "FROM tickets t " "JOIN routes r ON t.route_id = r.id " "JOIN users u ON t.seller_id = u.id " "ORDER BY t.sale_date DESC",m_db); query.exec(); while (query.next()) { Ticket ticket; ticket.id = query.value(0).toInt(); ticket.routeId = query.value(1).toInt(); ticket.routeName = query.value(2).toString(); ticket.passengerName = query.value(3).toString(); ticket.documentNumber = query.value(4).toString(); ticket.seatCount = query.value(5).toInt(); ticket.totalPrice = query.value(6).toDouble(); ticket.sellerId = query.value(7).toInt(); ticket.sellerName = query.value(8).toString(); ticket.saleDate = query.value(9).toString(); tickets.append(ticket); } return tickets; } bool Database::addTicket(int routeId, const QString& passengerName, const QString& documentNumber, int seatCount, int sellerId) { Route route = getRoute(routeId); double totalPrice = route.price * seatCount; QSqlQuery query(m_db); query.prepare("INSERT INTO tickets (route_id, passenger_name, document_number, " "seat_count, total_price, seller_id, sale_date) VALUES (?, ?, ?, ?, ?, ?, ?)"); query.addBindValue(routeId); query.addBindValue(passengerName); query.addBindValue(documentNumber); query.addBindValue(seatCount); query.addBindValue(totalPrice); query.addBindValue(sellerId); query.addBindValue(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); if (query.exec()) { return updateAvailableSeats(routeId, -seatCount); } return false; } bool Database::deleteTicket(int id) { QSqlQuery query(m_db); query.prepare("SELECT route_id, seat_count FROM tickets WHERE id = ?"); query.addBindValue(id); if (query.exec() && query.next()) { int routeId = query.value(0).toInt(); int seatCount = query.value(1).toInt(); query.prepare("DELETE FROM tickets WHERE id = ?"); query.addBindValue(id); if (query.exec()) { return updateAvailableSeats(routeId, seatCount); } } return false; } int Database::getLastTicketId() { QSqlQuery query("SELECT last_insert_rowid()", m_db); if (query.next()) { return query.value(0).toInt(); } return -1; }