generated from wessel/boilerplate
Split documentation into three folders: Architecture, Testing and Installation. Rework and expand architecture.md alongside interfaces.md Split all parts to do with testing from Architecture md's into Test md's Add parameter to ExamResultGenerator node documentation
192 lines
6.2 KiB
Markdown
192 lines
6.2 KiB
Markdown
# 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<StudentCourse> 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");
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Unit Tests
|
|
|
|
Unit tests for `DatabaseManager` are implemented in `src/g2_2025_grade_calculator_pkg/test/DatabaseManager.test.cpp` using Google Test and ROS2 test utilities. The tests are designed to work reliably whether a database connection is available or not, focusing on error handling and method behavior validation.
|
|
|
|
### Test Cases
|
|
|
|
#### 1. ConstructorTest
|
|
|
|
**Description:** Verifies that DatabaseManager can be created without crashing and proper initialization occurs.
|
|
|
|
- **Test Action:** Create DatabaseManager instance with ROS2 logger
|
|
- **Expected Result:** Instance created successfully without exceptions
|
|
|
|
#### 2. ConnectionStatusTest
|
|
|
|
**Description:** Tests that the `is_connected()` method returns a valid boolean value.
|
|
|
|
- **Test Action:** Call `is_connected()` method
|
|
- **Expected Result:** Returns either `true` or `false` (no crashes or invalid states)
|
|
|
|
#### 3. QueuePendingCombinationsTest
|
|
|
|
**Description:** Verifies retrieval of pending student-course combinations that need exam results.
|
|
|
|
- **Test Action:** Call `queue_pending_combinations()`
|
|
- **Expected Result:** Returns valid vector (empty if no database connection, populated if connected)
|
|
|
|
#### 4. StoreExamResultTest
|
|
|
|
**Description:** Tests exam result storage with graceful handling of connection states.
|
|
|
|
- **Test Action:**
|
|
- Student: `"TestStudent"`
|
|
- Course: `"TestCourse"`
|
|
- Grade: `85`
|
|
- **Expected Result:** Returns `false` if no connection, `true` if connected and successful
|
|
|
|
#### 5. EnrollStudentTest
|
|
|
|
**Description:** Tests student enrollment into courses.
|
|
|
|
- **Test Action:**
|
|
- StudentCourse object with test data
|
|
- **Expected Result:** Returns `false` if no connection, `true` if connected and successful
|
|
|
|
#### 6. GetFinalGradeTest
|
|
|
|
**Description:** Tests final grade retrieval for non-existent student-course combinations.
|
|
|
|
- **Test Action:**
|
|
- Student: `"NonExistentStudent"`
|
|
- Course: `"NonExistentCourse"`
|
|
- **Expected Result:** Returns `-1` (no results found or no connection)
|
|
|
|
#### 7. StoreFinalResultTest
|
|
|
|
**Description:** Tests storing calculated final course results.
|
|
|
|
- **Test Action:**
|
|
- StudentCourse object
|
|
- Exam count: `3`
|
|
- Final grade: `75`
|
|
- **Expected Result:** Returns `false` if no connection, `true` if connected and successful
|