Showing posts with label Delphi. Show all posts
Showing posts with label Delphi. Show all posts

Tuesday, 3 December 2013

How to use CreateProcess API Call to create and execute a new process in Delphi XE4?

How to use CreateProcess API Call to create and execute a new process in Delphi XE4?

Executing a program or process in Win32 means loading a process and its child thread(s) in memory. CreateProcess is used to create and run the process in Win32. We will see how to use CreateProcess in Delphi XE4 to execute an exe? For backward compatibility, the Win16 calls for executing programs, WinExec and ShellExecute are still supported in the Windows API, and still work. But for 32-bit programs, they're considered obsolete.

The following code utilizes the CreateProcess API call, and will execute any program, DOS or Windows.

procedure ExecuteNewProcess(ProgramName : String; Wait: Boolean);
var
  StartInfo : TStartupInfo;
  ProcInfo : TProcessInformation;
  CreateOK : Boolean;
begin 
  FillChar(StartInfo,SizeOf(TStartupInfo),#0);
  FillChar(ProcInfo,SizeOf(TProcessInformation),#0);
  StartInfo.cb := SizeOf(TStartupInfo);
  
  CreateOK := CreateProcess(nil, PChar(ProgramName), nil, nil,False,
              CREATE_NEW_PROCESS_GROUP+NORMAL_PRIORITY_CLASS,
              nil, nil, StartInfo, ProcInfo);

  try
    if CreateOK then //Check if the process is created successfully
    begin
      if Wait then WaitForSingleObject(ProcInfo.hProcess, INFINITE); //Load children processes
    end
    else
    begin
      ShowMessage('Unable to run '+ProgramName);
    end;
  finally
    CloseHandle(ProcInfo.hProcess);
    CloseHandle(ProcInfo.hThread);
  end;
end;

In above code, I will pass an executable file to ExecuteNewProcess method lets say abc.exe.

Relation between Threads and Processes

Here it is very important to mention the relation between threads and processes. Threads are children of processes; while processes, on the other hand, are inert system entities that essentially do absolutely nothing but define a space in memory for threads to run - threads are the execution portion of a process and a process can have many threads attached to it. So, we can say, processes are merely memory spaces for threads.

Friday, 29 November 2013

How to use TpFIBDataSet, TpFIBQuery and TpFIBTransaction FIBPlus components to connect with Firebird / Interebase database in Delphi XE4?

How to use TpFIBDataSet, TpFIBQuery and TpFIBTransaction FIBPlus components to connect with Firebird / Interebase database in Delphi XE4?

Following is the basic article on Firebird / Interbase database connectivity in Delphi XE4 using FIBPlus database components like TpFIBDataSet, TpFIBQuery and TpFIBTransaction. I will explain all these FIBPlus database components in detail. I have written a small article on TpFIBDatabase before this article. Please go through that before reading this one. Read FIBPlus TpFIBDatabase...

FIBPlus TpFIBQuery Component

An application works with a database by issuing SQL instructions. They are used to get and modify data\metadata. FIBPlus has a special TpFIBQuery component responsible for SQL operator execution. This robust, light and powerful component can perform any actions with the database. 

TpFIBQuery is very easy-to-use: just set the TpFIBDatabase component, fill in the SQL property and call any ExecQuery method (ExecQueryWP, ExecQueryWPS). 

NOTE: The tpFIBQuery is not a TDataset descendant, so it does not act in exactly the same way or exhibit the same methods / properties as you would expect to find in a dataset. 

The example below will show how to create TpFIBQuery dynamically at run-time and thus get data about clients.

 var sql: TpFIBQuery;
 sql := TpFIBQuery.Create(nil);
 with sql do
 try
 Database := db;
 Transaction := db.DefaultTransaction;
 SQL.Text := 'select first_name, last_name from customer';
 ExecQuery;
 while not Eof do begin
 Memo1.Lines.Add(
 FldByName['FIRST_NAME'].AsString+' '+
 FldByName['LASTST_NAME'].AsString);
 Next; end;
 sql.Close;
 finally
 sql.Free;
 end;

FIBPlus TpFIBDataSet component

The TpFIBDataSet component is responsible for work with datasets. It is based on the TpFIBQuery component and helps to cache selection results. TpFIBDataSet is a TDataSet descendant so it supports all TDataSet properties, events and methods.

TpFIBDataSet enables you to select, insert, update and delete data. All these operations are executed by TpFIBQuery components in TpFIBDataSet. 

To select data you set the SelectSQL property. It’s similar to setting the SQL property of the QSelect component (TpFIBQuery type). Define the InsertSQL.Text property to insert data, UpdateSQL.Text to update, DeleteSQL.Text to delete and RefreshSQL.Text to refresh the data. 

Here is a demo database employee.gdb (or .fdb for Firebird) to show how to write Select SQL and get a list of all employees. I will write all queries in InsertSQL, UpdateSQL, etc.

with pFIBDataSet1 do begin
 if Active then Close;

 SelectSQL.Text := 'select CUST_NO, CUSTOMER, CONTACT_FIRST, CONTACT_LAST from CUSTOMER';

 InsertSQL.Text := 'insert into CUSTOMER(CUST_NO, CUSTOMER, CONTACT_FIRST,                                           CONTACT_LAST )' + 
                              ' values (:CUST_NO, :CUSTOMER, :CONTACT_FIRST, :CONTACT_LAST)';

 UpdateSQL.Text := 'update CUSTOMER set CUSTOMER = :CUSTOMER, '+
                   'CONTACT_FIRST = :CONTACT_FIRST, CONTACT_LAST = :CONTACT_LAST '+
                   'where CUST_NO = :CUST_NO';

 DeleteSQL.Text := 'delete from CUSTOMER where CUST_NO = :CUST_NO';

 RefreshSQL.Text := 'select CUST_NO, CUSTOMER, CONTACT_FIRST, CONTACT_LAST '                                       + 'from CUSTOMER where CUST_NO = :CUST_NO';

 Open;
end;

To open TpFIBDataSet either execute Open/OpenWP methods or set the Active property to True. To close TpFIBDataSet call the Close method

FIBPlus TpFIBTransaction component

A transaction is an operation of database transfer from one consistent state to another. All operations with the dataset (data/metadata changes) are done in the context of a transaction. To understand special FIBPlus features completely you need to know about InterBase / FIBPlus transactions. 

All the changes done in the transaction can be either committed (in case there are no errors) by Commit or rolled back (Rollback). Besides these basic methods TpFIBTransaction has their context saving analogues: CommitRetaining and RollbackRetaining, i.e. on the client side, these will not close a TpFibQuery or TpFibDataset.

To start the transaction you should call the StartTransaction method or set the Active property to True. To commit the transaction call Commit/CommitRetaing, to roll it back - Rollback/RollbackRetaining. 

TpFIBQuery and TpFIBDataSet components have some properties which help to control transactions automatically. In particular they are: the TpFIBDataSet.AutoCommit property; the poStartTransaction parameter in TpFIBDataSet.Options; qoStartTransaction and qoCommitTransaction in TpFIBQuery.Options.

TpFIBTransaction has three basic transaction types: 
tpbDefault, 
tpbReadCommited, 
tpbRepeatableRead. 

At design time you can also create special types of your own in the TpFIBTransaction editor and use them as internal ones. Set the transaction type to set its 
parameters:

TpbDefault – parameters must be set in TRParams
tbpReadCommited – shows the ReadCommited isolation level
tbpRepeatableRead – shows the RepeatableRead isolation level 

How to use TpFIBDatabase FIBPlus Component to connect with Firebird database in Delphi XE4?

How to use TpFIBDatabase FIBPlus Component to connect with Firebird database in Delphi XE4?

TpFIBDatabase component is used to make database connectivity with Firebird database in Delphi. For using TpFIBDatabase component, you should have FIBPlus and Firebird installed on your system. I am using Delphi XE4, Firebird 2.5.2 and FIBPlus 7.5 to make database connection.

Connection parameters are typical for InterBase/Firebird server:

1) path to a database file;
2) user name and password;
3) user role;
4) charset;
5) dialect;
6) client library (gds32.dll for InterBase and fbclient.dll for Firebird).

