unit uAddFoldersAndFilesToDB;

interface

uses
  System.SysUtils, System.Classes, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf,
  FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.VCLUI.Wait, Data.DB,
  FireDAC.Comp.Client, FireDAC.Phys.MySQLDef, FireDAC.Phys.MySQL,Vcl.Dialogs, FireDAC.Stan.Param, FireDAC.DatS,
  FireDAC.DApt.Intf, FireDAC.DApt, FireDAC.Comp.DataSet,System.IOUtils, System.Types,Vcl.Forms ;

type
  TAddFoldersAndFilesToDB = class(TDataModule)
  private

    function GetIDParentFromRelativeDir(ARelDirs: TStringList; ACurrentIndex: integer): integer;
    function GetNameFromRelPath(ARelPath: String): String;
    function IsSuchRelPathInDB(ARelPath: String): Boolean;



    { Private declarations }
  public
    { Public declarations }

    constructor Create(AOwner: TComponent); override;

     procedure GetFoldersFromRelDir(ARelDir: String; var AAbsDirs, ARelDirs: TStringList);
    {< recieves relative dir on server, builds abs dirs, checks if they are will extract folders since }

    procedure AddFoldersToDB(AAbsDirs, ARelDirs: TStringList; var idParentForFile:integer; users_id:integer);
    {< will add New Record To DB of Folders}

    procedure GetInfoAboutFile(ARelPath:string; var fileName:string; var fileSize:int64; var AbsPath:String );

    procedure InsertFolderOrFileToDB
    (IsFolderParam:Boolean;idParent: Integer; nameToInsert: string; users_id:integer;fileSize:integer;relPath:string; absPath:string); overload;
    {< inserts Folders and Files with users_id}

    procedure InsertFolderOrFileToDB
    (IsFolderParam:Boolean; idParent:Integer; nameToInsert:string; fileSize:integer;relPath:string;absPath:string); overload;
    {< inserts Folders and Files without users_id}

  end;

var
  AddFoldersAndFilesToDB: TAddFoldersAndFilesToDB;

implementation

{%CLASSGROUP 'Vcl.Controls.TControl'}

{$R *.dfm}

uses uHTTPServer_Main;
var  HTTPServer_Main_UnitVar:TfHTTPServer;


{ TAddFoldersAndFiles }

constructor TAddFoldersAndFilesToDB.Create(AOwner: TComponent);
begin
  inherited;

  if (AOwner is TfHTTPServer) then
  HTTPServer_Main_UnitVar:=(AOwner as TfHTTPServer);

end;



procedure TAddFoldersAndFilesToDB.
GetFoldersFromRelDir(ARelDir: String; var AAbsDirs:TStringList; var ARelDirs:TStringList );

var
  AppDir: String;
  AbsPath: String;

  SplittedString: TArray<String>;
  i: Integer;
  SomeRelDir:string;
  SomeAbsDir: String;
  SomeRelDirWithFirstSlash:String;
  SomeRelDirWithoutFirstSlash:string;

begin


AAbsDirs.Clear;

// we will get Relative dir like this
// rel public\files\UserID\2016\28\10\SomeFile.jpg

// 1---------- Lets build Absolute dir and find all dirs since public
// abs C:\DELPHI\MyStudyProjects\373_PS_HTTPClient_Dev\HTTPServer\Win32\Debug\public\files\UserID\2016\28\10\SomeFile.jpg

AppDir:=ExtractFileDir(Application.ExeName);


