Pascal Library of Utilities - Quick development library (AutoMapper, LinQ, IOC Dependency Injection, MemoryCache, Scheduled tasks, Json and Yml Config and Options pattern, Serializers, etc) with crossplatform support for Delphi/Firemonkey (Windows,Linux,OSX/IOS/Android) and freepascal (Windows/Linux).

Turrican d5937a006e Merge remote-tracking branch 'origin/develop' into develop 6 lat temu
samples ca47d8f942 Quick.Config.Yaml sample updated 6 lat temu
.gitignore a18985dfcf updated gitignore 6 lat temu
Delphinus.Info.json 9714a2490e Delphinus support 7 lat temu
Delphinus.Install.json 82f247daeb delphinus install fixed 6 lat temu
LICENSE.txt 0b2f621aaf First release 7 lat temu
Quick.Amazon.pas 3f2e0fbdd3 fpc compatibility 7 lat temu
Quick.AppService.pas 349a336cb9 improved fpc linux compatibility 7 lat temu
Quick.Arrays.Helper.pas 9dbb4d55bd New Quick.Arrays.Helper 6 lat temu
Quick.Arrays.pas d8ec710499 Quick.Array new implicit 6 lat temu
Quick.AutoMapper.pas 0c1484af41 AutoMapper allow property paths 6 lat temu
Quick.Azure.pas 9578281c41 Quick.Azure small bug fixed 6 lat temu
Quick.Base64.pas 92213786c4 small correction 7 lat temu
Quick.Chrono.pas c34235a8f3 OSX/IOS partial support 6 lat temu
Quick.CloudStorage.Provider.Amazon.pas 4c5fabce18 TAnonymousThread added 6 lat temu
Quick.CloudStorage.Provider.Azure.pas 4c5fabce18 TAnonymousThread added 6 lat temu
Quick.CloudStorage.pas 4c5fabce18 TAnonymousThread added 6 lat temu
Quick.Commons.pas 418b422465 Merge remote-tracking branch 'turric4n/develop' into develop 6 lat temu
Quick.Compression.pas d74dfe17c5 small changes 6 lat temu
Quick.Config.Base.pas d4a6da6552 Quick.Config cleanup 6 lat temu
Quick.Config.Json.pas 1d4ecad868 Quick.Config.Json cleanup 6 lat temu
Quick.Config.Registry.pas 00eaed60f8 Quick.Config registry small changes 6 lat temu
Quick.Config.YAML.pas f94d07d50f New Quick.Config.YAML 6 lat temu
Quick.Console.pas ef03ce8fdc Quick.Console 6 lat temu
Quick.Crypto.pas 4c5fabce18 TAnonymousThread added 6 lat temu
Quick.Data.Custom.pas cff3cb74d9 Quick.Commons new functions 6 lat temu
Quick.Data.InfluxDB.pas cff3cb74d9 Quick.Commons new functions 6 lat temu
Quick.Expression.pas 8120a6e169 New unit Quick.Expression 6 lat temu
Quick.FileMonitor.pas b98c5eb3ca Quick.FileMonitor fpc small fix 6 lat temu
Quick.Files.pas 7e01a8a2bd Quick.Files new functions 6 lat temu
Quick.Format.pas 1a82f5a23c small changes 7 lat temu
Quick.HttpClient.pas bac215ce92 JsonHttpClient stream post method 6 lat temu
Quick.JSON.Helper.pas 0a4d952474 fpc compatibility improved 6 lat temu
Quick.JSON.Utils.pas 2496e473e9 Json.Utils bug fix not mswindows 6 lat temu
Quick.JSONRecord.pas 77c6290d36 Quick.JsonRecord load/save from/to json file 6 lat temu
Quick.Json.Serializer.pas 461dac461b Quick.Json.Serializer cleanup 6 lat temu
Quick.Json.fpc.Compatibility.pas 6b2c5892fb small change 7 lat temu
Quick.Linq.pas 962c0153cc New unit Quick.Linq 6 lat temu
Quick.Lists.pas e223a96a74 Quick.Lists compatibility improved 6 lat temu
Quick.Log.pas f3148d2ee2 Firemonkey OSX, IOS & Delphi Linux compatibility 6 lat temu
Quick.Network.pas 3f2e0fbdd3 fpc compatibility 7 lat temu
Quick.Process.pas a444a645b6 Quick.Process bug fix 7 lat temu
Quick.RTTI.Utils.pas da531502ba RTTI small fixes 6 lat temu
Quick.SMTP.pas 9f00a8f6aa Quick.smtp multi recipient separators 7 lat temu
Quick.Service.pas ff3541cb0a bug fixed 7 lat temu
Quick.SyncObjs.Linux.Compatibility.pas f3148d2ee2 Firemonkey OSX, IOS & Delphi Linux compatibility 6 lat temu
Quick.SysInfo.pas f3148d2ee2 Firemonkey OSX, IOS & Delphi Linux compatibility 6 lat temu
Quick.Threads.pas d5937a006e Merge remote-tracking branch 'origin/develop' into develop 6 lat temu
Quick.Value.RTTI.pas da531502ba RTTI small fixes 6 lat temu
Quick.Value.pas fa63b9b09e Quick.Value improved 6 lat temu
Quick.WMI.pas cff3cb74d9 Quick.Commons new functions 6 lat temu
Quick.WebBrowser.pas 0b2f621aaf First release 7 lat temu
Quick.YAML.Serializer.pas 51724261d7 Quick.Yaml linux compatibility 6 lat temu
Quick.YAML.pas d5517adbeb Quick.Yaml bug fix 6 lat temu
QuickLib.inc 722a02bdbe small changes 6 lat temu
QuickLib.png 9714a2490e Delphinus support 7 lat temu
README.md 104ffaba8d fixed Delphinus support 6 lat temu
WbemScripting_TLB.pas cff3cb74d9 Quick.Commons new functions 6 lat temu
quicklib.lpk e9a1e60edb quicklib fpc updated 6 lat temu
quicklib.pas 04d48b5c6d small changes 6 lat temu

