pub struct Workdays {
pub conn: Connection,
}Expand description
Database manager for workday operations and time tracking functionality.
The Workdays struct provides a comprehensive interface for managing daily
work sessions, including creation, modification, and querying of workday
records. It handles database connections, ensures data integrity, and
provides efficient access patterns for time tracking operations.
§Design Principles
- One Session Per Day: Each calendar date has at most one workday record
- Local Timezone: All timestamps use local timezone for user clarity
- Automatic Tracking: Supports both automatic and manual time entry
- Data Integrity: Enforces constraints and validation for reliable tracking
§Connection Management
Each instance maintains its own database connection and ensures the workdays table schema is properly initialized during construction.
Fields§
§conn: ConnectionDirect database connection for workday operations.
Provides transactional access to the workdays table with optimized performance for time tracking queries and updates.
Implementations§
Source§impl Workdays
impl Workdays
Sourcepub fn new() -> Result<Self>
pub fn new() -> Result<Self>
Creates a new Workdays manager and initializes the database schema.
This constructor establishes a database connection, ensures the workdays table exists with proper constraints, and prepares the manager for time tracking operations. Schema creation is idempotent and safe for repeated initialization.
§Returns
Returns a new Workdays instance ready for workday management
operations, or an error if database initialization fails.
§Example
use kasl::db::workdays::Workdays;
let mut workdays = Workdays::new()?;
// Ready for workday tracking§Database Integration
The workdays table schema is created if it doesn’t exist, ensuring the manager can operate regardless of database initialization order. This provides robustness in different deployment scenarios.
§Errors
Returns an error if:
- Database connection cannot be established
- Schema creation fails due to permissions or corruption
- Table initialization encounters constraint violations
Sourcepub fn insert_start(&mut self, date: NaiveDate) -> Result<()>
pub fn insert_start(&mut self, date: NaiveDate) -> Result<()>
Records the start of a work session for the specified date.
This method creates a new workday record with the current timestamp as the start time, or does nothing if a workday already exists for the given date. This prevents duplicate workday records while allowing safe repeated calls to start tracking.
§Duplicate Handling
The method checks for existing workday records before insertion to prevent database constraint violations. If a workday already exists for the specified date, the operation succeeds without modification.
§Timezone Consistency
Uses local timezone for timestamp recording to ensure consistency with user expectations and interface displays. All workday times are recorded in the system’s local timezone.
§Arguments
date- Calendar date for which to start work session tracking
§Returns
Returns Ok(()) if the start time is recorded or already exists,
or an error if the database operation fails.
§Example
use chrono::Local;
let mut workdays = Workdays::new()?;
let today = Local::now().date_naive();
workdays.insert_start(today)?; // Start tracking work for today§Idempotency
This operation is idempotent - calling it multiple times with the same date has the same effect as calling it once. This makes it safe for use in automatic tracking systems.
Sourcepub fn insert_end(&mut self, date: NaiveDate) -> Result<()>
pub fn insert_end(&mut self, date: NaiveDate) -> Result<()>
Records the end of a work session for the specified date.
This method updates an existing workday record by setting the end timestamp to the current time. It marks the completion of a work session and enables duration calculations for the workday.
§Prerequisites
The workday must already exist (created via insert_start) for this
operation to succeed. The method updates the existing record rather
than creating a new one, maintaining data integrity.
§Completion Semantics
Once a workday has an end time, it represents a completed work session for that date. The end time can be modified later using time adjustment methods if corrections are needed.
§Arguments
date- Calendar date for which to end work session tracking
§Returns
Returns Ok(()) if the end time is recorded successfully, or an error
if no workday exists for the date or the database operation fails.
§Example
use chrono::Local;
let mut workdays = Workdays::new()?;
let today = Local::now().date_naive();
// Start and end a work session
workdays.insert_start(today)?;
// ... work happens ...
workdays.insert_end(today)?; // Mark work as completed§Error Conditions
- No workday record exists for the specified date
- Database connection or constraint failures
- Concurrent modification conflicts
Sourcepub fn fetch(&mut self, date: NaiveDate) -> Result<Option<Workday>>
pub fn fetch(&mut self, date: NaiveDate) -> Result<Option<Workday>>
Retrieves a complete workday record for the specified date.
This method fetches detailed workday information including all temporal data and metadata for a specific calendar date. It provides the primary mechanism for accessing workday details for analysis and reporting.
§Data Parsing
The method handles automatic conversion from database string formats
to appropriate Rust types (NaiveDate, NaiveDateTime), providing
type safety and convenience for downstream operations.
§Return Semantics
Some(Workday): Complete workday record found for the dateNone: No workday exists for the specified dateError: Database access or parsing failures
§Arguments
date- Calendar date for which to retrieve workday information
§Returns
Returns Some(Workday) if a record exists, None if no workday is
found for the date, or an error if the database query fails.
§Example
use chrono::Local;
let mut workdays = Workdays::new()?;
let today = Local::now().date_naive();
if let Some(workday) = workdays.fetch(today)? {
println!("Work started at: {}", workday.start);
if let Some(end_time) = workday.end {
println!("Work ended at: {}", end_time);
} else {
println!("Work session is still active");
}
} else {
println!("No work session recorded for today");
}§Data Integrity
The method assumes well-formed timestamp data in the database and will return errors if timestamp parsing fails due to data corruption or unexpected format changes.
Sourcepub fn fetch_month(&mut self, date: NaiveDate) -> Result<Vec<Workday>>
pub fn fetch_month(&mut self, date: NaiveDate) -> Result<Vec<Workday>>
Retrieves all workdays within the calendar month containing the specified date.
This method fetches workday records for an entire month using SQL date functions to determine month boundaries. It provides efficient bulk access to workday data for monthly reporting, productivity analysis, and trend identification.
§Month Calculation
The method uses SQL strftime functions to extract year-month components
and match them against the target date’s month. This approach handles
month boundaries correctly across different year transitions.
§Result Processing
All workdays are loaded into memory and returned as a vector, providing convenient access for analysis operations. The results maintain chronological order for consistent processing.
§Arguments
date- Any date within the target month for workday retrieval
§Returns
Returns a vector of all workdays in the same month as the specified date, or an error if the database query or parsing fails.
§Example
use chrono::Local;
let mut workdays = Workdays::new()?;
let current_month = Local::now().date_naive();
let monthly_workdays = workdays.fetch_month(current_month)?;
println!("Found {} workdays this month", monthly_workdays.len());
for workday in monthly_workdays {
if let Some(end_time) = workday.end {
let duration = end_time - workday.start;
println!("Date: {}, Duration: {:?}", workday.date, duration);
}
}§Performance Considerations
- Loads all monthly workdays into memory simultaneously
- Efficient for typical monthly workday counts (20-30 records)
- May need optimization for very large historical datasets
- Consider pagination for bulk historical data processing
§Use Cases
- Monthly productivity reports
- Work pattern analysis and trend identification
- Timesheet generation and validation
- Historical work data export and backup
Sourcepub fn update_start(
&mut self,
date: NaiveDate,
new_start: NaiveDateTime,
) -> Result<()>
pub fn update_start( &mut self, date: NaiveDate, new_start: NaiveDateTime, ) -> Result<()>
Updates the start time of an existing workday to a specific timestamp.
This method provides manual adjustment capabilities for correcting automatic time tracking errors or implementing manual time entry scenarios. It modifies the start timestamp while preserving all other workday properties and relationships.
§Time Adjustment Use Cases
- Correcting automatic tracking start times that were recorded incorrectly
- Manual time entry for workdays that weren’t automatically tracked
- Adjusting for delayed system startup or application launch
- Retroactive time corrections based on external time records
§Data Validation
The method validates that the workday exists before attempting the update and returns an error if no matching record is found. This ensures referential integrity and provides clear error feedback.
§Arguments
date- Calendar date of the workday to modifynew_start- New start timestamp to apply to the workday
§Returns
Returns Ok(()) if the update succeeds, or an error if the workday
doesn’t exist or the database operation fails.
§Example
use chrono::{Local, NaiveDateTime};
let mut workdays = Workdays::new()?;
let today = Local::now().date_naive();
// Correct start time to 9:00 AM
let corrected_start = NaiveDateTime::parse_from_str(
&format!("{} 09:00:00", today.format("%Y-%m-%d")),
"%Y-%m-%d %H:%M:%S"
)?;
workdays.update_start(today, corrected_start)?;§Error Conditions
- No workday exists for the specified date
- Database constraint violations or connection failures
- Invalid timestamp format or timezone issues
Sourcepub fn update_end(
&mut self,
date: NaiveDate,
new_end: Option<NaiveDateTime>,
) -> Result<()>
pub fn update_end( &mut self, date: NaiveDate, new_end: Option<NaiveDateTime>, ) -> Result<()>
Updates the end time of an existing workday or clears it to mark as ongoing.
This method provides flexible end time management, supporting both specific timestamp updates and clearing end times to mark workdays as ongoing or incomplete. It enables comprehensive time adjustment and correction capabilities.
§Operation Modes
- Set End Time:
Some(timestamp)sets a specific completion time - Clear End Time:
Noneremoves the end time, marking as ongoing - Correction: Modify existing end times for accuracy improvements
§State Transitions
The method supports all valid workday state transitions:
- Completed → Ongoing (clear end time)
- Ongoing → Completed (set end time)
- Completed → Completed (adjust end time)
§Arguments
date- Calendar date of the workday to modifynew_end- New end timestamp (Some) or clear end time (None)
§Returns
Returns Ok(()) if the update succeeds, or an error if the workday
doesn’t exist or the database operation fails.
§Example
use chrono::{Local, NaiveDateTime};
let mut workdays = Workdays::new()?;
let today = Local::now().date_naive();
// Set specific end time
let end_time = NaiveDateTime::parse_from_str(
&format!("{} 17:30:00", today.format("%Y-%m-%d")),
"%Y-%m-%d %H:%M:%S"
)?;
workdays.update_end(today, Some(end_time))?;
// Clear end time (mark as ongoing)
workdays.update_end(today, None)?;§Data Consistency
The method ensures database consistency by validating workday existence and providing clear error feedback for failed operations. This maintains data integrity across time adjustment operations.