- init: inti repo
This commit is contained in:
306
database.cpp
Normal file
306
database.cpp
Normal file
@@ -0,0 +1,306 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user