# DatabaseManager (`assignments::one::DatabaseManager`) ## Overview The `DatabaseManager` class is a PostgreSQL database interface for the ROS2 grade calculator. It handles all database operations including connection management, table creation and data insertion. ## Implementation Details ### Dependencies - **pqxx**: Modern C++ PostgreSQL library for database connectivity - **rclcpp**: ROS2 C++ client library for logging - **ConfigManager**: Configuration manager for database settings ### Key Components #### Constructor ```cpp DatabaseManager(rclcpp::Logger logger) ``` - Initializes the database manager with ROS2 logging - Creates a ConfigManager instance for configuration handling - Automatically calls `init_database()` to establish connection and setup #### Connection Management **`bool connect(const std::string& connection_string)`** > Returns `true` on successful connection, `false` on failure - Establishes connection to PostgreSQL database using connection information from the config TOML - Connection string format: `"host=localhost port=5432 dbname=grades user=postgres password=postgres"` **`bool is_connected() const`** > Returns `true` if connection exists and is open - Check for active database connection status #### Database Initialization **`void init_database()`** - Database setup process - Loads configuration from ConfigManager - Establishes connection using configuration settings - Creates necessary tables and inserts sample data - Error handling for configuration and connection failures **`void create_tables()`** - Creates all required database tables using SQL queries from `SQLQueries.hpp` - Tables created: - `enrollments`: Student course enrollments - `exam_results`: Individual exam scores - `course_results`: Final course grades and statistics - Uses transactions for atomic table creation **`void insert_sample_data()`** - Inserts predefined sample student data ### Data Operations #### Student Course Management **`std::vector queue_pending_combinations()`** > Returns vector of StudentCourse objects for processing queue - Gets all student-course combinations that need exam results generated - Executes complex SQL query to find missing exam results **`bool enroll_student_into_course(const StudentCourse& sc)`** > Returns `true` on successful enrollment, `false` on failure - Enrolls a student into a specific course #### Exam Result Processing **`bool store_exam_result(const std::string& student_name, const std::string& course_name, int grade)`** - Stores individual exam results in the database - Parameters: - `student_name`: Name of the student - `course_name`: Name of the course - `grade`: Exam score (10-100) **`bool store_final_course_result(const StudentCourse& sc, int exam_count, int final_grade)`** - Stores calculated final course results - Parameters: - `sc`: StudentCourse object containing student and course names - `exam_count`: Number of exams taken - `final_grade`: Calculated final grade - Used by grade calculation nodes for final result storage #### Grade Retrieval **`int get_final_course_grade(const StudentCourse& sc)`** > Returns: > - `> 0`: Valid final grade (rounded average) > - `-1`: No exams taken or no results found - Gets final calculated grade for a student-course combination - Performs average calculation with proper rounding - Used by nodes to check if final grading is complete ### Logging - Uses ROS2 logger with `[DBS]` prefix for database operations - Different log levels: - `INFO`: Successful operations, connection status - `ERROR`: SQL errors, connection failures, configuration issues - `WARN`: Non-critical issues, missing configurations ### Usage Examples #### Basic Database Setup ```cpp // Create DatabaseManager with ROS2 logger DatabaseManager db_manager(node->get_logger()); // Check connection status if (db_manager.is_connected()) { // Database ready for operations bool success = db_manager.store_exam_result("Wessel", "ROS2", 85); if (success) { RCLCPP_INFO(logger, "Exam result stored successfully"); } } ```