Posted on 6,861 Comments

FireDAC Memory Table

FireDAC FDMemTable is an in-memory dataset component that allows the storage of data in table format in local memory. It does not require any database connection so it is very handy on many occasions.

In order to use it, just the fields have to be defined and ready for actions like add, edit, delete records. It can be used for storing data from external files like csv for temporary manipulations.

A. Create fields in memory table

Var
FDMemTable1 : TFDMemTable;

begin;
with FDMemTable1.FieldDefs do
begin
Add(‘EmpID’, ftInteger, 0, True);
Add(‘EmpName’, ftString, 50, False);
end;

FDMemTable1.CreateDataset;
FDMemTable1.Open;
end;

B. Add/Edit data in memory table

with FDMemTable1 do
begin
Append;
//Edit;
Fields[0].AsInteger := 1;
Fields[1].AsString := ‘Surendra’;
Post;
end;

C. Deleting data from memory table

FDMemTable1.Delete;

D. Delete all records from memory table

FDMemTable1.EmptyDataset;

E. Sorting Data
Use Index for sorting. So we can use property Indexes, IndexDefs or IndexFieldNames.

FDMemTable1.IndexFieldNames := ‘AcctID ASC’;

Or

FDMemTable1.IndexDefs.Add(‘Index1’, ‘AcctID’, [ixPrimary]);
FDMemTable1.IndexName := ‘Index1’;

Or

F. Find Data
Just like in other dataset use Locate, Lookup and Find methods to find a specific record.

Locate
FDMemTable1.Locate(‘AcctID’, 1, []);

Or

FDMemTable1.Locate(‘Name’, ’Surendra’, [loCaseInsensitive]);

Lookup

var
sName: string;
sName := FDMemTable1.Lookup(‘AcctID’, 1, ‘Name’);

FindKey
Findkey will work if only any Index is applied

FDMemTable1.FindKey([1]);
FDMemTable1.FindFirst;
FDMemTable1.FindLast;
FDMemTable1.FindNext;
FDMemTable1.FindPrev;

G. Filtering Data

FDMemTable1.Filtered := False;
FDMemTable1.Filter := ‘AcctID=1’;
FDMemTable1.Filtered := True;

H. Copy data from one FDMemTable to another

The most simple way to copy the structure and data from a TdataSet or a TFDMemTable to another TFDMemTable is to use the CopyDataSet method:

FDMemTable1.CopyDataSet(SourceFDMemTable2, [coStructure, coRestart, coAppend]);
FDMemTable1.CopyDataSet(SourceDataset2, [coStructure, coRestart, coAppend]);

Data property

// UniDirectional must be false

FDQuery1.FetchOptions.Undirectional := False;
FDQuery1.Sql.Text := ‘select * from Account’;
FDQuery1.Open;
FDMemTable1.Data := FDQuery1.Data;
FDMemTable1.First;
while not FDMemTable1.Eof do
begin
FDMemTable1.Edit;
// other codes
FDMemTable1.Post;
FDMemTable1.Next;
end;

I. Difference between CopyDataset and Data property

  1. CopyDataSet can copy from a non-FireDAC dataset but Data property allows you to copy data only from a FireDAC dataset.
  2. CopyDataSet works through TDataSet firing appropriate events but Data property works through no events are fired.
  3. CopyDataSet copies only current field values but Data property copies all record field versions and preserves the row state (inserted, deleted, updated, or unchanged).

Assigning values to Data is much faster than CopyDataSet.

Optimize the performance of TFDMemTable
Set the following properties LogChanges, FetchOptions, ResourceOptions, and UpdateOptions, DisableControls.

FDMemTable1.LogChanges := False;
FDMemTable1.ResourceOptions.SilentMode := True;
FDMemTable1.UpdateOptions.LockMode := lmNone;
FDMemTable1.UpdateOptions.LockPoint := lpDeferred;
FDMemTable1.UpdateOptions.FetchGeneratorsPoint := gpImmediate;
FDMemTable1.DisableControls;
FDMemTable1.BeginBatch;
try
for i := 1 to 100 do begin
FDMemTable1.Append;
//other codes
FDMemTable1.Post;
end;
finally
FDMemTable1.EndBatch;
FDMemTable1.EnableControls;
end;

Posted on 11,433 Comments

When do I write the console application?

Server-side automation

Console applications are executed from the command line without any user interfaces. Therefore, console applications are a very effective way of performing tasks on a regular basis without any user interaction. I write it when there are requirements for such a type of automation.

Automation not only helps to speed up the workflow but also helps to avoid errors. Manually executed tasks are always risky. You don’t know who does them and if the person is not experienced with these tasks, it can lead to errors. By automating tasks, you save yourself from making that type of mistake.

Fast Coding

Creating a console application is much faster than creating an application including a user interface. There are a lot of questions regarding user interface, color combination, user experiences, etc. for an application with a user interface. A console application does not need to consider such requirements. Just to concentrate on functional requirements.

