unit uDeleteThread;

interface

uses
  System.SysUtils, System.Classes, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param,
  FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf, FireDAC.Stan.Async,
  FireDAC.DApt, FireDAC.UI.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Phys,
  FireDAC.VCLUI.Wait, FireDAC.Phys.MySQLDef, FireDAC.Phys.MySQL, Data.DB, FireDAC.Comp.Client,
  FireDAC.Comp.DataSet,
  Vcl.ComCtrls, // Для TTreeView
  Contnrs,vcl.dialogs,
  syncobjs,vcl.Forms,vcl.Controls, uSelectionOptions,uSelectedOrChecked,uDBConnectionBPL,
  uTreeView,uSQLQueries;

type
  TDeleteThread = class(TThread)
  private

   FDBtreeView:TDBTreeView;
   FSelectedOrChecked:TSelectedOrChecked;

   FIDList:TStringList;

   Procedure DeleteNodesFromDB(IDList:TStringlist);
   Procedure DeleteNodesFromTree;
   Function FindNodeInTree(ID:Integer):TTreeNode;

   procedure DisposeNodeData(Node:TTreeNode);
   procedure DeleteNodesFromTree3;


  public

  procedure MyCreate;

  property DBtreeView:TDBTreeView read FDBtreeView write FDBtreeView;

  property SelectedOrChecked:TSelectedOrChecked
  read FSelectedOrChecked write FSelectedOrChecked;

  property IDList:TStringList read FIDList write FIDList;

  protected
    procedure Execute; override;
  end;

implementation


                               { TDeleteThread }

procedure TDeleteThread.MyCreate;
begin
      //Создание
      FIDList:=TStringList.Create;
end;



procedure TDeleteThread.Execute;

var IDList:TStringList;
begin

 screen.Cursor:=crSQLWait;

 try

      DeleteNodesFromDB(FIDList);
      Synchronize(DeleteNodesFromTree3);


  finally
      //Освобождение
      FreeAndNil(FIDList);

   screen.Cursor:=crDefault;
  end;




end;


procedure TDeleteThread.DeleteNodesFromDB(IDList: TStringlist);
var qDelete:TFDQuery;  i:integer;
    DBConnectionLocal:TDBConnectionBPL;
    SQLQueries:TSQLQueries;

begin

// Создание
qDelete:=TFDQuery.Create(nil);
SQLQueries:=TSQLQueries.Create(nil);


DBConnectionLocal:=TDBConnectionBPL.Create(nil);

qDelete.SQL.Text:=SQLQueries.DeleteNodesFromDB.Text;
//'DELETE FROM `treeview_db`.`tree` WHERE `id`=:id;';

qDelete.Connection:=DBConnectionLocal.FDConnection;

 for i := 0 to IDList.Count-1 do
   begin
    with qDelete.Params do
     ParamValues['ID']:=IDList[i];
     qDelete.ExecSQL;
   end;



//Уничтожение
FreeAndNil(DBConnectionLocal);
FreeAndNil(qDelete);
FreeAndNil(SQLQueries)

end;

//-------------------Удаление узлов из дерева-------------------------------------------------------

procedure TDeleteThread.DeleteNodesFromTree;
var i,J:integer;
    Node:TTreeNode;
    DBTreeViewLocal:TDBTreeView;


begin


  //Присвоение
  DBTreeViewLocal:=Self.FDBtreeView;


//Удаление самих узлов
for i := FIDList.Count-1 downto 0 do
  begin

  Node:=FindNodeInTree(FIDList[i].ToInteger());

{   //Далее уходим в рекурсию
  if Node.HasChildren then
  for j := 0 to Node.Count-1 do
  DeleteNodesFromTree;}

  if Node<>nil then
      begin
      Dispose(Node.Data);
      DBTreeViewLocal.Items.Delete(Node);
      end;

  end;


end;



//--------------------------------------------------------------------------------------------------




//-----------------Вспомогательная процедура поиска узла

function TDeleteThread.FindNodeInTree(ID: Integer): TTreeNode;
var i:integer; DBTreeViewLocal:TDBTreeView;

begin

 DBTreeViewLocal:=FDBtreeView;

 Result:=nil; //Если родитель не будет найден, то это нулевой уровень
//Иначе, это будет какой-то конкретный узел
 for i := 0 to DBTreeViewLocal.Items.Count-1 do


 if DBTreeViewLocal.Items.Item[i].Data<>nil then

 begin
     if Integer(DBTreeViewLocal.Items.Item[i].Data^)=ID then

   begin
     Result:=DBTreeViewLocal.Items.Item[i];
     Break;
   end;
 end;




end;


//--------------------Корректное удаление---------------------------------------

procedure TDeleteThread.DeleteNodesFromTree3;

var i:integer; Node:TTreeNode; DBTreeViewLocal:TDBTreeView;
begin

  DBTreeViewLocal:=Self.FDBTreeView;

// Чистим память под указателями
for i := FIDList.Count-1 downto 0  do
   begin

   Node:=FindNodeInTree(FIDList[i].ToInteger());
   if Node<>nil then

       begin
       DisposeNodeData(Node);

       DBTreeViewLocal.Items.Delete(Node);
       end;


   end;



end;

procedure TDeleteThread.DisposeNodeData(Node: TTreeNode);
var i:integer;
begin

Dispose(Node.Data);
if Node.HasChildren then
 for i := 0 to Node.Count-1 do DisposeNodeData(Node[i]);

end;




end.