To connect to a database you should call the Open method or set the Connected property to True. It’s also possible to use this code to connect to a database:

function Login(DataBase: TpFIBDatabase; dbpath, uname, upass, urole: string): Boolean;
begin
 if DataBase.Connected then DataBase.Connected := False; 
 with FDataBase.ConnectParams do begin
   UserName := uname;
   Password := upass;
   RoleName := urole;
 end;
 DataBase.DBName := dbpath;
 try DataBase.Connected := True;
 except
   on e: Exception do
   ShowMessage(e.Message);
 end;
 Result := DataBase.Connected;
end;

To close the connection either call the Close method or set the Connected property to False. 

You can also close all datasets and connected transactions at once:

procedure Logout(DataBase: TpFIBDatabase);
var i: Integer;
begin
  if not DataBase.Connected then
  Exit;

  for i := 0 to DataBase.TransactionCount - 1 do
    if TpFIBTransaction(DataBase.Transactions[i]).InTransaction then 
      TpFIBTransaction(DataBase.Transactions[i]).Rollback
 DataBase.CloseDataSets;
 DataBase.Close;
end;

Friday, 27 September 2013

Filename Extensions in Delphi

Filename Extensions in Delphi

There are various types of files with different filename extensions in a Delphi project like pas, dcu, dfm, exe, dll, dpr, res, dpk, dcp, bpl etc. Some of these files are source files and some are binary files. These files are required by Delphi for various reasons. Lets discuss each Delphi file one by one.

