Dear all,
for the next release after 3.6, I would like to contribute to
https://github.com/GoldenCheetah/GoldenCheetah/issues/411 (Feature request - Favorite workouts).
Based on the current TrainDB, I have a prototype for filtering workouts (see attached gif) that proved useful to me and could serve as a starting point for this feature request.
Since the trainDB is global to all athletes of a Golden Cheetah instance, the datamodel of the TrainDB has to be changed for #411.
My plan to implement #411 is as follows:
1. Refactor the TrainDB (see proposal below)
2. Implement a information widget for the currently selected workout
3. Implement a rating-widget (1-n stars) within the information widget
4. Implement a filter for workouts
5. Implement a migration from TrainDB schema version 1 to version 2
TrainDB: Proposed datamodel```mermaid
erDiagram
version {
text table_name PK "Name of the table"
integer schema_version "Version of the table"
integer creation_date "Creation date of the table"
}
video {
text filepath PK "Path of the video-file, relative to the TrainDB"
integer creation_date "Timestamp when this video was imported"
text displayname "Name of this video, this is shown to the user"
}
videosync {
text filepath PK "Path of the videosync-file, relative to the TrainDB"
integer creation_date "Timestamp when this videosync was imported"
text source "Origin of this videosync"
text displayname "Name of this videosync, this is shown to the user"
}
workout {
text filepath PK "Path of the workout-file, relative to the TrainDB"
text type "Type of the workout (code|slp|erg)"
integer creation_date "Timestamp when this workout was imported"
text source "Origin of this workout"
text source_id "Id of this workout as defined by the source (if available)"
text displayname "Name of this workout, this is shown to the user"
text description "Additional description of this workout"
text erg_subtype "Subtype if the workout is of type erg (abs|rel)"
integer erg_duration "Duration of this workout"
integer erg_rel_min_power "Minimum power of this workout [% CP]"
integer erg_rel_max_power "Maximum power of this workout [% CP]"
integer erg_rel_avg_power "Average power of this workout [% CP]"
integer erg_rel_dominant_zone "Dominant power zone of this workout (1-7)"
real erg_rel_duration_z1 "Duration in power zone 1 [% Duration]"
real erg_rel_duration_z2 "Duration in power zone 2 [% Duration]"
real erg_rel_duration_z3 "Duration in power zone 3 [% Duration]"
real erg_rel_duration_z4 "Duration in power zone 4 [% Duration]"
real erg_rel_duration_z5 "Duration in power zone 5 [% Duration]"
real erg_rel_duration_z6 "Duration in power zone 6 [% Duration]"
real erg_rel_duration_z7 "Duration in power zone 7 [% Duration]"
real erg_bikestress "Bikestress of this workout"
real erg_if "IF of this workout"
integer erg_abs_min_power "Minimum power of this workout [Watt]"
integer erg_abs_max_power "Maximum power of this workout [Watt]"
integer erg_abs_avg_power "Average power of this workout [Watt]"
real slp_distance "Distance [km]"
integer slp_elevation "Elevation Gain [m]"
real slp_avg_grade "Average Grade [%]"
}
workout_athleteinfo {
integer workout_filepath FK "<PK> References workout.filepath"
text athlete_id PK "<PK> ID of the athlete as given by Golden Cheetah (see <athleteDir>/config/athlete-general.ini/[General]/Id)"
integer rating "User rating of this workout (1-n, NULL means unrated)"
datetime last_run "Last execution of this workout by this user"
}
workout ||--o{ workout_athleteinfo : filepath
```
Attributes prefixed with one of the types (allowed values: `code`, `slp`, `erg`) are only available when the value of attribute `type` is matching. If the type is `erg`, the attributes with extended prefix as given in `erg_subtype` (allowed values: `abs`, `rel`) are also relevant.
All table names are in singular, resulting in foreign keys named *tablename_key* (e.g. *workout_filepath*). Using plural would result in awkward foreign key names like *workout**s**_filepath*. Additionally this change to the status quo helps for parallel existence of both versions (current and future tables) and therefore ease the migration. The table *version* is already in singular and therefore remains as is.
Timestamps are always stored as *unixepoch* in fields of type *integer*.
1. Provide all data required for finding workouts
2. Support athlete-specific data like ratings - while keeping the global approach of the TrainDB
3. Reduce dependencies from the TrainDB-class to other code within Golden Cheetah as much as possible
1. To achieve this I moved most datafields from ErgFile / VideoSyncFile to a new base-class (including getters and setters)
2. Increased typesafety by introducing enum-classes
4. Separate file- and display-name
Feedback, concerns, additional usecases are welcome!
Since this is my first "big" attempt to contribute to Golden Cheetah, I would be grateful for hints how to proceed with this topic.
Regards
Joachim