Skip to content

Commit ecac2a3

Browse files
authored
Merge pull request #18 from ZenonEl/refactor/db-schema-cleanup
refactor(db): merge MutedContacts into Contacts, add indexes
2 parents 0b0c234 + 6b8a686 commit ecac2a3

9 files changed

Lines changed: 67 additions & 103 deletions

File tree

Database/BaseDBMigration.cs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,11 @@ CREATE TABLE Contacts (
4545
UserId INTEGER NOT NULL,
4646
ContactId INTEGER NOT NULL,
4747
status TEXT,
48+
MutedUntil TEXT,
4849
PRIMARY KEY (UserId, ContactId)
4950
)");
5051
}
5152

52-
// MutedContacts
53-
if (!Schema.Table("MutedContacts").Exists())
54-
{
55-
Create.Table("MutedContacts")
56-
.WithColumn("MutedId").AsInt32().PrimaryKey().Identity()
57-
.WithColumn("MutedByUserId").AsInt32().NotNullable()
58-
.WithColumn("MutedContactId").AsInt32().NotNullable()
59-
.WithColumn("MuteDate").AsDateTime().NotNullable()
60-
.WithColumn("ExpirationDate").AsDateTime().Nullable()
61-
.WithColumn("IsActive").AsBoolean().NotNullable().WithDefaultValue(true);
62-
}
63-
6453
// UsersGroups
6554
if (!Schema.Table("UsersGroups").Exists())
6655
{

Database/Interfaces/IContactRepository.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ namespace TelegramMediaRelayBot.Database.Interfaces;
1515
public interface IContactAdder
1616
{
1717
void AddContact(long telegramID, string link);
18-
bool AddMutedContact(int mutedByUserId, int mutedContactId, DateTime? expirationDate = null, DateTime muteDate = default);
18+
bool MuteContact(int userId, int contactId, DateTime? mutedUntil = null);
1919
}
2020

2121
public interface IContactRemover
2222
{
23-
void RemoveMutedContact(int userId, int contactId);
23+
bool UnmuteContact(int userId, int contactId);
2424
bool RemoveContactByStatus(int senderTelegramID, int accepterTelegramID, string? status = null);
2525
bool RemoveUsersFromContacts(int userId, List<int> contactIds);
2626
bool RemoveAllContactsExcept(int userId, List<int> excludeIds);
@@ -36,7 +36,7 @@ public interface IContactGetter
3636
{
3737
Task<List<long>> GetAllContactUserTGIds(int userId);
3838
Task<List<int>> GetAllContactUserIds(int userId);
39-
string GetActiveMuteTimeByContactID(int contactID);
39+
DateTime? GetMutedUntil(int userId, int contactId);
4040
int GetContactIDByLink(string link);
4141
int GetContactByTelegramID(long telegramID);
4242
}

Database/Interfaces/IUserRepository.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ public interface IUserRepository
1515
{
1616
bool CheckUserExists(long telegramId);
1717
void AddUser(string name, long telegramID, bool user);
18-
void UnMuteUserByMuteId(int userId);
1918
bool ReCreateUserSelfLink(int userId);
2019
}
2120

@@ -26,7 +25,7 @@ public interface IUserGetter
2625
int GetUserIDbyTelegramID(long telegramID);
2726
string GetUserNameByTelegramID(long telegramID);
2827
List<long> GetUsersIdForMuteContactId(int contactId);
29-
List<int> GetExpiredUsersMutes();
28+
Task<List<(int UserId, int ContactId)>> GetExpiredMutesAsync();
3029
long GetUserTelegramIdByLink(string link);
3130
string GetUserSelfLink(long telegramId);
3231
Task<int> GetAllUsersCount();

Database/Repositories/SqLite/Contacts.cs

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -44,34 +44,25 @@ INSERT INTO Contacts (UserId, ContactId, Status)
4444
}
4545
}
4646