.PAS - Delphi Source File

In Delphi, PAS files are always the source code to either a unit or a form. Unit source files contain most of the code in an application. The unit contains the source code for any event handlers attached to the events of the form or the components it contains. We may edit .pas files using Delphi's code editor. Do not delete .pas files.

.DCU - Delphi Compiled Unit

A compiled unit (.pas) file. By default the compiled version of each unit is stored in a separate binary-format file with the same name as the unit file, but with the extension .DCU (Delphi compiled unit). For example unit1.dcu contains the code and data declared in the unit1.pas file. When you rebuild a project, individual units are not recompiled unless their source (.PAS) files have changed since the last compilation, or their .DCU files cannot be found. Safely delete .dcu file because Delphi recreates it when you compile the application.

.DFM - Delphi Form

These files are always paired with .pas files. DFM file contains the details (properties) of the objects contained in a form. It can be view as text by right clicking on the form and selecting view as text from the pop-up menu. Delphi copies information in .dfm files into the finished .exe code file. Caution should be used in altering this file as changes to it could prevent the IDE from being able to load the form. Form files can be saved in either binary or text format. The Environment Options dialog lets you indicate which format you want to use for newly created forms. Do not delete .dfm files.

.DPR - Delphi Project

The .dpr file is the central file to a delphi project (one .dpr file per a project), actually a Pascal source file. It serves as the primary entry point for the executable. The dpr contains the references to the other files in the project and links forms with their associated units. Although we can modify the .dpr file , we should not modify it manually. Do not delete .dpr files.

.RES - Windows Resource File

A Windows resource file, generated automatically by Delphi and required by the compilation process. This binary-format file contains the version info resource (if required) and the application’s main icon. File may also contain other resources used within the application but these are preserved as is.

.EXE - Application Executable

The first time we build an application or a standard dynamic-link library, the compiler produces a .DCU file for each new unit used in your project; all the .DCU files in your project are then linked to create a single .EXE (executable) or .DLL file. This binary-format file is the only one (in most cases) you have to distribute to your users. Safely delete your projects .exe file because Delphi recreates it when you compile the application.

.DLL - Application Extension

Code for dynamic link library. A dynamic-link library (DLL) is a collection of routines that can be called by applications and by other DLLs. Like units, DLLs contain sharable code or resources. But a DLL is a separately compiled executable that is linked at runtime to the programs that use it. Do not delete .dll file unless you wrote it. 

.DPK - Delphi Package

This file contains the source code for a package, which are most often collection of multiple units. Package source files are similar to project files, but they are used to construct special dynamic-link libraries called packages. Do not delete .dpk files.

.DCP

This binary image file consists of the actual compiled package. Symbol information and additional header information required by the IDE are all contained within the .dcp file. The IDE must have access to this file in order to build a project. Do not delete .dcp files.

.BPL or .DPL

This is the actual design-time or run-time package. This file is a Windows DLL with Delphi-specific features integrated into it. This file is essential for deployment of an application that uses a package. In version 4 and above this is 'Borland package library' in version 3 it's 'Delphi package library'. 

.~?? - Delphi Backup Files

Files with names ending in .~?? (e.g. unit2.~pa) are backup copies of modified and saved files. Safely delete those files at any time, however you might want to keep the for recovering damaged programming.

