Skip to content

Commit

Permalink
fix: Race condition for database
Browse files Browse the repository at this point in the history
  • Loading branch information
gcarreno committed Dec 9, 2024
1 parent 50e66ea commit b8b977b
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 49 deletions.
6 changes: 3 additions & 3 deletions pasirclogbot.example.config
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[IRC]
Host="irc.libera.chat"
Host="localhost"
Port=6667
NickName="[PasLogBot]"
UserName="paslogbot"
RealName="IRC channel #pascal log bot"
Channel="#PasLogBot"
Channel="#pascal"
[DB]
File="paslogbot.db"
File="paslogbot.db"
4 changes: 2 additions & 2 deletions src/bot/irclogbot.bot.pas
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ TReplayThread = class(TTHread)
protected
procedure Execute; override;
public
constructor Create(const AIRC: TIdIRC; const ATarget: String;
constructor Create(AIRC: TIdIRC; const ATarget: String;
const ALines: TStringList);
published
end;
Expand Down Expand Up @@ -105,7 +105,7 @@ procedure TReplayThread.Execute;
end;
end;

constructor TReplayThread.Create(const AIRC: TIdIRC; const ATarget: String;
constructor TReplayThread.Create(AIRC: TIdIRC; const ATarget: String;
const ALines: TStringList);
begin
inherited Create(True);
Expand Down
109 changes: 65 additions & 44 deletions src/database/irclogbot.database.pas
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ interface
uses
Classes
, SysUtils
, SyncObjs
, SQLite3Conn
, SQLDB
, IRCLogBot.Common
Expand All @@ -16,6 +17,7 @@ interface
{ TDatabase }
TDatabase = class(TObject)
private
FCriticalSection: TCriticalSection;
FConnection: TSQLite3Connection;
FTransaction: TSQLTransaction;
FQuery: TSQLQuery;
Expand Down Expand Up @@ -60,67 +62,85 @@ procedure TDatabase.SetupTables;

procedure TDatabase.Insert(ANickName, AChannel, AMessage: String);
begin
FCriticalSection.Acquire;
try
debug('Starting Transaction...');
FTransaction.StartTransaction;
debug('Inserting: <%s> [%s] "%s"', [ANickName, AChannel, AMessage]);
FConnection.ExecuteDirect(Format(
'INSERT INTO logs (nick, channel, message) VALUES (%s, %s, %s)',
[QuotedStr(ANickName), QuotedStr(AChannel), QuotedStr(AMessage)]));
FTransaction.Commit;
debug('Transaction committed.');
except
on e:Exception do
begin
FTransaction.Rollback;
debug('Error inserting message: %s', [e.Message]);
try
debug('Starting Transaction...');
FTransaction.StartTransaction;
try
debug('Inserting: <%s> [%s] "%s"', [ANickName, AChannel, AMessage]);
FConnection.ExecuteDirect(Format(
'INSERT INTO logs (nick, channel, message) VALUES (%s, %s, %s)',
[QuotedStr(ANickName), QuotedStr(AChannel), QuotedStr(AMessage)]));
finally
FTransaction.Commit;
debug('Transaction committed.');
end;
except
on e:Exception do
begin
FTransaction.Rollback;
debug('Error inserting message: %s', [e.Message]);
end;
end;
finally
FCriticalSection.Release;
end;
end;

function TDatabase.Get(ACount: Integer): TStringList;
begin
Result:= TStringList.Create;
FCriticalSection.Acquire;
try
debug('Starting transaction.');
FTransaction.StartTransaction;
FQuery.SQL.Text:= Format(
'SELECT timestamp, nick, channel, message FROM logs ORDER BY id DESC LIMIT %d',
[ACount]
);
FQuery.Open;
if FQuery.RecordCount > 0 then
begin
FQuery.First;
repeat
debug('Retrieving: %s [%s] %s: %s', [
FQuery.FieldByName('timestamp').AsString,
FQuery.FieldByName('channel').AsString,
FQuery.FieldByName('nick').AsString,
FQuery.FieldByName('message').AsString
]);
Result.Insert(0, Format('%s [%s] %s: %s',[
FQuery.FieldByName('timestamp').AsString,
FQuery.FieldByName('channel').AsString,
FQuery.FieldByName('nick').AsString,
FQuery.FieldByName('message').AsString
]));
FQuery.Next;
until FQuery.EOF;
FQuery.Close;
FTransaction.EndTransaction;
debug('Transaction ended.');
end;
except
on e:Exception do
begin
debug('Error retrieving lines: %s', [e.Message]);
try
try
FQuery.SQL.Text:= Format(
'SELECT timestamp, nick, channel, message FROM logs ORDER BY id DESC LIMIT %d',
[ACount]
);
FQuery.Open;
if FQuery.RecordCount > 0 then
begin
FQuery.First;
repeat
debug('Retrieving: %s [%s] %s: %s', [
FQuery.FieldByName('timestamp').AsString,
FQuery.FieldByName('channel').AsString,
FQuery.FieldByName('nick').AsString,
FQuery.FieldByName('message').AsString
]);
Result.Insert(0, Format('%s [%s] %s: %s',[
FQuery.FieldByName('timestamp').AsString,
FQuery.FieldByName('channel').AsString,
FQuery.FieldByName('nick').AsString,
FQuery.FieldByName('message').AsString
]));
FQuery.Next;
until FQuery.EOF;
FQuery.Close;
end;
finally
FTransaction.EndTransaction;
debug('Transaction ended.');
end;
except
on e:Exception do
begin
FTransaction.Rollback;
debug('Error retrieving lines: %s', [e.Message]);
end;
end;
finally
FCriticalSection.Release;
end;
end;

constructor TDatabase.Create(ADatabaseFile: String);
begin
FCriticalSection:= TCriticalSection.Create;
FConnection:= TSQLite3Connection.Create(nil);
FTransaction:= TSQLTransaction.Create(FConnection);
FConnection.Transaction:= FTransaction;
Expand All @@ -133,6 +153,7 @@ constructor TDatabase.Create(ADatabaseFile: String);

destructor TDatabase.Destroy;
begin
FCriticalSection.Free;
FQuery.Free;
FTransaction.Free;
FConnection.Free;
Expand Down

0 comments on commit b8b977b

Please sign in to comment.