47-
public bool AddMutedContact(int mutedByUserId, int mutedContactId, DateTime? expirationDate = null, DateTime muteDate = default)
47+
public bool MuteContact(int userId, int contactId, DateTime? mutedUntil = null)
4848
{
49-
if (muteDate == default)
50-
{
51-
muteDate = DateTime.Now;
52-
}
53-
5449
const string query = @"
55-
INSERT INTO MutedContacts (MutedByUserId, MutedContactId, MuteDate, ExpirationDate)
56-
VALUES (@mutedByUserId, @mutedContactId, @muteDate, @expirationDate)
57-
ON CONFLICT(MutedByUserId, MutedContactId)
58-
DO UPDATE SET
59-
MuteDate = @muteDate,
60-
ExpirationDate = @expirationDate,
61-
IsActive = 1";
50+
UPDATE Contacts
51+
SET MutedUntil = @mutedUntil
52+
WHERE UserId = @userId AND ContactId = @contactId";
6253

6354
using (var connection = new SqliteConnection(_connectionString))
6455
{
6556
try
6657
{
67-
connection.Execute(query, new
58+
string? mutedUntilStr = mutedUntil?.ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss");
59+
int affected = connection.Execute(query, new
6860
{
69-
mutedByUserId,
70-
mutedContactId,
71-
muteDate,
72-
expirationDate
61+
userId,
62+
contactId,
63+
mutedUntil = mutedUntilStr
7364
});
74-
return true;
65+
return affected > 0;
7566
}
7667
catch (Exception ex)
7768
{
@@ -86,22 +77,24 @@ public class SqliteContactRemover(string connectionString) : IContactRemover
8677
{
8778
private readonly string _connectionString = connectionString;
8879

89-
public void RemoveMutedContact(int userId, int contactId)
80+
public bool UnmuteContact(int userId, int contactId)
9081
{
9182
const string query = @"
92-
UPDATE MutedContacts
93-
SET IsActive = 0
94-
WHERE MutedByUserId = @userId AND MutedContactId = @contactId";
83+
UPDATE Contacts
84+
SET MutedUntil = NULL
85+
WHERE UserId = @userId AND ContactId = @contactId";
9586

9687
using (var connection = new SqliteConnection(_connectionString))
9788
{
9889
try
9990
{
100-
connection.Execute(query, new { userId, contactId });
91+
int affected = connection.Execute(query, new { userId, contactId });
92+
return affected > 0;
10193
}
10294
catch (Exception ex)
10395
{
104-
Log.Error(ex, "An error occurred in the method {MethodName}", nameof(RemoveMutedContact));
96+
Log.Error(ex, "An error occurred in the method {MethodName}", nameof(UnmuteContact));
97+
return false;
10598
}
10699
}
107100
}
@@ -385,26 +378,28 @@ FROM Contacts
385378
}
386379
}
387380

388-
public string GetActiveMuteTimeByContactID(int contactID)
381+
public DateTime? GetMutedUntil(int userId, int contactId)
389382
{
390383
try
391384
{
392385
using var connection = new SqliteConnection(_connectionString);
393-
394-
var expirationDate = connection.QueryFirstOrDefault<DateTime?>(
395-
@"SELECT ExpirationDate
396-
FROM MutedContacts
397-
WHERE MutedContactId = @contactID
398-
AND IsActive = 1",
399-
new { contactID });
400-
401-
return expirationDate?.ToString("yyyy-MM-dd HH:mm:ss")
402-
?? Config.GetResourceString("NoActiveMute");
386+
387+
var mutedUntilStr = connection.QueryFirstOrDefault<string?>(
388+
@"SELECT MutedUntil
389+
FROM Contacts
390+
WHERE UserId = @userId AND ContactId = @contactId",
391+
new { userId, contactId });
392+
393+
if (mutedUntilStr != null && DateTime.TryParse(mutedUntilStr, out var result))
394+
{
395+
return result;
396+
}
397+
return null;
403398
}
404399
catch (Exception ex)
405400
{
406-
Log.Error(ex, "An error occurred in the method {MethodName}", nameof(GetActiveMuteTimeByContactID));
407-
return "";
401+
Log.Error(ex, "An error occurred in the method {MethodName}", nameof(GetMutedUntil));
402+
return null;
408403
}
409404
}
410405

Database/Repositories/SqLite/SQLiteDBMigration.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,6 @@ protected override void CreateSpecificConstraints()
4444
.OnTable("Contacts")
4545
.OnColumn("ContactId");
4646

47-
// ========== Индексы для MutedContacts ==========
48-
Create.Index("IX_MutedContacts_MutedByUserId")
49-
.OnTable("MutedContacts")
50-
.OnColumn("MutedByUserId");
51-
52-
Create.Index("IX_MutedContacts_MutedContactId")
53-
.OnTable("MutedContacts")
54-
.OnColumn("MutedContactId");
55-
5647
// ========== Индексы для UsersGroups ==========
5748
Create.Index("IX_UsersGroups_UserId")
5849
.OnTable("UsersGroups")

Database/Repositories/SqLite/UserRepository.cs

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,6 @@ INSERT INTO Users (TelegramID, Name, Link)
4848
connection.Execute(query, new { telegramID, name, link });
4949
}
5050

51-
public void UnMuteUserByMuteId(int muteId)
52-
{
53-
const string query = @"
54-
UPDATE MutedContacts
55-
SET IsActive = 0
56-
WHERE MutedId = @muteId";
57-
58-
using var connection = new SqliteConnection(_connectionString);
59-
connection.Execute(query, new { muteId });
60-
}
61-
6251
public bool ReCreateUserSelfLink(int userId)
6352
{
6453
string newLink = Utils.GenerateUserLink();
@@ -111,13 +100,14 @@ public string GetUserNameByTelegramID(long telegramID)
111100
public List<long> GetUsersIdForMuteContactId(int contactId)
112101
{
113102
const string query = @"
114-
SELECT MutedByUserId
115-
FROM MutedContacts
116-
WHERE MutedContactId = @ContactId AND IsActive = 1";
117-
103+
SELECT UserId
104+
FROM Contacts
105+
WHERE ContactId = @ContactId
106+
AND (MutedUntil IS NULL OR MutedUntil > datetime('now'))";
107+
118108
using var connection = new SqliteConnection(_connectionString);
119109
var mutedByUserIds = connection.Query<int>(query, new { ContactId = contactId }).ToList();
120-
110+
121111
return mutedByUserIds.Select(GetTelegramIDbyUserID).ToList();
122112
}
123113

@@ -163,24 +153,24 @@ public string GetUserSelfLink(long telegramID)
163153
return "";
164154
}
165155

166-
public List<int> GetExpiredUsersMutes()
156+
public async Task<List<(int UserId, int ContactId)>> GetExpiredMutesAsync()
167157
{
168158
const string query = @"
169-
SELECT MutedId
170-
FROM MutedContacts
171-
WHERE ExpirationDate <= datetime('now')
172-
AND IsActive = 1";
159+
SELECT UserId, ContactId
160+
FROM Contacts
161+
WHERE MutedUntil IS NOT NULL
162+
AND MutedUntil <= datetime('now')";
173163

174164
try
175165
{
176166
using var connection = new SqliteConnection(_connectionString);
177-
var expiredMuteIds = connection.Query<int>(query).ToList();
178-
return expiredMuteIds;
167+
var results = await connection.QueryAsync<(int UserId, int ContactId)>(query);
168+
return results.ToList();
179169
}
180170
catch (Exception ex)
181171
{
182-
Log.Error(ex, "An error occurred in the method {MethodName}", nameof(GetExpiredUsersMutes));
183-
return new List<int>();
172+
Log.Error(ex, "An error occurred in the method {MethodName}", nameof(GetExpiredMutesAsync));
173+
return new List<(int UserId, int ContactId)>();
184174
}
185175
}
186176

TelegramBot/Scheduler.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@ class Scheduler
1919
{
2020
private Timer? _unMuteTimer;
2121
private Timer? _torChangingChainTimer;
22-
private readonly IUserRepository _userRepository;
2322
private readonly IUserGetter _userGetter;
23+
private readonly IContactRemover _contactRemover;
2424

2525
public Scheduler(
26-
IUserRepository userRepository,
27-
IUserGetter userGetter
26+
IUserGetter userGetter,
27+
IContactRemover contactRemover
2828
)
2929
{
30-
_userRepository = userRepository;
3130
_userGetter = userGetter;
31+
_contactRemover = contactRemover;
3232
}
3333

3434
public void Init()
@@ -39,23 +39,21 @@ public void Init()
3939
Log.Information("Scheduler started");
4040
}
4141

42-
private Task CheckForUnmuteContacts()
42+
private async Task CheckForUnmuteContacts()
4343
{
4444
try
4545
{
46-
List<int> expiredMutes = _userGetter.GetExpiredUsersMutes();
46+
var expiredMutes = await _userGetter.GetExpiredMutesAsync();
4747

48-
foreach (var muteUserId in expiredMutes)
48+
foreach (var (userId, contactId) in expiredMutes)
4949
{
50-
_userRepository.UnMuteUserByMuteId(muteUserId);
50+
_contactRemover.UnmuteContact(userId, contactId);
5151
}
5252
}
5353
catch (Exception ex)
5454
{
5555
Log.Error(ex, "An error occurred in the method{MethodName}", nameof(CheckForUnmuteContacts));
5656
}
57-
58-
return Task.CompletedTask;
5957
}
6058

6159
private static async Task TorChangingChain()

TelegramBot/States/MuteUser.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ await botClient.SendMessage(chatId, text, cancellationToken: cancellationToken,
111111

112112
if (int.TryParse(muteTime, out int time))
113113
{
114-
DateTime unmuteTime = DateTime.Now.AddSeconds(time);
114+
DateTime unmuteTime = DateTime.UtcNow.AddSeconds(time);
115115
expirationDate = unmuteTime;
116116
string unmuteMessage = string.Format(Config.GetResourceString("UserWillBeUnmuted"), unmuteTime, time);
117117
await botClient.SendMessage(chatId, unmuteMessage, cancellationToken: cancellationToken);
@@ -141,7 +141,7 @@ await botClient.SendMessage(chatId, Config.GetResourceString("ConfirmFinalDecisi
141141
await ReplyKeyboardUtils.RemoveReplyMarkup(botClient, chatId, cancellationToken);
142142

143143
UserSessionManager.Remove(chatId);
144-
if (_contactAdder.AddMutedContact(mutedByUserId, mutedContactId, expirationDate))
144+
if (!_contactAdder.MuteContact(mutedByUserId, mutedContactId, expirationDate))
145145
{
146146
await CommonUtilities.AlertMessageAndShowMenu(botClient, update, chatId, Config.GetResourceString("ActionCancelledError"));
147147
return;

TelegramBot/States/UnMuteUser.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ await botClient.SendMessage(chatId, Config.GetResourceString("ConfirmDecision"),
100100
case UserUnMuteState.WaitingForUnMute:
101101
if (await CommonUtilities.HandleStateBreakCommand(botClient, update, chatId)) return;
102102

103-
string activeMuteTime = _contactGetter.GetActiveMuteTimeByContactID(mutedContactId);
103+
DateTime? mutedUntil = _contactGetter.GetMutedUntil(mutedByUserId, mutedContactId);
104+
string activeMuteTime = mutedUntil?.ToString("yyyy-MM-dd HH:mm:ss")
105+
?? Config.GetResourceString("NoActiveMute");
104106
string text = string.Format(Config.GetResourceString("UserInMute"), activeMuteTime);
105107
await botClient.SendMessage(chatId, text, cancellationToken: cancellationToken,
106108
replyMarkup: ReplyKeyboardUtils.GetSingleButtonKeyboardMarkup(Config.GetResourceString("YesButtonText")));
@@ -111,7 +113,7 @@ await botClient.SendMessage(chatId, text, cancellationToken: cancellationToken,
111113
if (await CommonUtilities.HandleStateBreakCommand(botClient, update, chatId)) return;
112114
await ReplyKeyboardUtils.RemoveReplyMarkup(botClient, chatId, cancellationToken);
113115

114-
_contactRemover.RemoveMutedContact(mutedByUserId, mutedContactId);
116+
_contactRemover.UnmuteContact(mutedByUserId, mutedContactId);
115117
await CommonUtilities.AlertMessageAndShowMenu(botClient, update, chatId, Config.GetResourceString("UserUnmuted"));
116118
UserSessionManager.Remove(chatId);
117119
break;

0 commit comments

Comments
 (0)