Delphi 7 to Delphi XE4 Code Migration Issues, Error, Warning and Hints

Delphi 7 to Delphi XE4 Code Migration Issues, Error, Warning and Hints

When I was migrating my old Delphi 7 code to new Delphi XE4, I got a lot code migration issues, errors, warning and hints. I resolved all the errors, warnings and hints by putting a lot of efforts. By this post, I want to share my experience of Delphi code migration. I had mentioned the list of errors which I got during migrating my code from Delphi 7 to Delphi XE4 in my last post. In this post, I will mention the list of compiler warning and hints which I got and resolved during Delphi 7 to Delphi XE4 code migration. Here is my list of compiler warning and hints:

1. Symbol is specific to platform

Some symbols work only in Windows platform but not on Linux, Mac etc. If your application is specific to windows platform only, you need not to consider this compiler warning.

2. Symbol is deprecated

If you get "Symbol is deprecated" compiler warning while migration the old delphi code to the newer versions of Delphi, you need to replace the methods with the newer versions.

3. Redeclaration hides a member in the base class

This compiler warning comes when base class variables are re-declared in derived class due to which base class variables become hidden. 

4. Method hides virtual method of base type

This compiler warning comes when base class methods are re-declared in derived class due to which base class methods become hidden. 

5. Constructing instance of 'TMyClass' containing abstract method 

This compiler warning comes when abstract methods are defined in the class. So when object of such class is created, compiler throws this warning.

6. Return value of function might be undefined

This compiler warning comes when return value is assigned under some conditions in functions. If conditions are met, only then function returns the value otherwise return value remains undefined. 

7. Variable might not have been initialized

This compiler warning comes when variables are assigned conditionally in a function or procedure. If condition is not met, variables remain uninitialized.

8. FOR-Loop variable may be undefined after loop

Variable is declared before FOR loop and used after FOR loop. Compiler throws warning because there might be some scenario when variable is not initialized within the FOR loop. 

9. WideChar reduced to byte char in set expressions

Use CharInSet function to resolve the warning.

10. Private symbol declared but never used

This compiler hint comes when function is declared and implemented in the unit but not called within the unit. 

11. Inline function has not been expanded because unit 'System.Types' is not specified in USES list

You will get this hint while migrating the old delphi code to the newer versions of Delphi.  Add System.Types in uses and hint will get resolved.

Delphi Assert Function - A Debugging Tool in Delphi

Delphi Assert Function - A Debugging Tool in Delphi

Assert function in Delphi is used as a debugging tool. Assert Function is used to make sure that certain conditions which are assumed to be true are never violated. Assert is a Symbol not a Keyword in Delphi. You can set Assertion ON/OFF in RAD Studio.

Syntax of Assert Function:

function Assert(expr : Boolean [; const msg: string]);

Assert function tests whether a boolean expression expr is true. If not, Assert raises an EAssertionFailed exception. If a message string was passed to Assert, the exception object is created with that string (Exception.CreateFmt).

Assert provides an opportunity to intercept an unexpected condition and halt a program rather than allow execution to continue under unanticipated conditions.

Code Snippet for Assert Function

procedure TestAssert;
var
  i : integer;
begin
   i:=5;
   assert(i<2,'Assert Message');
end;

Now when you run the above Delphi code with Assertions enabled, you will get message 'Assert Message' because 'i<2' is false. If i = 1, the program will continue as nothing happened.

ASSERT is not a KEYWORD in DELPHI

Assert is not a keyword in Delphi. Assert is the symbol that is not reserved by the compiler. Assert exists as symbol within the "System" unit namespace. You can create your own Assert procedure or function and even though it's not recommended, it will compile.

Assertion Settings in Delphi

We can put settings in the RAD Studio to tell the compiler whether to compile with assertions in a debug mode or not. Assertion are always "ON" in debug mode and "OFF" in release mode by default. Compiler directives are provided to disable the generation of assertion code: $ASSERTIONS ON/OFF(long form) 

Firebird Basic Interview Questions and Answers

Firebird Basic Interview Questions and Answers

If you are going to appear in a firebird technical interview, you must go through following basic firebird interview questions and answers. These are very basic questions on firebird database like general introduction to firebird, features of firebird database, similarities and differences between firebird and interbase, IBExpert tool for Firebird, firebird database connectivity etc. Following are the firebird interview questions and answers.

1. What do you know about Firebird database?

