Compare commits

...

11 Commits

2
.gitignore vendored

@ -569,3 +569,5 @@ Migrations/
*.db
*.db-shm
*.db-wal

@ -26,7 +26,7 @@ public static class ActivityMapper
Minimum = activity.Minimum,
AverageTemperature = activity.AverageTemperature,
HasAutoPause = activity.HasAutoPause
});
}, (activityDto, activity) => activityDto.heartRates = activity.);
}
public static Activity ToModel(this ActivityDto activityDto)

@ -24,7 +24,8 @@ public static class UserMappeur
Weight = user.Weight,
DateOfBirth = user.DateOfBirth,
IsCoach = user.Role is Coach
});
},
(userDto, user) => userDto.Id = user.Id);
}
@ -45,7 +46,8 @@ public static class UserMappeur
DateOfBirth = userDto.DateOfBirth,
Role = userDto.IsCoach ? new Coach() : new Athlete()
});
},
(user, userDto) => user.Id = userDto.Id);
}
}

@ -211,8 +211,7 @@ namespace DbContextLib
modelBuilder.Entity<ActivityEntity>()
.HasMany(a => a.HeartRates)
.WithOne(h => h.Activity)
.HasForeignKey(h => h.ActivityId)
.IsRequired();
.HasForeignKey(h => h.ActivityId);
modelBuilder.Entity<DataSourceEntity>()
.HasMany(d => d.Activities)
@ -221,10 +220,10 @@ namespace DbContextLib
.IsRequired();
modelBuilder.Entity<DataSourceEntity>()
.HasMany(ds => ds.Activities)
.HasMany(ds => ds.Athletes)
.WithOne(at => at.DataSource)
.HasForeignKey(at => at.DataSourceId)
.IsRequired(false);
.IsRequired();
// modelBuilder.Entity<AthleteEntity>()
// .HasMany(fer => fer.Followers)

@ -7,15 +7,6 @@ namespace EFMappers;
public static class ActivityMapper
{
private static GenericMapper<Activity, ActivityEntity> _mapper = new GenericMapper<Activity, ActivityEntity>();
public static Activity? GetModel(ActivityEntity entity) =>
_mapper.GetT(entity);
public static ActivityEntity? GetEntity(Activity model) =>
_mapper.GetU(model);
public static void Add(Activity model, ActivityEntity entity)
{
var tuple = new Tuple<Activity, ActivityEntity>(model, entity);
_mapper.Add(model, entity);
}
// ! RESET
// ? Quand on fait appel au reset ?
// * Apres des saves changing ou rollback.
@ -40,9 +31,9 @@ public static class ActivityMapper
entity.Maximum,
entity.Minimum,
entity.AverageTemperature,
entity.HasAutoPause));
entity.HasAutoPause)
// ! regarder a ce que le model est bien les relation comme l'EF
// ), (activity, entity) => activity.Id = entity.IdActivity);
, (activity, entity) => activity.heartRates = entity.HeartRates.Select(hr => hr.ToModel()).ToList());
}
// dictionnaire;
@ -50,8 +41,8 @@ public static class ActivityMapper
public static ActivityEntity? ToEntity(this Activity model)
{
// return model.ToEntity();
return model.ToU(_mapper, activityEntity => new ActivityEntity
Func<Activity,ActivityEntity> create = activity => new ActivityEntity
{
IdActivity = model.Id,
Type = model.Type,
@ -67,14 +58,51 @@ public static class ActivityMapper
Minimum = model.Minimum,
AverageTemperature = model.AverageTemperature,
HasAutoPause = model.HasAutoPause
}
};
Action<Activity,ActivityEntity> link = (activity, entity) =>
{
entity.HeartRates =
// Juste faire un mappeur pour les heartRate et du coup du fait cette appel
// activity.heartRates.Select(hr => hr.ToEntity()).ToList();
activity.heartRates.Select(hr => new HeartRateEntity
{
IdHeartRate = hr.Id,
Altitude = hr.Altitude,
Time = hr.Time,
Temperature = hr.Temperature,
Bpm = hr.Bpm,
Longitude = hr.Longitude,
Latitude = hr.Latitude,
ActivityId = entity.IdActivity
}).ToList<HeartRateEntity>();
entity.DataSource = activity.DataSource
// entity.DataSource = activity.DataSource.ToEntity();
// entity.Athlete = activity.Athlete.ToEntity();
};
// return model.ToEntity();
return model.ToU(_mapper, create, );
// ! regarder a ce que le model est bien les relation comme l'EF
);
/*(activity, entity) => entity.HeartRates = activity.heartRates.Select(hr => new HeartRateEntity
{
IdHeartRate = hr.Id,
Altitude = hr.Altitude,
Time = hr.Time,
Temperature = hr.Temperature,
Bpm = hr.Bpm,
Longitude = hr.Longitude,
Latitude = hr.Latitude,
ActivityId = entity.IdActivity
}).ToList<HeartRateEntity>()*/
}
public static IEnumerable<Activity> ToModels(this IEnumerable<ActivityEntity> entities)
public static IEnumerable<Activity?> ToModels(this IEnumerable<ActivityEntity> entities)
=> entities.Select(a => a.ToModel());
public static IEnumerable<ActivityEntity> ToEntities(this IEnumerable<Activity> models)
public static IEnumerable<ActivityEntity?> ToEntities(this IEnumerable<Activity> models)
=> models.Select(a => a.ToEntity());
}