README.md



QuickLib

Small delphi/Firemonkey(Windows, Linux, Android, OSX & IOS) and fpc(Windows & Linux) library containing interesting and quick to implement functions, created to simplify application development and crossplatform support and improve productivity.

Areas of functionality:

  • Mapping: Map fields from a class to other class, copy objects, etc..
  • Config: Thread your config as an object and load/save from/to file (Json/Yaml) or Windows Registry.
  • Serialization: Serialize objects to/from json/Yaml.
  • Scheduling: Schedule tasks launching as independent threads.
  • Threading: Simplify run and control of multithread background tasks, Thread-safe Lists, queues, etc
  • Data: Flexible data interchange and storage, allowing several input-output types.
  • Cloud: Simplify cloud Azure/Amazon file management, send emails and more.
  • Querying: Indexed Lists, Searchable Lists and Linq query system for generic lists and arrays.
  • Benchmark: Time elapsed control and benchmark functions.
  • Filesystem: Process and Services control, file modify monitors and helpers, etc...

Main units description:

  • Quick.Commons: Functions frequently needed in the day to day of a developer.
  • Quick.AppService: Allow a console app to run as console mode or service mode with same code simplifying debug tasks.
  • Quick.Azure/Amazon: Simplifies blob iteraction with Azure and Amazon Cloud Storage.
  • Quick.Network: CIDR and IP Range functions.
  • Quick.Chrono: Chronometer and Benchmark a piece of code is simple.
  • Quick.Console: Write log messages to console with colors and more...
  • Quick.Log: Log to disk or memory with verbose levels and daily or max space rotation.
  • Quick.Config: Load/Save a config as Json or Yaml file or Windows Registry keys and manage it as an object.
  • Quick.FileMonitor: Monitorizes a file for changes and throws events.
  • Quick.JsonUtils: Utils for working with json objects.
  • Quick.SMTP: Send email with two code lines.
  • Quick.Threads: Thread safe classes, scheduling and backgrounds tasks.
  • Quick.Process: Manages windows processes.
  • Quick.Services: Manages windows services.
  • Quick.Format: String format.
  • Quick.JsonSerializer: Serializes an object from/to json text. You can define if public or published will be processed (only Delphi, fpc rtti only supports published properties)
  • Quick.AutoMapper: Map fields from one class to another class. Allows custom mappings to match different fields and custom mapping procedure to cast/convert fields manually.
  • Quick.JsonRecord: Used as a DTO class, with json serialize and mapping functions included.
  • Quick.Lists: Improved lists with indexing or search features.
  • Quick.Value FlexValue stores any data type and allow pass to other class with integrated operators and autofrees.
  • Quick.Arrays: Improved arrays.
  • Quick.YAML: Yaml object structure.
  • Quick.YAML.Serializer: Serialize/Deserialize object from/to Yaml.
  • Quick.Expression: Evaluate object properties using expressions.
  • Quick.Linq: Makes Linq queries to any TObjectList, TList, TArray and TXArray, performing Select by complex Where like SQL syntax, update and order over your list.

    Updates:

    • NEW: Linq over generic lists and arrays.
    • NEW: QuickConfig YAML provider.
    • NEW: YAML Object and Serializer
    • NEW: AutoMapper customapping path namespaces style.
    • NEW: FlexArray, FlexPair & FlexPairArray.
    • NEW: AutoMapper mapping procedures (see documentation below)
    • NEW: JsonSerializer improved
    • NEW: TXArray: array like TList
    • NEW: Delphi Linux compatibility
    • NEW: QuickConfigJson reload if config file changed
    • NEW: First version with OSX/IOS partial support
    • NEW: Delphinus-Support

    Documentation:

    Quick.AppService: Allow a console app to run as console mode or service mode with same code simplifying debug tasks.

    if not AppService.IsRunningAsService then
    begin
        ...your code running as console
    end
    else
    begin
        AppService.ServiceName := 'MyService';
        AppService.DisplayName := 'MyServicesvc';
        //you can pass an anonymous method to events
        AppService.OnStart := procedure
                              begin
                                ...your start code
    	                      end;
        AppService.OnExecute := YourExecuteFunction;
        AppService.OnStop := YourStopFunction;
        AppService.CheckParams;
    end;
    

    Quick.Azure/Amazon: Simplifies blob iteraction with Azure and Amazon Cloud Storage.

    //connect to a Azure blobstorage
    QuickAzure := TQuickAzure.Create(AzureAccountName,AzureAccountKey);
    
    //download a blob file to a stream
    done := QuickAzure.GetBlob('MyContainer','MyFile.jpg',ResponseInfo,MyStream);
        
    //check if exists a folder
    found := ExistFolder('MyContainer','/Public/Documents/Personal');
        
    //list blobs starting with a pattern (recursively or not)
    for azBlob in ListBlobs('MyContainer','/Public/Documents',Recursive,ResponseInfo) do
    begin
        if azBlob.Size > 1000 then Showmessage(azBlob.Name);
    end;
    

    Quick.Network: CIDR and IP Range functions.

    //convert ip string to integer
    IPv4ToInt('192.168.1.10');
    
    //get first and last ip of a subnet scope
    GetIpRange('192.168.100.0','255.255.255.0',LowIp,HighIP);
    

    Quick.Commons: Functions frequently needed in the everyday of a developer.

    //coverts UTC time TDateTime to Local date time
    UTCToLocalTime(MyUTCTime);
        
    //generate a 10 char length random password with alfanumeric and signs.
    RandomPassword(10,[pfIncludeNumbers,pfIncludeSigns]);
    
    //Capitalize every word of a phrase
    CapitalizeAll('the grey fox'); //returns "The Grey Fox"
    
    //Simple TCounter and TTimeCounter for loops
    counter := TCounter;
    counter.Init(200);
    timecounter : TTimeCounter;
    timecounter.Init(10000);
    while true do
    begin
        Inc(n);
        {your procedural process here}
        //every 200 steps writes to console
        if counter.Check then writeln(Format('Processed %d entries',[n]));
        //every 10 seconds writes to console
        if timecounter.Check then writeln('Im working...'); 
    end;
    

    Quick.Chrono: Chronometer and Benchmark a piece of code is simple.

    //get elapsed time execution of a code part
    Chrono := TChronometer.Create(False);
    Chrono.Start;
    ...code you need benchmark
    Chrono.Stop;
    
    //shows elapsed time in LongTime format (2 hour(s) and 10 minute(s))
    Showmessage(Chrono.TimeElapsed(True));
    
    //shows elapsed time in ShortTime format (02:10:00)
    Showmessage(Chrono.TimeElapsed(False));
    //get benchmak info of a process
    Chrono := TChronoBenchMark.Create;
    Chrono.TotalProcess := 100000;
    for i := 1 to 10000 do
    begin
        {your process here}
        Chrono.CurrentProcess := i;
        //shows estimated time your process will take in x hour(s), x minute(s) x second(s) format
        writeln(Chrono.EstimatedTime(True));
        //shows speed: num items per second processed of your process
        writeln(Format('Items processed %d/sec',[Chrono.Speed]));
    end;
    writeln(Chrono.ElapsedTime(False)); //shows total time elapsed in 00:00:00 format
    

    Quick.Console: Write log messages to console with colors and more...

    //define which level of output needed
    Console.Verbose := LOG_DEBUG;
    
    //writes line to console in red color
    cout('Error x',etError); 
    
    //writes formatted line in green color
    coutFmt('Proccess %s finished',[ProccesName],etSuccess);
    
    //writes integer
    cout(12348);
    
    //Connect a QuickLog and write to disk and screen with one line of code (with independent verbose levels)
    MyQuickLog := TQuickLog.Create;
    MyQuickLog.Verbose := LOG_ALL;
    Console.Verbose := LOG_ONLYERRORS;
    Console.Log := MyQuickLog;
    

    Quick.Log: Log to disk or memory with verbose levels and daily or max space rotation.

    //write a header on start with info as running path, appname, debugmode, user, etc...
    Log.ShowHeader := True;
    
    //sets log with rotation at 20MB
    Log.SetLog('.\mylog.log',False,20);
    
    //write an error message
    Log.Add('Error x',etError);
    
    //write formatted error message
    Log.Add('Error is %s',[ErrorStr],etError);
    

    Quick.Config: Load/Save a config as Json or Yaml file or Windows Registry keys. Create a descend class from TAppConfigJson, TAppConfigYaml or TAppConfigRegistry and added published properties will be loaded/saved. Files configs can be reloaded on detect files changes.

    //create a class heritage
    TMyConfig = class(TAppConfigJson)
    private
        fName : string;
        fSurname : string;
        fStatus : Integer;
    published
        property Name : string read fName write fName;
        property SurName : string read fSurname write fSurname;
        property Status : Integer read fStatus write fStatus;
    end;
    
    //create your config to json file
    //Add Quick.Config.Json to your uses
    MyConfig := TMyConfig.Create('Config.json');
    MyConfig.Provider.CreateIfNotExists := True;
    MyConfig.Provider.ReloadIfFileModified := True;
    MyConfig.Name := 'John';
    MyConfig.Surname := 'Smith';
    //load
    MyConfig.Load;
    //save
    MyConfig.Save;
      
    //create your config to Windows Registry
    //Add Quick.Config.Registry to your uses
    MyConfig := TMyConfig.Create;
    //Define Registry as HKEY_CURRENT_USER\Software\MyApp
    MyConfig.HRoot := HKEY_CURRENT_USER; 
    MyConfig.MainKey := 'MyApp';
    MyConfig.Name := 'John';
    MyConfig.Surname := 'Smith';
    //load
    MyConfig.Load;
    //save
    MyConfig.Save;
    
    //Create a custom Config with no default provider
    TMyConfig = class(TAppConfig)
    ...your properties
    end;
    
    MyConfig := TMyConfig.Create(TAppConfigJsonProvider.Create('.\config.json');
    
    

    Quick.FileMonitor: Monitorizes a file for changes and throws events.

    FileMonitor.Filename := '.\myfile.txt';
    //check file changes every 2 seconds
    FileMonitor.Interval := 2000;
    //watch for deleted or modified file events
    FileMonitor.Notifies := [mnFileModified, mnFileDeleted)];
    FileMonitor.OnFileChange := MyFileChangeFunction;
    FileMonitor.Enabled := True;
    

    Quick.JsonUtils: Utils for working with json objects.

    //When unit declared in uses, a TObject Helper allows all your objects to be loaded or saved to/from json string
    MyObject.FromJson := jsonstring;
    MyString := MyObject.ToJson;
    
    //You can clone simple objects with clone function
    MyObject1.Clone(MyObject2);
    

    Quick.SMTP: Send email with two code lines.

    //Send email
    SMTP := TSMTP.Create('mail.domain.com',25,False);
    SMTP.SendMail('[email protected]','[email protected]','Email subject','My message body');
    
    //You can define more advanced options
    SMTP.SenderName := 'John';
    SMTP.From := '[email protected]';
    SMTP.Recipient := '[email protected],[email protected]';
    SMTP.Subject := 'Email subject';
    SMTP.AddBodyFromFile := '.\body.html';
    SMTP.CC := '[email protected]';
    SMTP.BCC := '[email protected]';
    SMTP.Attachments.Add('.\notes.txt');
    SMTP.SendMail;
    

    Quick.Threads: Thread safe classes.

    • TThreadedQueueCS: Version of TThreadedQueue with Critical Section.
    • TThreadObjectList: Thread safe Object List.
    • TThreadedQueueList: Thread safe Queue List. Autogrow and with Critical Section.
    • TAnonymousThread: Creates anonymous thread defining unchained Execute and OnTerminate methods. Use Execute_Sync and OnTerminate_Sync methods if code needs to update UI.

      • Execute: Specify code to execute on start.
      • Execute_Sync: Like Execute but runs code with syncronized thread method (avoids problems if your code updates UI).
      • OnTerminate: Specify code to execute when task finishes.
      • OnTerminate_Sync: Like OnTerminate but runs code with syncronized thread method (avoids problems if your code updates UI).
      • Start: Starts thread execution.

        //simple anonymousthread
        TAnonymousThread.Execute(
        procedure
        var
        i : Integer;
        begin
        for i := 0 to 10 do cout('Working %d',[i],etTrace);
        cout('executed thread',etSuccess);
        end)
        .OnTerminate(
        procedure
        begin
        cout('terminated thread',etSuccess);
        cout('PRESS <ENTER> TO EXIT',etInfo);
        end)
        .Start;
        
    • TBackgroundsTasks: Launch tasks in background allowing number of concurrent workers. Use AddTask_Sync and OnTerminate_Sync methods if code needs to update UI.

      • AddTask: Specify Task name, parameters to pass to anonymous method(If OwnedParams=true, task will free params on expiration task) and method than will be executed.
      • AddTask_Sync: Like AddTask but runs code with synchronize thread method (avoids problems if your code updates UI).
      • OnTerminate: Specify code to execute when task finishes.
      • OnTerminate_Sync: Like OnTerminate but runs code with syncronized thread method (avoids problems if your code updates UI).
      • OnException: Specify code to execute when task generates an exception.
      • Start: Starts tasks execution.

        backgroundtasks := TBackgroundTasks.Create(10);
        for i := 1 to 100 do
        begin
        mytask := TMyTask.Create;
        mytask.Id := i;
        mytask.Name := 'Task' + i.ToString;
        backgroundtasks.AddTask([mytask],False,
                              procedure(task : ITask)
                              begin
                                cout('task %d started',[TMyTask(task.Param[0].AsObject).Id],etDebug);
                                TMyTask(task.Param[0].AsObject).DoJob;
                              end
                            ).OnException(
                              procedure(task : ITask; aException : Exception)
                              begin
                                cout('task %d failed (%s)',[TMyTask(task.Param[0].AsObject).Id,aException.Message],etError);
                              end
                            ).OnTerminated(
                              procedure(task : ITask)
                              begin
                                cout('task %d finished',[TMyTask(task.Param[0].AsObject).Id],etDebug);
                                TMyTask(task.Param[0].AsObject).Free;
                              end
                            ).Run;
        end;
        backgroundtasks.Start;
        
    • TScheduledTasks: Alternative to Timer. You can assign tasks with start time, repeat options and expiration date. Use AddTask_Sync, OnTerminate_Sync and OnExpired_Sync if code needs to update UI. You can assign anonymous methods to execute, exception, terminate and expiration events.

    • Add a task to execute:

      • AddTask: Specify Task name, parameters to pass to anonymous method(If OwnedParams=true, task will free params on expiration task) and method than will be executed.
      • AddTask_Sync: Like AddTask but runs code with synchronize thread method (avoids problems if your code updates UI).
    • Define events to control:

      • OnTerminate: Specify code to execute when task finishes.
      • OnTerminate_Sync: Like OnTerminate but runs code with syncronized thread method (avoids problems if your code updates UI).
      • OnExpire: Specify code to execute when task expiration reached or task was cancelled.
      • OnExpire_Sync: Like OnExpire but runs code with synchronized thread method (avoids problems if your code updates UI).
      • OnException: Specify code to execute when task generates an exception.
    • Define when to start task:

      • StartNow: Start task immediately.
      • StartAt: Date and time to start task.
      • StartTodayAt: Start task today at defined time.
      • StartTomorrowAt: Start task tomorrow at defined time.
      • StartOnDayChange: Start task when day changes.
      • StartInMinutes: Start task after x minutes.
      • StartInSeconds: Start task after x seconds.
    • Define if needs to repeat or not (if not defined a previous StartAt, StartOn, etc, task will be executed immediately):

      • RunOnce: Task will be executed one time only.
      • RepeatEvery: Can indicate repeat step over time and expiration date.
      • RepeatEveryDay: Repeat task every day at same hour.
      • RepeatEveryWeek: Repeat task every week at same hour.
    • Start/Stop scheduler:

      • Start: Starts scheduler.
      • Stop: Stops scheduler.

        myjob := TMyJob.Create;
        myjob.Name := Format('Run at %s and repeat every 1 second until %s',[DateTimeToStr(ScheduledDate),DateTimeToStr(ExpirationDate)]);
        scheduledtasks.AddTask('Task1',[myjob],True,
                            procedure(task : ITask)
                            begin
                              cout('task "%s" started',[TMyTask(task.Param[0]).Name],etDebug);
                              TMyJob(task.Param[0]).DoJob;
                            end
                          ).OnException(
                            procedure(task : ITask; aException : Exception)
                            begin
                              cout('task "%s" failed (%s)',[TMyJob(task.Param[0]).Name,aException.Message],etError);
                            end
                          ).OnTerminated(
                            procedure(task : ITask)
                            begin
                              cout('task "%s" finished',[TMyJob(task.Param[0]).Name],etDebug);
                            end
                          ).OnExpired(
                            procedure(task : ITask)
                            begin
                              cout('task "%s" expired',[TMyJob(task.Param[0]).Name],etWarning);
                            end
                          ).StartAt(ScheduledDate
                          ).RepeatEvery(1,TTimeMeasure.tmSeconds,ExpirationDate);
        scheduledtasks.Start;
        

    Quick.Process: Manages windows processes.

    //kill explorer process
    KillProcess('explorer.exe');
    //determine if an application is running
    if IsProcessRunning('explorer.exe') then Showmessage('Explorer is running!');
    //get username who is running an exe
    writeln('Explorer.exe open by: ' + GetProcessUser('explorer.exe');
    //gets handle of a window with a 20 seconds timeout
    if FindWindowTimeout('MainWindow',20) then writeln('Window detected');
    

    Quick.Services: Manages windows services.

    //detect if a service is installed
    if not ServiceIsPresent('localhost','MySvc') then raise Exception.Create('Service not installed!');
    //Start a service
    ServiceStart('localhost','MySvc');
    //Uninstall a service
    ServiceUninstall('MySvc');
    

    Quick.Format: String format.

    //Format bytes to MB, GB, TB...
    FormatBytes(50000) //shows 50KB
    FormatBytes(90000000) //shows 90MB
    

    Quick.JsonSerializer: Serializes an object from/to json text. You can define if public or published will be processed (only Delphi, fpc rtti only supports published properties)

    json := '{"name":"Peter","age":30}';
    serializer := TJsonSerializer.Create(TSerializeLevel.slPublishedProperty);
    try
       serializer.JsonToObject(user,json);
    finally
       serializer.Free;
    end;
    

    Quick.AutoMapper: Map fields from one class to another class. Allows custom mappings to match different fields and custom mapping procedure to cast/convert fields manually.

    //Map values from User1 to User2
    TMapper<TUser2>.Map(User);
    
    //Map custom mappings
    AutoMapper := TAutoMapper<TUser,TUser2>.Create;
    
    //option1: you can define auto map different named properties
    AutoMapper.CustomMapping.AddMap('Cash','Money');
    AutoMapper.CustomMapping.AddMap('Id','IdUser');
    
    //option2: you can decide to modify each property manually or allow to auto someones
    AutoMapper.OnDoMapping := procedure(const aSrcObj : TUser; const aTargetName : string; out Value : TFlexValue)
                              begin
                                if aTargetName = 'Money' then Value := aSrcObj.Cash * 2
                                  else if aTargetName = 'IdUser' then Value := aSrcObj.Id;
                              end;
    
    //option3: you can modify some properties after automapping done
    AutoMapper.OnAfterMapping := procedure(const aSrcObj : TUser; aTgtObj : TUser2)
                                 begin
                                   aTgtObj.Money := aSrcObj.Cash * 2;
                                   aTgtObj.IdUser := aSrcObj.Id;
                                 end;
    
    User2 := AutoMapper.Map(User);
    

    Quick.JsonRecord: Used as a DTO class, with json serialize and mapping functions included.

    type
       TUser = class(TJsonRecord)
       private
          fName : string;
          fAge : Integer;
       published
          property Name : string read fName write fName;
          property Age : Integer read fAge write fAge;
       end;
    var
       user, user2 : TUser;
    begin
       user := TUser.Create;
       //show as json string
       Writeln(user.ToJson);
       //mapping to other class
       user.Mapto(User2);
       Writeln(user2.ToJson);
       //load from file
       user.LoadFromFile('.\user.json');
       //save to file
       user2.SaveToFile('.\user2.json');
    end;
    

    Quick.Lists: Improved lists with indexing or search features.

    • TIndexedObjectList: Allows fast hashed searches by object properties or fields.
    • TSearchObjectList: Allows iteration search by object properties or fields.

      var
      users : TIndexedObjectList<TUser>;
      begin
      users := TIndexedObjectList<TUser>.Create(True);
      //create index by property "Name"
      users.Indexes.Add('Name','Name',TClassField.cfProperty);
      //create index by private field "Id"
      users.Indexes.Add('Id','fId',TClassField.cfField);
      //get user by "Name" index
      writeln(users.Get('Name','Peter').SurName);
      end;
      

    Quick.Value FlexValue stores any data type and allow pass to other class with integrated operators and autofrees.

    var
      value : TFlexValue;
      str : string;
      num : Integer; 
    begin
      value := 'hello';
      str := value;
      value := 123;
      num := value;
    end;
    

    Quick.Arrays: Improved arrays.

    • TXArray: Array with methods like TList.

      var
      users : TXArray<TUser>;
      begin
      users.Add(User);
      if users.Count:= TIndexedObjectList<TUser>.Create(True);
      //create index by property "Name"
      users.Indexes.Add('Name','Name',TClassField.cfProperty);
      //create index by private field "Id"
      users.Indexes.Add('Id','fId',TClassField.cfField);
      //get user by "Name" index
      writeln(users.Get('Name','Peter').SurName);
      end;
      
    • TFlexArray: Array with methods like TList than can storage different value types into same array.

      var
      flexarray : TFlexArray;
      begin
      flexarray.Add(10);
      flexarray.Add('Hello');
      user := TUser.Create;
      try
        user.Name := 'Joe';
        flexarray.Add(user);
      
        cout('Integer Item = %d',[flexarray[0].AsInteger],etInfo);
        cout('String Item = %s',[flexarray[1].AsString],etInfo);
        cout('Record Item = %s',[TUser(flexarray[2]).Name],etInfo);
      finally
        user.Free;
      end;
      end;
      
    • TFlexPairArray: Array with methods like TList than can store different value types into same array, and search by item name.

      var
      flexarray : TFlexPairArray;
      begin
      flexarray.Add('onenumber',10);
      flexarray.Add('other','Hello boy!');
      user := TUser.Create;
      try
        user.Name := 'Joe';
        flexarray.Add('myuser',user);
      
        cout('Integer Item = %d',[flexarray.GetValue('onenumber').AsInteger],etInfo);
        cout('String Item = %s',[flexarray.GetValue('other').AsString],etInfo);
        cout('Record Item = %s',[TUser(flexarray.GetValue('myuser')).Name],etInfo);
      finally
        user.Free;
      end;
      end;
      

    Quick.YAML: Yaml object structure.

    • TYamlObject: A Yaml object is and array of YamlValue pairs.

      //create Yaml object from yaml text
      yamlobj.ParseYamlValue(aYaml)
      //add a pair
      yamlobj.AddPair('Name','Mike');
      //display as yaml structure
      Writeln(yamlobj.ToYaml);
      
    • TYamlArray: Array of objects or scalars.

      yamlarray.AddElement(TYamlPair.Create('Age',30));
      yamlobj.AddPair('myarray',yamlarray);
      
    • TYamlPair: Name-Value pair. Value can be object, array or scalar.

      n := yamlobj.GetPair('Name').Value as TYamlInteger;
      

    Quick.YAML.Serializer: Serialize/Deserialize object from/to Yaml.

      //Serialize
      text := YamlSerializer.ObjectToYaml(obj);
      //Deserialize
      YamlSerializer.YamlToObject(obj,yamltext);
    

    Quick.Expression: Evaluate object properties using expressions.

      if TExpressionParser.Validate(user,('(Age > 30) AND (Dept.Name = "Financial")') then
      begin
        //do something
      end;
    

    Quick.Linq: Makes Linq queries to any TObjectList, TList, TArray and TXArray, performing Select by complex Where like SQL syntax, update and order over your list.

      //Select multi conditional
      for user in TLinq<TUser>.From(userslist).Where('(Name = ?) OR (SurName = ?) OR (SurName = ?)',['Peter','Smith','Huan']).Select do
      begin
        //do something
      end;
      
      //Select like and update field
      TLinq<TUser>.From(userlist).Where('SurName Like ?',['%son']).SelectFirst.Name := 'Robert';
      
      //Select top and Order by field
      for user in TLinq<TUser>.From(userlist).Where('Age > ?',[18]).SelectTop(10).OrderBy('Name') do
      begin
        //do something
      end;
      
      //update fields by conditional
      TLinq<TUser>.From(userlist).Where('Name = ?',['Peter']).Update(['Name'],['Joe']);
      
      //count results
      numusers := TLinq<TUser>.From(userlist).Where('(Age > ?) AND (Age < ?)',[30,40]).Count;