You should know general things about the Firebird database like: 

A) Firebird is open source database
B) It runs on Windows, Linux and Unix
C) Some Facts, Figures and Features of Firebird database

Read more for further details...

2. What are the various features of Firebird database?

You should be aware of the features and functionalities Firebird database provides like:

1. Firebird supports multiple platforms like Windows, Linux and Unix
2. Multi-generation architecutre of Firebird database
3. Powerful and developer-friendly SQL language
4. Logging and monitoring features of Firebird database
5. Security and Performance of Firebird and much more.

Read more for further details...

3. What is the difference and similarities between Firebird and Interbase databases?

You must prepare this interview questions because Firebird and Interbase databases are closely related. There are a lot of difference and similarities between Firebird and Interbase databases. I have written a complete article on this. You can access it here.

4. What is IBExpert?

IBExpert is a professional Integrated Development Environment (IDE) for the development and administration of InterBase and Firebird databases. IBExpert includes many coding tools and features: visual editors for all Database Objects, an SQL Editor and Script Executive, a Debugger for Stored Procedures and Triggers, a Query Builder, a powerful Database Designer and much, much more...

5. How to connect with Firebird database in Delphi using TSQLConnection?

This question is related to Delphi developers. TSQLConnection component is used to connect with firebird in Delphi. Below is code snippet for making firebird database connection in Delphi.

begin
  SQLConnection1.ConnectionName := 'Devart InterBase';
  SQLConnection1.DriverName := 'DevartInterBase';
  SQLConnection1.GetDriverFunc := 'getSQLDriverInterBase';
  SQLConnection1.Params.Values['LibraryName'] := 'dbexpida40.dll';
  SQLConnection1.Params.Values['VendorLib'] := 'fbclient.dll';
  SQLConnection1.Params.Values['HostName'] := 'hostname';
  SQLConnection1.Params.Values['Database'] := 'databasename';
  SQLConnection1.Params.Values['User_Name'] := 'username';
  SQLConnection1.Params.Values['Password'] := 'password';
  SQLConnection1.LoginPrompt := False;
  SQLConnection1.Open;
end;

6. Have you ever found the compiler error "Unsupported on-disk structure for file xxx.fdb" while working with Firebird database?

This is the common error occurs in most of the cases when you are using both firebird and interbase. Sometimes mismatch happens between gds32.dll (interbase driver dll) and fbclient.dll (firebird driver dll) which causes this error. There is detailed solution of this error discussed here.

Beside all the above firebird interview questions and answers, you should prepare general database concepts like joins, index, query optimization, stored procedures and functions, triggers, cursors etc. 

Wednesday, 25 September 2013

List of Errors and Compiler Warnings while code migration from Delphi 7 to Delphi XE4 - Part 1

List of Errors and Compiler Warnings while code migration from Delphi 7 to Delphi XE4 - Part 1

I had to migrate a Delphi 7 application to the Delphi XE4. While migrating my Delphi 7 application to Delphi XE4, I encountered a lot of compiler errors, warnings and hints. I made a list of all the compiler errors and warning with their solutions which I got during migration from Delphi 7 to Delphi XE4. I think I should share my list and experience with all you Delphi guys. 

Basically, you will get all these compiler errors and warnings when you are migrating the code from your Delphi application which is earlier than Delphi 2009 to Delphi 2009 or the higher versions of Delphi. Most of the errors are related to unicode strings. Delphi 7 does not support unicode because unicode support in Delphi was introduced in Delphi 2009.

Here goes my list of errors and compiler warnings which I got and resolved during Delphi 7 to Delphi XE4 code migration.

1. Mismatched datatypes like AnsiChar / AnsiPChar / AnsiString 

In my Delphi 7 code, a lot of AnsiChar, AnsiPChar and AnsiString keywords were used which were causing problems. So I converted them to WideChar (Char), Unicode String (String) and WidePChar (PChar) for unicoding.

2. Index 0 is not accessible in string

In Delphi 7, there is 0 based string indexing while in Delphi XE4, there is 1 based string indexing. So wherever 0 index of string was used, I had to use 1 index.

3. NoMetadata property does not exist

In Delphi 7, TSQLDataset has property NoMetadata which if set to true, no metadata is loaded. Similar property in Delphi XE4 is GetMetadata which if set to false, no metadata is loaded.

So, I replaced all NoMetaData = True lines to GetMetadata = False and the error got resolved.