@ -0,0 +1,61 @@
using Entities;
using Model;
using Shared;
namespace EFMappers;
public static class HeartRateMapper
{
private static GenericMapper<HeartRate, HeartRateEntity> _mapper = new GenericMapper<HeartRate, HeartRateEntity>();
// ! RESET
// ? Quand on fait appel au reset ?
// * Apres des saves changing ou rollback.
public static void Reset()
{
_mapper.Reset();
}
public static HeartRate ToModel(this HeartRateEntity entity)
{
// return entity.ToModel();
return entity.ToT(_mapper, heartRate => new HeartRate (
entity.IdHeartRate,
entity.Altitude,
entity.Time,
entity.Temperature,
entity.Bpm,
entity.Longitude,
entity.Latitude,
entity.ActivityId
)
// ! regarder a ce que le model est bien les relation comme l'EF
, (heartRate, entity) => heartRate.ActivityId = entity.ActivityId);
}
// dictionnaire;
public static HeartRateEntity? ToEntity(this HeartRate model)
{
// return model.ToEntity();
return model.ToU(_mapper, heartRateEntity => new HeartRateEntity
{
IdHeartRate = model.Id,
Altitude = model.Altitude,
Time = model.Time,
Temperature = model.Temperature,
Bpm = model.Bpm,
Longitude = model.Longitude,
Latitude = model.Latitude,
ActivityId = model.ActivityId
}
, (heartRate, entity) => entity.ActivityId = heartRate.ActivityId
// ! regarder a ce que le model est bien les relation comme l'EF
);
}
public static IEnumerable<HeartRate?> ToModels(this IEnumerable<HeartRateEntity> entities)
=> entities.Select(hr => hr.ToModel());
public static IEnumerable<HeartRateEntity?> ToEntities(this IEnumerable<HeartRate> models)
=> models.Select(hr => hr.ToEntity());
}

@ -1,5 +1,7 @@
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER $APP_UID
RUN echo $APP_UID
RUN whoami
WORKDIR /app
EXPOSE 8080
EXPOSE 8081
@ -36,6 +38,7 @@ RUN dotnet build "HeartTrackAPI.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "HeartTrackAPI.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .

@ -32,7 +32,34 @@ public class Activity
public float AverageTemperature { get; set; }
public bool HasAutoPause { get; set; }
public HashSet<User> Users { get; private set; } = new HashSet<User>();
// ! pk ??! pas dans le model
// public HashSet<User> Users { get; private set; } = new HashSet<User>();
public List<HeartRate> heartRates { get; set; } = new List<HeartRate>();
public User User { get; set; }
public DataSource DataSource { get; set; }
public Activity(int idActivity ,string? type, DateTime date, DateTime startTime, DateTime endTime,
int effort, float variability, float variance, float standardDeviation,
float average, int maximum, int minimum, float averageTemperature, bool hasAutoPause, List<HeartRate> heartRates, User user, DataSource dataSource)
{
Id = idActivity;
Type = type;
Date = date;
StartTime = startTime;
EndTime = endTime;
Effort = effort;
Variability = variability;
Variance = variance;
StandardDeviation = standardDeviation;
Average = average;
Maximum = maximum;
Minimum = minimum;
AverageTemperature = averageTemperature;
HasAutoPause = hasAutoPause;
this.heartRates = heartRates;
User = user;
DataSource = dataSource;
}
public Activity(int idActivity ,string? type, DateTime date, DateTime startTime, DateTime endTime,
int effort, float variability, float variance, float standardDeviation,
float average, int maximum, int minimum, float averageTemperature, bool hasAutoPause)
@ -51,6 +78,7 @@ public class Activity
Minimum = minimum;
AverageTemperature = averageTemperature;
HasAutoPause = hasAutoPause;
this.heartRates = heartRates;
}
public Activity(){}

@ -0,0 +1,34 @@
using Model;
public class DataSource
{
public int Id { get; set; }
public string Type { get; set; }
public string Model { get; set; }
public float Precision { get; set; }
public ICollection<Activity> Activities { get; set; } = new List<Activity>();
public ICollection<Athlete> Athletes { get; set; } = new List<Athlete>();
public DataSource(int id, string type, string model, float precision, ICollection<Activity> activities, ICollection<Athlete> athletes)
{
Id = id;
Type = type;
Model = model;
Precision = precision;
Activities = activities;
Athletes = athletes;
}
public DataSource(){}
public DataSource(int id, string type, string model, float precision)
{
Id = id;
Type = type;
Model = model;
Precision = precision;
}
public override string ToString()
{
return $"DataSource #{Id}: {Type} {Model} with a precision of {Precision}";
}
}

@ -0,0 +1,30 @@
namespace Model;
public class HeartRate {
public int Id { get; set; }
public double Altitude { get; set; }
public TimeOnly Time { get; set; }
public float Temperature { get; set; }
public int Bpm { get; set; }
public float Longitude { get; set; }
public float Latitude { get; set; }
public int ActivityId { get; set; }
public HeartRate(int id, double altitude, TimeOnly time, float temperature, int bpm, float longitude, float latitude, int activityId)
{
Id = id;
Altitude = altitude;
Time = time;
Temperature = temperature;
Bpm = bpm;
Longitude = longitude;
Latitude = latitude;
ActivityId = activityId;
}
public HeartRate(){}
public override string ToString()
{
return $"HeartRate #{Id}: {Bpm} bpm at {Time:HH:mm:ss} with a temperature of {Temperature}°C" +
$" and an altitude of {Altitude}m at {Longitude}°E and {Latitude}°N";
}
}

@ -17,6 +17,8 @@ public class User
protected List<Notification> Notifications { get; set; } = new List<Notification>();
protected List<Activity> Activities { get; set; } = new List<Activity>();
public List<User> Users { get; set; } = new List<User>();
public User( string username, string profilePicture, string nom, string prenom, string email, string motDePasse, string sexe, float taille, float poids, DateTime dateNaissance, Role role)