Robustness

Once created, a console application does not have to be changed unless the requirements change. Console applications do not need to change with every new shiny framework, or tool that’s trending right now.

Conclusion

I write console applications when certain functions to be performed on a regular basis which can be executed without user interactions. It makes it flexible, easy to modify and add functionality when needed.

Posted on 1,998 Comments

Memory Leak and Solution

What is Memory Leak

memory leak is a kind of resource consumption that occurs when the code does not manage memory allocations while creating the objects. So in order to manage it, the memory used by the object created should be released when not needed. For example, if you call a function or procedure where the object is created and not released then it goes on consuming memories due to multiple calls from the calling programme. A memory leak may also happen when an object is stored in memory but cannot be accessed by the running code.

This could be a serious issue when the system or service is used for 24x7x365 without addressing it. If not handled it will slow down the system by consuming all resources and finally hangs the system.

How to solve it

There are several third party tools available but the simple solution solution is to release or free the used components or objects when not needed while exiting the funtion procedure.

Example:

procedure DoSomething;
var sl : TStringList;
begin
  sl := TStringList.create()
  try
    try
      // code that may raise exception
      sl.Add('suren');
      sl.Add('sujan');
    except
      ShowMessage('Error occured !');
    end;
  finally
    // Free all memory used in this block
    sl.free;
  end;
end;

Note that there are two try blocks are used in above code. They are different and serve two different purposes. First try is used to make all objects free and the second try is used to trap the errors.

The finally block will always be executed, even if there is no exception, while the except block is only executed when there is an exception.

The finally block is even executed when you exit the function early using Exit in a try-finally block.

The except block is meant to handle the exception(s), while the finally block is not. The finally block is meant to contain code that should be executed regardless of an exception, i.e. mainly to protect resources. That is why you should do:

s := b.Create;
try
  // Code that may raise an exception.
finally
  s.Free; // Free resource, even if there was an exception.
          // Exception is NOT handled.
end;

and:

try
  // Code that may raise an exception.
except
  // Handle the kind of exceptions you can handle.
end;

combined :

try
  try
    // code that may raise exception
  except
    // Handle Exception;
  end;
finally
    // Free all memory used in this block
end;

Note the finally block is not limited to memory management. It can be used for other actions like restoring/undo/close opened files, close open connections, shut down hardware that was started etc.

Posted on 2,751 Comments

System Error 5

While installing Windows Services, you may get “System error 5 has occurred”  Error or “EOSError Code: 5 Access Denied” Error. This error was due to insufficient permission to run command. The easiest way to run Command Prompt as an administrator is to find the “command prompt” in Search and once you find it, right-click on the “Command Prompt” and then Choose “Run as administrator” to run it with administrative privileges.

Another option is to run in command prompt as below:

C:\net user administrator /active:yes

It is also possible to run netplwiz to solve this error

Posted on 32 Comments

Delphi Service Application

Windows Service Application

What is Windows Service?

Microsoft Windows service is an application software which runs in the background. Service applications accept requests from client applications, process those requests, and return information to the client applications. As it runs in the background, it does not require user input interaction. These services can be automatically started when the computer boots, can be paused and restarted, and do not show any user interface. The service can have multiple methods to execute at the background level. So it can be used for different background processing like checking system update, processing routines, validations of data etc.

Why do we need it?

Windows services are needed when an application needs to continuously run without user interaction. Services runs until it is stopped or the computer is turned off. When the system needs to respond 24/7/365, then Windows Services Applications are used. When it is running, it is capable of getting requests from clients and return the response.

What are its limitations?

Service Application does not allow to use visual components. Only non-visual components are allowed in service applications. Besides that every processing in the background can be achieved.

When there is a requirement of huge data communication between client and server, DataSnap will be the right choice as it is more flexible and can be deployed as Windows services and Web Services usiing IIS, Apachy and even standalone server.

Posted on 10,487 Comments

How to Create a Console Application that Accepts Command-Line parameters in Delphi

Steps: In the Delphi IDE, choose File/New/Console Application. Then write

program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;

begin
// Following code you have to write

if ParamCount = 0 then
begin
Writeln(‘No parameters passed.’);
end;
if ParamCount = 1 then
begin
Writeln(‘One Parameter passed!’);
Writeln(ParamStr(1));
end;
if ParamCount = 2 then

begin
Writeln(‘Two Parameters passed!’);
Writeln(ParamStr(1));
Writeln(ParamStr(2));
end;
if ParamCount > 2 then
Writeln(‘More than Two Parameters passed!’);
end.

Compile.

Run CMD and go to directory where you saved the project

In Command Prompt

c:\TestConsole\Project1 “hello world”

One parameter passed

hello world

c:\TestConsole\Project1 “hello” “world”

Two Parameter passed

hello

world