4. DBXpress component was not found

DBXpress is deprecated and its functionality is included in SqlExpr. So I removed DBExpress from uses.

5. TMsgDlgBtn enum was causing compilation errors

TMsgDlgBtn enum (Message Dialog) has 12 elements in Delphi XE4 while in Delphi 7, there are only 11 elements. New element is mbClose. So added mbClose in the enums.

6. Shortstring (string[n]) datatypes were throwing errors

Shortstring (string[n]) datatype is deprecated in Delphi XE4 but is there for backward compatibility. So you can still use shortstring in Delphi XE4 but its ANSI not unicode.

I was using firebird 2.5.2 database. I also got some error related to that:

7. %1 is not a valid Win32 application

I had installed 32-bit Delphi XE4 and 64-bit Firebird 2.5. Because of this, I was getting the mentioned error while connecting to the database through Delphi XE4. I uninstalled 64-bit Firebird, downloaded and installed 32-bit Firebird and the problem was resolved. 

8. Following errors were coming in while executing firebird database queries from Delphi XE4

invalid Token
invalid request BLR at offset 163 
function F_ANYFUNCTION is not defined     
module name or entrypoint could not be found

Earlier I was using Firebird 2.5.1. Now I had migrated to Firebird 2.5.2. I looked in the Firebird 2.5.1 configuration file and made similar changes in firebird 2.5.2 configuration file.

ExternalFileAccess = Restrict (path of database file)

Also added udf.dll in UDF folder of Firebird 2.5.2

9. Unknown Driver - DevartInterbase

My Delphi 7 was using DevartInterbase driver in one of the TSQLConnection component. But now when I migrated to Delphi XE4, I was getting the above error. To solve this I downloaded the latest version of devart interbase for Delphi XE4 and the problem was resolved.

10. Unsupported on-disk structure for file mydatabase.fdb

When we installed latest version of devart interbase, by default it was using gds32.dll which is for interbase database. I just replaced VendorLib property of TSQLConnection from gds32.dll with fbclient.dll and the problem was resolved.

11. 'SQLDataSet: Type mismatch for field 'NAME', expecting: String actual:WideString'

When I installed latest devart interbase driver to support Delphi XE4 unicode version, I got this error in TSQLConnection component. 

I found 2 solutions for this error:

A) Set UseUnicode property of TSQLConnection to False.
B) Replace all TStringField with TWideStringField

12. interbase is not licensed

As I downloaded the developer free edition of devart interbase, it was giving this error. To resolve this error, Firebird and Interbase databases have to be restarted every 24 hour. Afterwards I got enterprise edition of devart.

13. Cannot perform operation – DB is not open

While connecting to database, firebird library name and path (fbclient.dll) was missing. Added fbclient.dll path and problem was resolved.

14. “EurekaLog Error” - project post processing has failed

Delphi 7 was using EurekaLog 6. But now I was using EurekaLog 7. So to handle the error, I went in Project –> Eurekalog options –> activated eurekalog and changed project type to old eurekalog application.

Rebuilt and compiled the application and error was gone.

15. When opened Delphi 7 application in Delphi XE4 RAD Studio, I noticed that all the dfm files had changed. The changes which I noticed were like:

Width = 443 --changed in Delphi XE4
Height = 277 --changed in Delphi XE4
ExplicitWidth = 443 --added automatically in Delphi XE4
ExplicitHeight = 277 --added automatically in Delphi XE4

These are the changes which RAD Studio introduces itself in the dfm files when you open it first time. You can ignore these changes or accept it for the first time.

I will come up with more compiler errors and warnings which I got during Delphi 7 to Delphi XE4 code migration in second part of this post.

Purpose and Usage of CharInSet function in Delphi XE4

Purpose and Usage of CharInSet function in Delphi XE4

CharInSet function is found in SysUtils unit. When I was migrating my Delphi 7 code to Delphi XE4, I found the usage and purpose of CharInSet function. While migrating my code from Delphi 7 to Delphi XE4, I got following compiler warning:

[DCC Warning] MyUnit.pas(80): W1050 WideChar reduced to byte char in set expressions. Consider using 'CharInSet' function in 'SysUtils' unit.

I had following procedure in my MyUnit.pas file which was throwing this compiler warning:

procedure MyProcedure;
var
  C: Char;
