using Dapper; using System.Data; using Yuna.Website.Server.Model; namespace Yuna.Website.Server.Storage.Repositories.Device { public class DeviceRepository : IDeviceRepository { private readonly DapperContext _context; public DeviceRepository(DapperContext context) { _context = context; } public async Task AddProps(IReadOnlyList props, long deviceId) { var query = $@"INSERT INTO ""Yuna_Props_In_Devices"" (""PropId"", ""DeviceId"") VALUES {string.Join(", ", props.Select(prop => $"({prop.Id}, {deviceId})"))}"; await _context.Connection.ExecuteAsync(query); } public async Task Create(Model.Device device) { var query = $@"INSERT INTO ""Yuna_Devices"" (""Name"", ""Description"", ""DeviceUrl"", ""UserId"") VALUES ('{device.Name}', '{device.Description}', '{device.DeviceUrl}', {device.UserId}) RETURNING *"; var result = await _context.Connection.QuerySingleAsync(query, device); return result; } public async Task Delete(long id) { var query = $@" UPDATE ""Yuna_Devices"" SET ""IsDeleted"" = TRUE WHERE ""Id"" = {id} AND NOT ""IsDeleted"" returning * "; return await _context.Connection.QuerySingleOrDefaultAsync(query); } public async Task GetById(long id) { var query = $@"SELECT d.""Id"" as {nameof(Model.Device.Id)}, d.""Name"" as {nameof(Model.Device.Name)}, d.""Description"" as {nameof(Model.Device.Description)}, d.""DeviceUrl"" as {nameof(Model.Device.DeviceUrl)}, d.""UserId"" as {nameof(Model.Device.UserId)}, p.""Id"" as {nameof(Model.Prop.Id)}, p.""Name"" as {nameof(Model.Prop.Name)}, p.""JsonValueName"" as {nameof(Model.Prop.JsonValueName)}, p.""MeasureName"" as {nameof(Model.Prop.MeasureName)}, p.""Type"" as {nameof(Model.Prop.Type)} FROM ""Yuna_Devices"" d LEFT JOIN ""Yuna_Props_In_Devices"" pd ON d.""Id"" = pd.""DeviceId"" LEFT JOIN ""Yuna_Props"" p ON pd.""PropId"" = p.""Id"" WHERE d.""Id"" = {id} AND NOT d.""IsDeleted"""; var deviceDict = new Dictionary(); var result = await _context.Connection.QueryAsync( query, (device, prop) => { if (!deviceDict.TryGetValue(device.Id, out var currentDevice)) { currentDevice = device; currentDevice.Props = new List(); deviceDict.Add(currentDevice.Id, currentDevice); } currentDevice.Props.Add(prop); return currentDevice; }, splitOn: $"{nameof(Model.Prop.Id)}" // Specify the column to split the results on ); return result.FirstOrDefault(); } public async Task> GetList() { var query = $@"SELECT d.""Id"" as {nameof(Model.Device.Id)}, d.""Name"" as {nameof(Model.Device.Name)}, d.""Description"" as {nameof(Model.Device.Description)}, d.""DeviceUrl"" as {nameof(Model.Device.DeviceUrl)}, d.""UserId"" as {nameof(Model.Device.UserId)}, p.""Id"" as {nameof(Model.Prop.Id)}, p.""Name"" as {nameof(Model.Prop.Name)}, p.""JsonValueName"" as {nameof(Model.Prop.JsonValueName)}, p.""MeasureName"" as {nameof(Model.Prop.MeasureName)}, p.""Type"" as {nameof(Model.Prop.Type)} FROM ""Yuna_Devices"" d LEFT JOIN ""Yuna_Props_In_Devices"" pd ON d.""Id"" = pd.""DeviceId"" LEFT JOIN ""Yuna_Props"" p ON pd.""PropId"" = p.""Id"" WHERE NOT d.""IsDeleted"" ORDER BY d.""Id"""; var deviceDict = new Dictionary(); var result = await _context.Connection.QueryAsync( query, (device, prop) => { if (!deviceDict.TryGetValue(device.Id, out var currentDevice)) { currentDevice = device; currentDevice.Props = new List(); deviceDict.Add(currentDevice.Id, currentDevice); } if(prop is not null) currentDevice.Props.Add(prop); return currentDevice; }, splitOn: $"{nameof(Model.Prop.Id)}" // Specify the column to split the results on ); return result.Distinct().ToList(); } public async Task> GetList(long userId) { var query = $@"SELECT d.""Id"" as {nameof(Model.Device.Id)}, d.""Name"" as {nameof(Model.Device.Name)}, d.""Description"" as {nameof(Model.Device.Description)}, d.""DeviceUrl"" as {nameof(Model.Device.DeviceUrl)}, d.""UserId"" as {nameof(Model.Device.UserId)}, p.""Id"" as {nameof(Model.Prop.Id)}, p.""Name"" as {nameof(Model.Prop.Name)}, p.""JsonValueName"" as {nameof(Model.Prop.JsonValueName)}, p.""MeasureName"" as {nameof(Model.Prop.MeasureName)}, p.""Type"" as {nameof(Model.Prop.Type)} FROM ""Yuna_Devices"" d LEFT JOIN ""Yuna_Props_In_Devices"" pd ON d.""Id"" = pd.""DeviceId"" LEFT JOIN ""Yuna_Props"" p ON pd.""PropId"" = p.""Id"" WHERE d.""UserId"" = {userId} AND NOT d.""IsDeleted"" ORDER BY d.""Id"""; var deviceDict = new Dictionary(); var result = await _context.Connection.QueryAsync( query, (device, prop) => { if (!deviceDict.TryGetValue(device.Id, out var currentDevice)) { currentDevice = device; currentDevice.Props = new List(); deviceDict.Add(currentDevice.Id, currentDevice); } if (prop is not null) currentDevice.Props.Add(prop); return currentDevice; }, splitOn: $"{nameof(Model.Prop.Id)}" // Specify the column to split the results on ); return result.Distinct().ToList(); } public async Task Update(Model.Device device) { var query = $@" UPDATE public.""Yuna_Devices"" SET ""Name"" = @Name, ""Description"" = @Description, ""DeviceUrl"" = @DeviceUrl, ""UserId"" = @UserId WHERE ""Id"" = @Id AND NOT ""IsDeleted"" returning * "; return await _context.Connection.QuerySingleOrDefaultAsync(query, device); } } }