aboutsummaryrefslogtreecommitdiff
path: root/Timeline/Services/UserDetailService.cs
blob: 0bb745f3a3ac3f3378c40f1909c77b3710a21555 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading.Tasks;
using Timeline.Entities;
using Timeline.Models;

namespace Timeline.Services
{
    public interface IUserDetailService
    {
        /// <summary>
        /// Get the detail of user.
        /// </summary>
        /// <param name="username">The username to get user detail of.</param>
        /// <returns>The user detail.</returns>
        /// <exception cref="ArgumentException">Thrown if <paramref name="username"/> is null or empty.</exception>
        /// <exception cref="UserNotExistException">Thrown if user doesn't exist.</exception>
        Task<UserDetail> GetUserDetail(string username);

        /// <summary>
        /// Update the detail of user. This function does not do data check.
        /// </summary>
        /// <param name="username">The username to get user detail of.</param>
        /// <param name="detail">The detail to update. Can't be null. Any null member means not set.</param>
        /// <exception cref="ArgumentException">Thrown if <paramref name="username"/> is null or empty or <paramref name="detail"/> is null.</exception>
        /// <exception cref="UserNotExistException">Thrown if user doesn't exist.</exception>
        Task UpdateUserDetail(string username, UserDetail detail);
    }

    public class UserDetailService : IUserDetailService
    {
        private readonly ILogger<UserDetailService> _logger;

        private readonly DatabaseContext _databaseContext;

        public UserDetailService(ILogger<UserDetailService> logger, DatabaseContext databaseContext)
        {
            _logger = logger;
            _databaseContext = databaseContext;
        }

        // Check the existence of user detail entry
        private async Task<UserDetailEntity> CheckAndInit(long userId)
        {
            var detail = await _databaseContext.UserDetails.Where(e => e.UserId == userId).SingleOrDefaultAsync();
            if (detail == null)
            {
                detail = new UserDetailEntity()
                {
                    UserId = userId
                };
                _databaseContext.UserDetails.Add(detail);
                await _databaseContext.SaveChangesAsync();
                _logger.LogInformation("An entity is created in user_details.");
            }
            return detail;
        }

        public async Task<UserDetail> GetUserDetail(string username)
        {
            var userId = await DatabaseExtensions.CheckAndGetUser(_databaseContext.Users, username);
            var detailEntity = await CheckAndInit(userId);
            return UserDetail.From(detailEntity);
        }

        public async Task UpdateUserDetail(string username, UserDetail detail)
        {
            if (detail == null)
                throw new ArgumentNullException(nameof(detail));

            var userId = await DatabaseExtensions.CheckAndGetUser(_databaseContext.Users, username);
            var detailEntity = await CheckAndInit(userId);

            if (detail.QQ != null)
                detailEntity.QQ = detail.QQ;

            if (detail.EMail != null)
                detailEntity.EMail = detail.EMail;

            if (detail.PhoneNumber != null)
                detailEntity.PhoneNumber = detail.PhoneNumber;

            if (detail.Description != null)
                detailEntity.Description = detail.Description;

            await _databaseContext.SaveChangesAsync();
            _logger.LogInformation("An entity is updated in user_details.");
        }
    }

    public static class UserDetailServiceCollectionExtensions
    {
        public static void AddUserDetailService(this IServiceCollection services)
        {
            services.AddScoped<IUserDetailService, UserDetailService>();
        }
    }
}