begin
  C := 'k';
  if C in ['a'..'z', 'A'..'Z'] then
  begin
   ShowMessage("Show any message");
  end;
end;

Cause of the compiler warning: In Delphi 7, a character was one byte, so holding characters in a set was no problem. But now in Delphi XE4, Char is declared as a WideChar, and thus cannot be held in a set any longer. 

Solution of the above compiler warning: If you don't bother about this compiler warning, you can ignore this. But if you actually want to get rid of this compiler warning, you have to use CharInSet function to remove this compiler warning like following:

  if CharInSet(C, ['a'..'z', 'A'..'Z']) then
  begin
   ShowMessage("Show any message");
  end;

The CharInSet function will return a Boolean value, and compile without the compiler warning.

Wednesday, 18 September 2013

A Software Developer should be a good Debugger and Analyst

A Software Developer should be a good Debugger and Analyst

As a developer, you are not going to develop a project from scratch every time  You cannot expect sheer coding work at all the time. In IT industry, major effort of project life cycle goes into maintenance and support. 

I have 4 years of software development experience and currently I am working in my second company. In my this short experience, I have worked in 5 projects out of which 3 were maintenance projects and 2 were development projects which had to be developed from scratch. My first project was in Shipping domain which was maintenance project. Next two were development projects in Retail and Manufacturing domain which had to be developed in Delphi XE2 and WPF respectively, fourth one was health and insurance domain and my current project in security domain in which I have to migrate a Delphi 7 application to Delphi XE4.

In all the projects I did till now, I had done a lot of maintenance tasks like fixing existing bugs, doing some enhancements, adding / modifying new features in the existing big application, handling tickets and resolve the issues etc. But this is also quite interesting job in the life of a software developer. In fact these things are the real test of a software developer. To handle these kind of tasks you must have good debugging capabilities. You have to identify and use your skills and experience to know in which file, in which part of code, the issue is arising. You should use StackTrace, TraceInto features to know the real cause of the issue and fix it.

Impact Analysis

Only issue tracking and fixing is not only the solution. You should be aware of the impact which your change can cause to the application. So I suggest you to comment at every place where you make changes in the code with name, date and reason why the code was changed. Proper testing of application is required after making any change to ensure that all the existing functionality are not impacted by your change.

Documentation 

After adding/modifying the features/issues in the application, documentation related to the application like SSRS, Test Cases should be updated.

In short, maintenance and support projects are not boring. You can learn a lot from these projects. These kind of projects sharpen your debugging skills and make you good analyzer. These qualities are necessary to make you a complete and skilled software developer.

Learning and sharing: 

While analyzing the issues and debugging the code, you come to explore many secrets of the complex application. I usually use to note down all the new things, findings and solutions which I learn during this process and document it. I use to share them on the internal knowledge portal of my company so that other people if encounter same kind of error, may get benefited from my work. It also helps me because if I face same problem, I can refer my document.

Interbase (IB) vs Firebird (FB): Differences and Similarities between Interbase and Firebird

Interbase (IB) vs Firebird (FB): Differences and Similarities between Interbase and Firebird

There are a lot of differences and similarities between Interbase and Firebird. I have tried to compare both Interbase and Firebird in my way (Interbase vs Firebird).

Interbase and Firebird are two different database servers. Firebird has originated from Interbase. After the release of Interbase 6.0 in 2000, developers moved away from Interbase and made first freeware and open-source version of Interbase and named it Firebird 1.0, made it available on SourceForge. Up to this point, all the features of Interbase and Firebird were same but after this different team started working on their products (Interbase and Firebird).

Following are the differences between Interbase and Firebird:

1. Firebird is freeware and open source while Interbase is commercial and  is currently developed and marketed by Embarcadero Technologies. So Firebird as being freeware and open source, the community members can change/modify anything in the source code and all other users of Firebird will be benefitted of that. 

2. Delphi supports officially only Interbase, however drivers probably work with basic functions and there are free and paid drivers and libraries available for Firebird. With Enterprise and Architect Editions of Delphi XE4, Firebird drivers are also supported. Delphi works well with Interbase using two different sets of access components. Interbase Express provides specific support for Interbase only. It does not support Firebird. Database Express, a more generic set of components for various databases, is also part of Delphi and supports both Interbase and Firebird. IBX is usually preferred over DBX for Delphi access to Interbase.

