492 lines
13 KiB
ObjectPascal
492 lines
13 KiB
ObjectPascal
unit uDataBase;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.SysUtils, System.Classes, FireDAC.Comp.Client, FireDAC.Stan.Param,
|
|
FMX.Grid, FireDAC.Stan.Def, FireDAC.Stan.Intf, FireDAC.Stan.Option,
|
|
FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Pool,
|
|
FireDAC.Stan.Async, FireDAC.Phys, FireDAC.Phys.SQLite, FireDAC.Phys.SQLiteDef,
|
|
FireDAC.Stan.ExprFuncs, FireDAC.Phys.SQLiteWrapper.Stat, FireDAC.VCLUI.Wait,
|
|
FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt, Data.DB, FireDAC.Comp.DataSet,
|
|
FireDAC.FMXUI.Wait, FireDAC.Comp.UI, uRecords, System.Generics.Collections;
|
|
|
|
type
|
|
TSettingsDatabase = class
|
|
|
|
private
|
|
FConnection: TFDConnection;
|
|
procedure InitializeDatabase;
|
|
function GetSetting(const Name: string): string;
|
|
procedure SetSetting(const Name, Value: string);
|
|
function GetColumnsDefinition(Grid: TStringGrid): string;
|
|
function GetColumnsList(Grid: TStringGrid): string;
|
|
function GetValuesPlaceholders(Grid: TStringGrid): string;
|
|
function CheckTableExists(const TableName: string): Boolean;
|
|
public
|
|
FChannel: string;
|
|
|
|
constructor Create(const DatabasePath: string);
|
|
destructor Destroy; override;
|
|
|
|
// Ìåòîäû äëÿ ðàáîòû ñ íàñòðîéêàìè
|
|
function ReadSetting(const Name: string; Default: string = ''): string;
|
|
procedure WriteSetting(const Name, Value: string);
|
|
function getLoginData(): TLogin;
|
|
|
|
// Ìåòîäû äëÿ ðàáîòû ñ TStringGrid
|
|
procedure SaveGridToTable(const TableName: string; Grid: TStringGrid);
|
|
procedure LoadGridFromTable(const TableName: string; Grid: TStringGrid);
|
|
|
|
// Ìåòîäû äëÿ ðàáîòû ñ Users
|
|
// procedure SaveUsers(const Users: array of User);
|
|
procedure LoadUsers(var users: tlist<tuser>);
|
|
|
|
// Ìåòîäû äëÿ ðàáîòû ñ Ãðóïïîâûìè îòâåòàìè
|
|
procedure addGroupResponse(Name, Respons: string);
|
|
procedure getGroupResponse(aName: string; const lbResponse: Tstrings);
|
|
procedure getGroupName(const lbName: Tstrings);
|
|
procedure delGroupName(aName: string);
|
|
procedure delGroupResponse(aName, aResponse: string);
|
|
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses uGeneral;
|
|
|
|
constructor TSettingsDatabase.Create(const DatabasePath: string);
|
|
begin
|
|
FConnection := TFDConnection.Create(nil);
|
|
try
|
|
FConnection.DriverName := 'SQLite';
|
|
FConnection.Params.Database := DatabasePath;
|
|
FConnection.Connected := True;
|
|
InitializeDatabase;
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
FreeAndNil(FConnection);
|
|
raise Exception.Create('Îøèáêà ïðè ïîäêëþ÷åíèè ê áàçå äàííûõ: ' +
|
|
E.Message);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TSettingsDatabase.delGroupName(aName: string);
|
|
var
|
|
Query: TFDQuery;
|
|
begin
|
|
Query := TFDQuery.Create(nil);
|
|
try
|
|
Query.Connection := FConnection;
|
|
Query.SQL.Text := 'delete FROM GroupResponse where Name = "' + aName + '"';
|
|
Query.ExecSQL;
|
|
finally
|
|
Query.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TSettingsDatabase.delGroupResponse(aName, aResponse: string);
|
|
var
|
|
Query: TFDQuery;
|
|
begin
|
|
Query := TFDQuery.Create(nil);
|
|
try
|
|
Query.Connection := FConnection;
|
|
Query.SQL.Text := 'delete FROM GroupResponse where Name = :name' +
|
|
' and Response = :response';
|
|
Query.Params.ParamByName('name').AsString := aName;
|
|
Query.Params.ParamByName('response').AsString := aResponse;
|
|
Query.ExecSQL;
|
|
finally
|
|
Query.Free;
|
|
end;
|
|
end;
|
|
|
|
destructor TSettingsDatabase.Destroy;
|
|
begin
|
|
if Assigned(FConnection) then
|
|
FConnection.Connected := False;
|
|
FreeAndNil(FConnection);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TSettingsDatabase.InitializeDatabase;
|
|
var
|
|
FDQuery: TFDQuery;
|
|
FieldExists: Boolean;
|
|
begin
|
|
// Ñîçäàåì òàáëèöó, åñëè îíà íå ñóùåñòâóåò
|
|
FConnection.ExecSQL('CREATE TABLE IF NOT EXISTS params (' +
|
|
' name TEXT PRIMARY KEY,' + ' value TEXT' + ');');
|
|
// Ñîçäàåì òàáëèöó äëÿ ïîëüçîâàòåëåé, åñëè îíà íå ñóùåñòâóåò
|
|
FConnection.ExecSQL('CREATE TABLE IF NOT EXISTS users (' +
|
|
' id TEXT PRIMARY KEY,' + ' login TEXT,' + ' DisplayName TEXT,' +
|
|
' created_at DATETIME,' + ' follow_at DATETIME,' + ' isVip TEXT,' +
|
|
' isModer TEXT,' + ' isO TEXT,' + ' streamer TEXT' +
|
|
|
|
');');
|
|
FDQuery := TFDQuery.Create(nil);
|
|
try
|
|
FDQuery.Connection := FConnection;
|
|
FieldExists := False;
|
|
FDQuery.SQL.Text := 'PRAGMA table_info(users)';
|
|
FDQuery.Open;
|
|
while not FDQuery.EOF do
|
|
begin
|
|
if FDQuery.FieldByName('name').AsString = 'streamer' then
|
|
begin
|
|
FieldExists := True;
|
|
Break;
|
|
end;
|
|
FDQuery.Next;
|
|
end;
|
|
FDQuery.Close;
|
|
if not FieldExists then
|
|
begin
|
|
FConnection.ExecSQL('ALTER TABLE users ADD COLUMN streamer TEXT');
|
|
end;
|
|
finally
|
|
FDQuery.Free;
|
|
end;
|
|
|
|
FConnection.ExecSQL
|
|
('CREATE TABLE IF NOT EXISTS GroupResponse (ID INTEGER PRIMARY KEY, Name TEXT, Response TEXT);');
|
|
|
|
end;
|
|
|
|
{ procedure TSettingsDatabase.SaveUsers(const Users: array of User);
|
|
var
|
|
Query: TFDQuery;
|
|
UserItem: User;
|
|
s: string;
|
|
begin
|
|
if Length(Users) < 1 then
|
|
exit;
|
|
// Âñòàâëÿåì äàííûå èç ìàññèâà ïîëüçîâàòåëåé â òàáëèöó
|
|
Query := TFDQuery.Create(nil);
|
|
try
|
|
Query.Connection := FConnection;
|
|
for UserItem in Users do
|
|
begin
|
|
Query.SQL.Text :=
|
|
'INSERT OR REPLACE INTO users (id, login, DisplayName, created_at, follow_at, isVip, isModer, isO, streamer) '
|
|
+ 'VALUES (:id, :login, :DisplayName, :created_at, :follow_at, :isVip, :isModer, :isO, :streamer);';
|
|
Query.ParamByName('id').AsString := UserItem.id;
|
|
Query.ParamByName('login').AsString := UserItem.login;
|
|
Query.ParamByName('DisplayName').AsString := UserItem.DisplayName;
|
|
Query.ParamByName('created_at').AsDateTime := UserItem.created_at;
|
|
Query.ParamByName('follow_at').AsDateTime := UserItem.follow_at;
|
|
Query.ParamByName('streamer').AsString := FChannel;
|
|
|
|
if UserItem.isVip then
|
|
s := 'True'
|
|
else
|
|
s := 'False';
|
|
Query.ParamByName('isVip').AsString := s;
|
|
if UserItem.isModer then
|
|
s := 'True'
|
|
else
|
|
s := 'False';
|
|
Query.ParamByName('isModer').AsString := s;
|
|
if UserItem.isO then
|
|
s := 'True'
|
|
else
|
|
s := 'False';
|
|
Query.ParamByName('isO').AsString := s;
|
|
Query.ExecSQL;
|
|
end;
|
|
finally
|
|
Query.Free;
|
|
end;
|
|
end; }
|
|
|
|
procedure TSettingsDatabase.LoadUsers(var users: tlist<tuser>);
|
|
var
|
|
Query: TFDQuery;
|
|
UserItem: tuser;
|
|
|
|
begin
|
|
|
|
Query := TFDQuery.Create(nil);
|
|
try
|
|
Query.Connection := FConnection;
|
|
Query.SQL.Text := 'SELECT * FROM users WHERE streamer = :streamer';
|
|
Query.ParamByName('streamer').AsString := FChannel;
|
|
Query.Open;
|
|
|
|
while not Query.EOF do
|
|
begin
|
|
UserItem.id := Query.FieldByName('id').AsString;
|
|
UserItem.login := Query.FieldByName('login').AsString;
|
|
UserItem.DisplayName := Query.FieldByName('DisplayName').AsString;
|
|
UserItem.created_at := Query.FieldByName('created_at').AsDateTime;
|
|
UserItem.follow_at := Query.FieldByName('follow_at').AsDateTime;
|
|
UserItem.isVip := Query.FieldByName('isVip').AsString = 'True';
|
|
UserItem.isModer := Query.FieldByName('isModer').AsString = 'True';
|
|
UserItem.isO := Query.FieldByName('isO').AsString = 'True';
|
|
UserItem.isO_today := False;
|
|
users.Add(UserItem);
|
|
Query.Next;
|
|
end;
|
|
|
|
finally
|
|
Query.Free;
|
|
end;
|
|
end;
|
|
|
|
function TSettingsDatabase.GetColumnsDefinition(Grid: TStringGrid): string;
|
|
var
|
|
Col: Integer;
|
|
begin
|
|
Result := '';
|
|
for Col := 0 to Grid.ColumnCount - 1 do
|
|
begin
|
|
if Result <> '' then
|
|
Result := Result + ', ';
|
|
Result := Result + 'col' + IntToStr(Col) + ' TEXT';
|
|
end;
|
|
end;
|
|
|
|
function TSettingsDatabase.GetColumnsList(Grid: TStringGrid): string;
|
|
var
|
|
Col: Integer;
|
|
begin
|
|
Result := '';
|
|
for Col := 0 to Grid.ColumnCount - 1 do
|
|
begin
|
|
if Result <> '' then
|
|
Result := Result + ', ';
|
|
Result := Result + 'col' + IntToStr(Col);
|
|
end;
|
|
end;
|
|
|
|
procedure TSettingsDatabase.getGroupName(const lbName: Tstrings);
|
|
var
|
|
Query: TFDQuery;
|
|
begin
|
|
Query := TFDQuery.Create(nil);
|
|
try
|
|
Query.Connection := FConnection;
|
|
|
|
lbName.Clear;
|
|
Query.SQL.Text := 'SELECT DISTINCT Name FROM GroupResponse';
|
|
Query.Open;
|
|
while not Query.EOF do
|
|
begin
|
|
lbName.Add(Query.FieldByName('Name').AsString);
|
|
Query.Next;
|
|
end;
|
|
finally
|
|
Query.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TSettingsDatabase.getGroupResponse(aName: string;
|
|
const lbResponse: Tstrings);
|
|
var
|
|
Query: TFDQuery;
|
|
begin
|
|
Query := TFDQuery.Create(nil);
|
|
try
|
|
Query.Connection := FConnection;
|
|
|
|
lbResponse.Clear;
|
|
Query.SQL.Text := 'SELECT * FROM GroupResponse WHERE name=:TableName';
|
|
Query.ParamByName('TableName').AsString := aName;
|
|
Query.Open;
|
|
while not Query.EOF do
|
|
begin
|
|
lbResponse.Add(Query.FieldByName('Response').AsString);
|
|
Query.Next;
|
|
end;
|
|
finally
|
|
Query.Free;
|
|
end;
|
|
|
|
end;
|
|
|
|
function TSettingsDatabase.getLoginData: TLogin;
|
|
begin
|
|
Result.TTV_Token_Bot := ReadSetting('edtBotToken');
|
|
Result.TTV_Token_Strimer := ReadSetting('edtBotTokenStreamer');
|
|
Result.TTV_Name_Bot := ReadSetting('edtBotName');
|
|
Result.TTV_Name_Strimer := ReadSetting('edtChannel');
|
|
Result.TTV_ClientID := ReadSetting('edtBotClientID');
|
|
|
|
Result.DA_ClientID := ReadSetting('edtDAClientID');
|
|
Result.DA_Client_Sictert := ReadSetting('edtDAClientSecret');
|
|
Result.DA_RedirectURL := ReadSetting('edtDARedirectURL');
|
|
Result.DA_Code := ReadSetting('edtDACode');
|
|
|
|
Result.AI_Gigachat_ClientID := ReadSetting('edtGPTClientID');
|
|
Result.AI_Gigachat_AutorizationCode := ReadSetting('edtGPTAC');
|
|
Result.AI_ChatGPT_Token := ReadSetting('edtGPTATChatGPT');
|
|
Result.AI_DeepSeek_Token := ReadSetting('edtGPTATDeepSeek');
|
|
end;
|
|
|
|
function TSettingsDatabase.GetValuesPlaceholders(Grid: TStringGrid): string;
|
|
var
|
|
Col: Integer;
|
|
begin
|
|
Result := '';
|
|
for Col := 0 to Grid.ColumnCount - 1 do
|
|
begin
|
|
if Result <> '' then
|
|
Result := Result + ', ';
|
|
Result := Result + ':col' + IntToStr(Col);
|
|
end;
|
|
end;
|
|
|
|
procedure TSettingsDatabase.addGroupResponse(Name, Respons: string);
|
|
var
|
|
Query: TFDQuery;
|
|
begin
|
|
Query := TFDQuery.Create(nil);
|
|
try
|
|
Query.Connection := FConnection;
|
|
Query.SQL.Text :=
|
|
Format('INSERT INTO GroupResponse (Name, Response) VALUES (''%s'', ''%s'')',
|
|
[Name, Respons]);
|
|
Query.ExecSQL;
|
|
finally
|
|
Query.Free;
|
|
end;
|
|
end;
|
|
|
|
function TSettingsDatabase.CheckTableExists(const TableName: string): Boolean;
|
|
var
|
|
Query: TFDQuery;
|
|
begin
|
|
Result := False;
|
|
Query := TFDQuery.Create(nil);
|
|
try
|
|
Query.Connection := FConnection;
|
|
Query.SQL.Text :=
|
|
'SELECT COUNT(*) FROM sqlite_master WHERE type=''table'' AND name=:TableName';
|
|
Query.ParamByName('TableName').AsString := TableName;
|
|
Query.Open;
|
|
Result := (Query.Fields[0].AsInteger > 0);
|
|
finally
|
|
Query.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TSettingsDatabase.LoadGridFromTable(const TableName: string;
|
|
Grid: TStringGrid);
|
|
var
|
|
Query: TFDQuery;
|
|
Col, Row: Integer;
|
|
begin
|
|
Query := TFDQuery.Create(nil);
|
|
try
|
|
Query.Connection := FConnection;
|
|
|
|
// Ïðîâåðèòü íàëè÷èå òàáëèöû
|
|
if not CheckTableExists(TableName) then
|
|
begin
|
|
// Òàáëèöà íå ñóùåñòâóåò, âûõîäèì èç ïðîöåäóðû
|
|
exit;
|
|
end;
|
|
|
|
Query.SQL.Text := 'SELECT * FROM ' + TableName;
|
|
Query.Open;
|
|
|
|
// Î÷èùàåì Grid
|
|
Grid.RowCount := 0;
|
|
|
|
// Çàïîëíÿåì Grid äàííûìè èç òàáëèöû
|
|
while not Query.EOF do
|
|
begin
|
|
Row := Grid.RowCount;
|
|
Grid.RowCount := Grid.RowCount + 1;
|
|
|
|
for Col := 0 to Grid.ColumnCount - 1 do
|
|
begin
|
|
Grid.Cells[Col, Row] := Query.FieldByName('col' + IntToStr(Col)
|
|
).AsString;
|
|
end;
|
|
|
|
Query.Next;
|
|
end;
|
|
finally
|
|
Query.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TSettingsDatabase.SaveGridToTable(const TableName: string;
|
|
Grid: TStringGrid);
|
|
var
|
|
Query: TFDQuery;
|
|
Col, Row: Integer;
|
|
begin
|
|
// Óäàëÿåì ñòàðóþ òàáëèöó, åñëè îíà ñóùåñòâóåò
|
|
FConnection.ExecSQL('DROP TABLE IF EXISTS ' + TableName);
|
|
|
|
// Ñîçäàåì íîâóþ òàáëèöó
|
|
FConnection.ExecSQL('CREATE TABLE ' + TableName + ' (' +
|
|
' id INTEGER PRIMARY KEY AUTOINCREMENT,' + ' ' +
|
|
GetColumnsDefinition(Grid) + ');');
|
|
|
|
// Âñòàâëÿåì äàííûå èç Grid â òàáëèöó
|
|
Query := TFDQuery.Create(nil);
|
|
try
|
|
Query.Connection := FConnection;
|
|
for Row := 0 to Grid.RowCount - 1 do
|
|
begin
|
|
Query.SQL.Text := 'INSERT INTO ' + TableName + ' (' + GetColumnsList(Grid)
|
|
+ ') VALUES (' + GetValuesPlaceholders(Grid) + ')';
|
|
for Col := 0 to Grid.ColumnCount - 1 do
|
|
begin
|
|
Query.ParamByName('col' + IntToStr(Col)).AsString :=
|
|
Grid.Cells[Col, Row];
|
|
end;
|
|
Query.ExecSQL;
|
|
end;
|
|
finally
|
|
Query.Free;
|
|
end;
|
|
end;
|
|
|
|
function TSettingsDatabase.GetSetting(const Name: string): string;
|
|
var
|
|
Query: TFDQuery;
|
|
begin
|
|
Query := TFDQuery.Create(nil);
|
|
try
|
|
Query.Connection := FConnection;
|
|
Query.SQL.Text := 'SELECT value FROM params WHERE name = :name';
|
|
Query.ParamByName('name').AsString := Name;
|
|
Query.Open;
|
|
if not Query.IsEmpty then
|
|
Result := Query.FieldByName('value').AsString
|
|
else
|
|
Result := '';
|
|
finally
|
|
Query.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TSettingsDatabase.SetSetting(const Name, Value: string);
|
|
begin
|
|
FConnection.ExecSQL
|
|
('INSERT OR REPLACE INTO params (name, value) VALUES (:name, :value)',
|
|
[Name, Value]);
|
|
end;
|
|
|
|
function TSettingsDatabase.ReadSetting(const Name: string;
|
|
Default: string = ''): string;
|
|
begin
|
|
Result := GetSetting(Name);
|
|
if Result = '' then
|
|
Result := Default;
|
|
end;
|
|
|
|
procedure TSettingsDatabase.WriteSetting(const Name, Value: string);
|
|
begin
|
|
SetSetting(Name, Value);
|
|
end;
|
|
|
|
end.
|