Files
StationManager/database.cpp
2026-04-05 16:14:54 +03:00

307 lines
10 KiB
C++

#include "database.h"
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlRecord>
#include <QFile>
#include <QTextStream>
#include <QDir>
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<User> Database::getAllUsers() {
QVector<User> 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<Route> Database::getAllRoutes() {
QVector<Route> 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<Ticket> Database::getTicketsByRoute(int routeId) {
QVector<Ticket> 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<Ticket> Database::getAllTickets() {
QVector<Ticket> 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;
}