3. In Firebird, there is an embedded version so you don't need a real server - single user "server" is embedded into Delphi (Win) or Lazarus/FreePascal (Win/Lin) executable.

4. Interbase and Firebird DLLs: Usually we use gds32.dll to connect with interbase database server and fbclient.dll to connect with firebird server.

5. Latest Releases of Interbase and Firebird: 

InterBase XE is the latest version of Interbase which was released in 2010. Interbase XE new features include a 64 bit client and server, improved security, improved scalability, support for dynamic SQL in stored procedures, and optimized performance of large objects with stream methods.

Firebird 2.5.2 is the current stable version. New features included in this Firebird release are improved multithreading, regular expression syntax and the ability to query remote databases. The planned 3.0 release is expected to support stored procedures in languages such as Java and C++, and SQL window functions that restrict query results. An alpha version was released in August 2013.

Tuesday, 17 September 2013

What is the difference between dbExpress, dbGo and BDE in Delphi? Why to use dbExpress?

What is the difference between dbExpress, dbGo and BDE in Delphi? Why to use dbExpress?

There are a lot of database connectivity options in Delphi. Embarcadero supplies drivers for many databases, including Oracle, Firebird, InterBase, DB2, Informix, SQL Server, MySQL and ODBC. Additional drivers are available from third parties. Delphi supports many databases using several data access providers like dbExpress, dbGo, BDE, Interbase, FIBPlus, DevartIntebase (third party) etc. We will only talk about difference between BDE, dbGo and dbExpress and why should we use dbExpress instead of dbGo and BDE?

BDE is Borland Database Engine which was used in earlier versions of Delphi. Although its not deprecated still in Delphi XE4 but its advisable to migrate from BDE to dbExpress. 

dbGo for ADO mainly uses ADO connections to connect to MSSQL Server. No further enhancements have been made to dbGo since Delphi 6 when dbExpress was introduced. 

Both BDE and dbGo are bidirectional and uses connected access to database which degrades the performance in case of complex applications.  

dbExpress was introduced in Delphi 6 to replace BDE. dbExpress is a light-weight, extensible, cross-platform, high-performance mechanism for accessing data from SQL servers. dbExpress provides connectivity to databases for the Windows, .NET and Linux (using Kylix) platforms. dbExpress allows you to access different database servers like MySQL, Interbase, Oracle, MS SQL, Firebird, Informix etc. 

Disconnected Access and Unidirectional Approach in dbExpress

BDE and dbGo for ADO use connected data access techniques, that operate directly on the table or database but dbExpress architecture is the disconnected data access implementation available in Delphi. Instead of directly making any modification in database table, the dbExpress architecture requires the use of a TDataSetProvider to feed a TClientDataSet before we can connect to a TDataSource and data-aware controls.

One of the most significant features of dbExpress lies in the fact that it accesses databases using unidirectional datasets. Unidirectional datasets do not buffer data in memory - such a dataset cannot be displayed in a DBGrid. To build a user interface using dbExpress you will need to use two more components: TDataSetProvider and TClientDataSet as described above. 

Due to disconned access and unidirectional approach, dbExpress is provides good performance, so it is suitable for complex applications.

Saturday, 7 September 2013

How to create and consume webservices in Delphi using HTTP and SOAP protocols?

How to create and consume webservices in Delphi using HTTP and SOAP protocols?

I had to create and consume a webservice in my delphi XE4 application. I searched on the internet and after a lot of search I was able to pick some useful links (texts and video tutuorials) which may be useful to you while creating and consuming a webservice in delphi. I am just sharing those links to you in a sequence I understood them.


If you are new in webservices with delphi, you must start from this tutorial. This tutorial on webservices in delphi is written by Pawel Glowacki on Embarcadero Blogs.


This is the video tutorial on Embarcadero Development Network (EDN). This video tutorial on webservices in delphi is presented by Wecsley Fey - Aquasoft IT. He teaches consuming of webservices in delphi step by step with a simple examples. 



Read this article on consuming web service in delphi after clearing your concepts by reading above links. This link is for delphi 7, but it will give you clear idea on how to implement webservice in any version of delphi.


This link is also very simple for consuming web services in delphi. This site also provides some interesting web services which you can consume for free for testing purposes. You can create a demo delphi application and consume the webservice given on this site to play around.



You will have to sign in to Embarcadero to watch this video tutorial on building and consuming web services in Delphi and Delph Prism.