// now separate all by \ separator
SplittedString:=ARelDir.Split(['\']);

    SomeRelDir:='';SomeRelDirWithFirstSlash:=''; SomeRelDirWithoutFirstSlash:='';

    for i := 0 to High(SplittedString) do

     begin

      {
      SomeRelDirWithFirstSlash:=SomeRelDirWithFirstSlash+'\'+SplittedString[i];

      if i<>0 then
      SomeRelDirWithoutFirstSlash:=SomeRelDirWithoutFirstSlash+SplittedString[i]
      else
      SomeRelDirWithoutFirstSlash:=SomeRelDirWithoutFirstSlash+'\'+SplittedString[i];
      }

      SomeRelDir:=SomeRelDir+'\'+SplittedString[i];

      SomeAbsDir:=AppDir+SomeRelDir;

        //check if dir Exists and Add it to dirs;
        if TDirectory.Exists(SomeAbsDir) then

            begin

            ARelDirs.Add(SomeRelDir);
            AAbsDirs.Add(SomeAbsDir);

            end;


        //
        SomeAbsDir:='';

     end;



end;




procedure TAddFoldersAndFilesToDB.AddFoldersToDB(
AAbsDirs:TStringList; ARelDirs:TStringList; var idParentForFile:integer; users_id:integer);

var

  i: Integer;
  idParent:Integer;
  nameToInsert:String;
  fileSize:Integer;


begin

    for i := 0 to ARelDirs.Count-1 do

     begin

       ARelDirs[i]:=StringReplace(ARelDirs[i],'\','/',[rfReplaceAll]);

     // check if such Relative Dir in DataBase if not - add new Record

       if not IsSuchRelPathInDB(ARelDirs[i]) then

           begin

            // Preparing Params
            idParent:=GetIDParentFromRelativeDir(ARelDirs,i);
            nameToInsert:=GetNameFromRelPath(ARelDirs[i]);


            fileSize:=-1;


            if (nameToInsert='public') or (nameToInsert='files') then


            InsertFolderOrFileToDB(

                // Mainly for folders public/files/IDUser, without users_id, it will by null by default

                    True,//IsFolder:Boolean;
                    idParent,//idParent:Integer;
                    nameToInsert,//nameToInsert:string;
                    fileSize,//fileSize:integer;
                    ARelDirs[i],//relPath:string;
                    AAbsDirs[i]//absPath:string

                  ) else


                   InsertFolderOrFileToDB(

                    // for files...

                         True,//IsFolder:Boolean;
                    idParent,//idParent:Integer;
                    nameToInsert,//nameToInsert:string;
                    users_id,
                    fileSize,//fileSize:integer;
                    ARelDirs[i],//relPath:string;
                    AAbsDirs[i]//absPath:string

                    );





            if i=ARelDirs.Count-1 then begin

             idParentForFile:=GetIDParentFromRelativeDir(ARelDirs,i+1);

            end;


             end else
             //
                // just getting idParent


               if i=ARelDirs.Count-1 then begin
               idParentForFile:=GetIDParentFromRelativeDir(ARelDirs,i+1);
               end;

     end;


end;



function TAddFoldersAndFilesToDB.IsSuchRelPathInDB( ARelPath:String):Boolean;

begin

with HTTPServer_Main_UnitVar.DataBaseUnitServer do begin

 with qSelectFromFoldersAndFilesWhereRelPath do begin

  Params.ParamValues['RelPath']:=ARelPath;

  Open();

   if ARelPath=FieldByName('RelPath').AsString then Result:=true;


  Close();
 end;

end;

end;


function TAddFoldersAndFilesToDB.GetIDParentFromRelativeDir( ARelDirs:TStringList; ACurrentIndex:integer ):integer;

begin
//

with HTTPServer_Main_UnitVar.DataBaseUnitServer do begin

    if ACurrentIndex>0 then begin

     with qSelectFromFoldersAndFilesWhereRelPath do begin

      params.ParamValues['RelPath']:=ARelDirs[ACurrentIndex-1];

      Open();

      Result:=FieldByName('id').AsInteger;

      Close();

     end;


    end else

     begin
     // meaans public folder with id=-1;

      Result:=-1;

     end;

end;

end;




procedure TAddFoldersAndFilesToDB.GetInfoAboutFile(

ARelPath: string;
var fileName: string;
var fileSize: Int64;
var AbsPath:String

);



begin

AbsPath:=ExtractFilePath(Application.ExeName)+ARelPath;


ARelPath:=StringReplace(ARelPath,'\','/',[rfReplaceAll]);

fileName:=GetNameFromRelPath(ARelPath);
fileSize:=HTTPServer_Main_UnitVar.DataBaseUnitServer.GetFileSize(AbsPath);


end;

function TAddFoldersAndFilesToDB.GetNameFromRelPath( ARelPath:String ):String;

var SplittedString:TArray<String>;

begin
//
Result:='';

SplittedString:=ARelPath.Split(['/']);

if Length(SplittedString)>0 then Result:=SplittedString[High(SplittedString)];

end;


procedure TAddFoldersAndFilesToDB.InsertFolderOrFileToDB(

// Mainly for folders public/files/IDUser, without users_id, it will by null by default

  IsFolderParam:Boolean;
  idParent:Integer;
  nameToInsert:string;
  fileSize:integer;
  relPath:string;
  absPath:string

  );

var

    DateTime:TDateTime;
    DateTimeForMySQL:string;
    LastInsertedID:integer;

begin
  //

with HTTPServer_Main_UnitVar.DataBaseUnitServer do begin

   DateTime:=Now;
   DateTimeForMySQL:=FormatDateTime('yyyy-mm-dd hh:mm:ss',DateTime);


      with qInsertFolderOrFileNullUsers_id do begin

      Params.ParamValues['idParent']:=idParent;
      Params.ParamValues['name']:=nameToInsert;
      Params.ParamValues['relPath']:=relPath;
      Params.ParamValues['absPath']:=absPath;

      Params.ParamValues['creationDateTime']:=DateTimeForMySQL;
      Params.ParamValues['changesDateTime']:=DateTimeForMySQL;
      Params.ParamValues['lastAccessDateTime']:=DateTimeForMySQL;

      if IsFolderParam then
      Params.ParamValues['isFolder']:=1 else Params.ParamValues['isFolder']:=0;
      Params.ParamValues['fileSize']:=fileSize.ToString;

      ExecSQL;

      end;

end;


end;




procedure TAddFoldersAndFilesToDB.InsertFolderOrFileToDB(

// for files...

  IsFolderParam:Boolean;
  idParent:Integer;
  nameToInsert:string;
  users_id:integer;
  fileSize:integer;
  relPath:string;
  absPath:string

);

var

    DateTime:TDateTime;
    DateTimeForMySQL:string;
    LastInsertedID:integer;
    idFileType:integer;

begin
  //

with HTTPServer_Main_UnitVar.DataBaseUnitServer do begin

   DateTime:=Now;
   DateTimeForMySQL:=FormatDateTime('yyyy-mm-dd hh:mm:ss',DateTime);


      with qInsertFolderOrFile do begin

      Params.ParamValues['idParent']:=idParent;
      Params.ParamValues['name']:=nameToInsert;

      Params.ParamValues['relPath']:=relPath;
      Params.ParamValues['absPath']:=absPath;


      Params.ParamValues['creationDateTime']:=DateTimeForMySQL;
      Params.ParamValues['changesDateTime']:=DateTimeForMySQL;
      Params.ParamValues['lastAccessDateTime']:=DateTimeForMySQL;

      if IsFolderParam then

        begin

         // setting param to null
         with ParamByName('FileType_id') do begin
         DataType:=ftInteger;
         Clear();
         end;


        Params.ParamValues['isFolder']:=1
        end

      else

         // if IsFile
         begin
         //Check extension of File

            if FileTypeServer.IsFilePicture(absPath) then

            begin

             with qSelectFileTypeWhere do begin


             Params.ParamValues['FileType']:='Picture';
             Open();
             idFileType:=FieldByName('id').AsInteger;
             Close();
             end;

            Params.ParamValues['FileType_id']:=idFileType;
            end else


            if FileTypeServer.IsFileVideo(absPath) then

            begin

             with qSelectFileTypeWhere do begin

             Params.ParamValues['FileType']:='Video';
             Open();
             idFileType:=FieldByName('id').AsInteger;
             Close();
             end;

            Params.ParamValues['FileType_id']:=idFileType;
            end else



         if FileTypeServer.IsFileAudio(absPath) then

            begin

             with qSelectFileTypeWhere do begin

             Params.ParamValues['FileType']:='Audio';
             Open();
             idFileType:=FieldByName('id').AsInteger;
             Close();
             end;

            Params.ParamValues['FileType_id']:=idFileType;
            end else


           begin

             with qSelectFileTypeWhere do begin

             Params.ParamValues['FileType']:='Other';
             Open();
             idFileType:=FieldByName('id').AsInteger;
             Close();
             end;

            Params.ParamValues['FileType_id']:=idFileType;


           end;





         Params.ParamValues['isFolder']:=0;
         end;


      Params.ParamValues['users_id']:=users_id; // will be updated in different request
      Params.ParamValues['fileSize']:=fileSize.ToString;

      ExecSQL;

      end;


end;
end;



end.