@ -53,7 +53,7 @@ public partial class DbDataManager : IDataManager
try
{
_logger.LogInformation("Adding new activity");
var addedActivity = (await _dataManager.DbContext.AddItem(activity.ToEntity())).ToModel();
var addedActivity = (await _dataManager.DbContext.AddItem(activity.ToEntity()))!.ToModel();
if (addedActivity != null)
_logger.LogInformation($"Added activity with ID {addedActivity.Id}");
else
@ -71,14 +71,32 @@ public partial class DbDataManager : IDataManager
{
try
{
return activity;
// _logger.LogInformation($"Updating activity with ID {id}");
// var updatedActivity = await _dataManager.DbContext.ActivitiesSet.UpdateItem<ActivityEntity>(_dataManager.DbContext,(await GetActivityByIdAsync(id)).ToEntity(), activity.ToEntity());
// if (updatedActivity != null)
// _logger.LogInformation($"Updated activity with ID {id}");
// else
// _logger.LogError($"Failed to update activity with ID {id}");
// return await Task.FromResult(updatedActivity.ToModel());
// return activity;
_logger.LogInformation($"Updating activity with ID {id}");
var updatedActivity = await _dataManager.DbContext.UpdateItem<Activity, ActivityEntity>(id, activity, (activity, entity) =>
{
entity.Type = activity.Type;
entity.Date = DateOnly.FromDateTime(activity.Date);
entity.StartTime = TimeOnly.FromDateTime(activity.StartTime);
entity.EndTime = TimeOnly.FromDateTime(activity.EndTime);
entity.EffortFelt = activity.Effort;
entity.Variability = activity.Variability;
entity.Variance = activity.Variance;
entity.StandardDeviation = activity.StandardDeviation;
entity.Average = activity.Average;
entity.Maximum = activity.Maximum;
entity.Minimum = activity.Minimum;
entity.AverageTemperature = activity.AverageTemperature;
entity.HasAutoPause = activity.HasAutoPause;
});
if (updatedActivity != null) {
_logger.LogInformation($"Updated activity with ID {id}");
return await Task.FromResult(updatedActivity!.ToModel());
}
else {
_logger.LogError($"Failed to update activity with ID {id}");
return null;
}
}
catch (Exception ex)
{

@ -27,7 +27,8 @@ public partial class DbDataManager: IDataManager
public DbDataManager(string dbPlatformPath)
: this(new HeartTrackContext(dbPlatformPath))
{
Console.WriteLine($"Database created String: {DbContext.Database.EnsureCreated()}"); }
Console.WriteLine($"Database created String: {DbContext.Database.EnsureCreated()}");
}
public DbDataManager()

@ -7,18 +7,71 @@ namespace Model2Entities;
public static class Extensions
{
internal static async Task<T?> AddItem<T>(this HeartTrackContext context, T? item) where T :class
// internal static async Task<T?> AddItem<T>(this HeartTrackContext context, T? item) where T :class
// {
// if(item == null || context.Set<T>().Contains(item))
// {
// return await Task.FromResult<T?>(null);
// }
// var entry = context.Set<T>().Add(item);
// try {
// await context.SaveChangesAsync();
// }
// catch (Exception ex)
// {
// Console.WriteLine($"{ex.Message}, {ex.InnerException}, {ex.StackTrace}");
// }
// return await Task.FromResult<T?>(entry.Entity);
// }
internal static async Task<T?> AddItem<T>(this HeartTrackContext context, T? item) where T : class
{
if(item == null || context.Set<T>().Contains(item))
{
return await Task.FromResult<T?>(null);
}
var entry = context.Set<T>().Add(item);
await context.SaveChangesAsync();
// Si l'élément est une activité, nous devons gérer les fréquences cardiaques associées
if (item is Activity activity)
{
foreach (var heartRate in activity.heartRates)
{
// Ajouter chaque fréquence cardiaque associée à l'activité
context.Set<HeartRate>().Add(heartRate);
}
}
try {
await context.SaveChangesAsync();
}
catch (Exception ex)
{
Console.WriteLine($"{ex.Message}, {ex.InnerException}, {ex.StackTrace}");
}
return await Task.FromResult<T?>(entry.Entity);
}
// public static async Task<U?> UpdateItem<T, U>(this HeartTrackContext context, int? id, T? newItem, Action<T, U> updateAction) where T : class where U: class
// {
// var existingT = await context.Set<U>().FindAsync(id);
// if (existingT != null && newItem != null)
// {
// // Appliquer les mises à jour sur l'objet existant en utilisant l'action passée en paramètre
// updateAction(newItem, existingT);
// // Marquer l'objet comme modifié dans le contexte
// context.Update(existingT);
// // Enregistrer les modifications dans la base de données
// await context.SaveChangesAsync();
// return existingT;
// }
// return default(U);
// }
internal static async Task<bool> DeleteItem<T>(this HeartTrackContext context, int? id) where T:class
{
var item = await context.Set<T>().FindAsync(id);
@ -28,21 +81,52 @@ public static class Extensions
return await Task.FromResult(true);
}
internal static async Task<T?> UpdateItem<T>(this IList<T> collection, T? oldItem, T? newItem) where T : class
// ! 1
// internal static async Task<T?> UpdateItem<T>(this HeartTrackContext context, int? id, T? newItem) where T : class
// {
// var existingT = await context.Set<T>().FindAsync(id);
// if (existingT != null)
// {
// context.Entry(existingT).CurrentValues.SetValues(newItem!);
// context.Update(existingT);
// // existingT = func(newItem!);
// await context.SaveChangesAsync();
// }
// return existingT;
// // if(oldItem == null || newItem == null) return default(T);
// // if(!collection.Contains(oldItem))
// // {
// // return default(T);
// // }
// // collection.Remove(oldItem!);
// // await collection.AddItem(newItem!);
// // return newItem;
// // return await Task.FromResult<T?>(default(T));
// }
// ! 2
public static async Task<U?> UpdateItem<T, U>(this HeartTrackContext context, int? id, T? newItem, Action<T, U> updateAction) where T : class where U: class
{
// if(oldItem == null || newItem == null) return default(T);
var existingT = await context.Set<U>().FindAsync(id);
if (existingT != null && newItem != null)
{
// Appliquer les mises à jour sur l'objet existant en utilisant l'action passée en paramètre
updateAction(newItem, existingT);
// if(!collection.Contains(oldItem))
// {
// return default(T);
// }
// Marquer l'objet comme modifié dans le contexte
context.Update(existingT);
// collection.Remove(oldItem!);
// await collection.AddItem(newItem!);
// return newItem;
return await Task.FromResult<T?>(default(T));
// Enregistrer les modifications dans la base de données
await context.SaveChangesAsync();
return existingT;
}
return default(U);
}
public static IEnumerable<T> GetItemsWithFilterAndOrdering<T>(this IEnumerable<T> list, Func<T, bool> filter, int index, int count, Enum? orderCriterium, bool descending = false ) where T : class
{
var filteredList = list.Where(filter);

@ -2,7 +2,7 @@ namespace Shared;
public static class Extensions
{
public static U ToU<T, U>(this T t, GenericMapper<T, U> mapper, Func<T, U> func) where U :class where T :class
public static U ToU<T, U>(this T t, GenericMapper<T, U> mapper, Func<T, U> func, Action<T, U> action) where U :class where T :class
{
var u = mapper.GetU(t);
if (u != null) {
@ -10,11 +10,11 @@ public static class Extensions
}
u = func(t);
mapper.Add(t, u);
// action(t, u);
action(t, u);
return u;
}
// , Action<T, U> action
public static T ToT<T,U>(this U u, GenericMapper<T, U> mapper, Func<U, T> func) where U :class where T :class
public static T ToT<T,U>(this U u, GenericMapper<T, U> mapper, Func<U, T> func, Action<T, U> action) where U :class where T :class
{
var t = mapper.GetT(u);
if (t != null) {
@ -22,7 +22,7 @@ public static class Extensions
}
t = func(u);
mapper.Add(t, u);
// action(t, u);
action(t, u);
return t;
}
}

@ -30,7 +30,7 @@ namespace Model2Entities
// Test de la méthode GetActivityByIdAsync
Console.WriteLine("Testing GetActivityByIdAsync method...");
var activityById = await activityRepository.GetActivityByIdAsync(2);
var activityById = await activityRepository.GetActivityByIdAsync(3);
if (activityById != null)
{
Console.WriteLine($"Activity found: ID: {activityById.Id}, Name: {activityById.Type}, Date: {activityById.Date}, Start Time: {activityById.StartTime}, End Time: {activityById.EndTime}");
@ -41,9 +41,9 @@ namespace Model2Entities
}
Console.WriteLine();
// // Test de la méthode AddActivity
// Test de la méthode AddActivity
Console.WriteLine("Testing AddActivity method...");
var newActivity = new Activity(10, "New Activity", new DateTime(2021, 10, 10), new DateTime(10, 10, 10, 10, 10, 10), new DateTime(10, 10, 10, 12, 12, 12), 5, 5, 5, 5, 5, 5, 5, 5, false);
var newActivity = new Activity(10, "New Activity", new DateTime(2021, 10, 10), new DateTime(10, 10, 10, 10, 10, 10), new DateTime(10, 10, 10, 12, 12, 12), 5, 5, 5, 5, 5, 5, 5, 5, false, new List<HeartRate>(new HeartRate[] { new HeartRate(10, 10D, new TimeOnly(10, 10, 10), 10f, 10, 10f, 10f, 10) }));
var addedActivity = await activityRepository.AddActivity(newActivity);
if (addedActivity != null)
{
@ -55,22 +55,22 @@ namespace Model2Entities
}
Console.WriteLine();
// // Test de la méthode UpdateActivity
// Console.WriteLine("Testing UpdateActivity method...");
// var updatedActivity = await activityRepository.UpdateActivity(6, new Activity { Id = 6, Name = "Updated Activity" });
// if (updatedActivity != null)
// {
// Console.WriteLine($"Activity updated successfully: ID: {updatedActivity.Id}, Name: {updatedActivity.Name}");
// }
// else
// {
// Console.WriteLine("Failed to update activity.");
// }
// Console.WriteLine();
// Test de la méthode UpdateActivity
Console.WriteLine("Testing UpdateActivity method...");
var updatedActivity = await activityRepository.UpdateActivity(11, new Activity(10, "Updated Activity", new DateTime(2021, 10, 10), new DateTime(10, 10, 10, 10, 10, 10), new DateTime(10, 10, 10, 12, 12, 12), 5, 5, 5, 5, 5, 5, 5, 5, false, new List<HeartRate>(new HeartRate[] { new HeartRate(10, 10D, new TimeOnly(10, 10, 10), 10f, 10, 10f, 10f, 10) })));
if (updatedActivity != null)
{
Console.WriteLine($"Activity updated successfully: ID: {updatedActivity.Id}, Name: {updatedActivity.Type}, Date: {updatedActivity.Date}, Start Time: {updatedActivity.StartTime}, End Time: {updatedActivity.EndTime}");
}
else
{
Console.WriteLine("Failed to update activity.");
}
Console.WriteLine();
// Test de la méthode DeleteActivity
Console.WriteLine("Testing DeleteActivity method...");
var isDeleted = await activityRepository.DeleteActivity(1);
var isDeleted = await activityRepository.DeleteActivity(2);
if (isDeleted)
{
Console.WriteLine("Activity deleted successfully.");
@ -78,6 +78,7 @@ namespace Model2Entities
{
Console.WriteLine("Failed to delete activity.");
}
Console.WriteLine();
// Test de la méthode GetNbItems
Console.WriteLine("Testing GetNbItems method...");

Loading…
Cancel
Save