Skip to content

VCL FireDAC Workshop in Warsaw

Good fun!

I have promised a while ago to stop blogging here, but it is going to be a parallel pattern for a while;-)

http://community.embarcadero.com/index.php/blogs/entry/modernize-your-vcl-database-apps-with-firedac-and-delphi-xe7-workshop-in-warsaw

Modernize Your VCL Database Apps with FireDAC and Delphi XE7 workshop in Warsaw

I’m just back from the city I grew up - Warsaw. At the 15th floor of the "all-glass" sky scraper there were 29 Delphi-addicted programmers playing with Delphi XE7 FireDAC database access technology on their on laptops.

FireDAC and Object Pascal in Action clearly rulez!

My "C++ 3D FireMonkey Programming" CodeRage 9 session

The CodeRage 9 virtual conference has started and I’m now online at the C++ track watching parallel programming session by David I. This is all about the new Parallel Programming Library introduced in C++Builder XE7, Delphi XE7, RAD Studio XE7 and Appmethod 2014 September release.

My C++ "3D FireMonkey Programming" session is next and I have just uploaded my live demos source code to Code Central here: http://cc.embarcadero.com/item/30030

There are three C++ demos built with Appmethod:

  • SimpleEarth3D demonstrates basics of building a multi-device, cross-platform, interactive 3D app. It is based on the Form3D and uses a sphere component and a texture material component for loading "Earth" texture graphics. There is also "float animation" component to rotate Earth and OnClick event on the sphere that shows how to add interactivity to your 3D view.
  • SpaceDebris is a demo that shows how to use TModel3D component to load arbitrary 3D geometry. Instead of using a Form3D, this project is using a regular Form class and displays 3D inside of the Viewport3D component. It is also using explicit Camera and Light components.
  • CustomerInfo3D project shows how to add a "3D-twist" to your traditional database, enterprise applications. The project contains two Layer3D components placed inside of the Viewport3D that are used to host traditional two-dimensional controls like labels and buttons to display data coming from the "Customer" in-memory FireDAC "TFDMemTable" component using Visual LiveBindings. Initially the app looks like a regular 2D app, but when you click on the "info" button in the customer information a secondary layer displays with a 3D rotation more details about the current customer.

The source code is of this demos is available at the http://cc.embarcadero.com/item/30030

My blog has moved to community.embarcadero.com!

This is most likely my latest blog post on this server.
There is a new Embarcadero social website community.embarcadero.com where my blog has been migrated.
I’m looking forward to see you online on my new blog at
http://community.embarcadero.com/index.php/blogs/blogger/listall/pawel-glowacki-embarcadero-com

DataSnap "CUSTOMERS" FireDAC JSON Reflection Demo Code

My "RAD in Action: Build Modern Apps with Enterprise Mobility Services" webinar is happening right now. During my 50 minutes session I’m demonstrating using DataSnap framework for building multi-tier database application with FireDAC JSON Reflection framework. That’s very powerful and very easy to code.

During the demo I have illustrated the following best practices:

  • InterBase „EMPLOYEE” sample database
  • FireDAC database access components
  • DataSnap server deployed to a web server
  • Secure HTTPS communication
  • Role-based Authentication and Authorization
  • DataSnap REST Client Module and Proxies
  • FireDAC In-Memory Database Tables
  • Visual LiveBindings for connecting UI to data
  • FireMonkey Mobile iOS/Android Client

During the session I have promised to make the source code of the demo available, so here it is! I have uploaded "Customers" demo source code to Code Central here: http://cc.embarcadero.com/item/29916.

DataSnap "Simple Calculator" REST demo

It was so much fun to create one of the "Developer Skills Sprint" sessions last week.
During the live Q’n'A session I have promised to make the source code of my DataSnap "Simple Calculator" REST server and client projects available.

Here it is! It is now available from the Code Central at http://cc.embarcadero.com/item/29915

A few years ago, back in the Delphi XE time frame, I have created a series of DataSnap "Delphi Labs". The source code of these Delphi Labs has been updated to Delphi XE3. But the technology does not stand still. I do not think anymore that it makes sense to make just the cosmetic adjustments to these examples. In fact these demos need a major upgrade to use the latest technologies and best practices.

  • Server architecture. For performance reasons it is best to implement DataSnap servers as web applications and deploy to a web server. Instead of "DataSnap Server" wizard, use "DataSnap REST Application" or "DataSnap WebBroker Application".
  • Communication Protocol. In the world of highly disconnected apps the best communication protocol is standard HTTP or HTTPS.
  • Security. On top of HTTPS transport security, make sure to use encryption filters and role-based authentication and authorisation.
  • Client Connectivity. Instead of using "DBX" use "REST". There are two wizards for creating client-side proxy classes: "DataSnap Client Module" and "DataSnap REST Client Module". The first one is based on the DBExpress technology and uses "TSQLConnection" component for connectivity. Don’t use it. Use the second, REST-based wizard, that generates REST-style client proxies and uses "TDSRESTConnection" component for connectivity.

The "Simple Calculator REST" demo is the new generation version of my first "Delphi Lab" and covers the basics of creating DataSnap server and client projects.

The second historical demo in the "Delphi Labs" session was about creating multi-tier database applications with DataSnap. The new generation version of this demo is in the works and will be presented this Wednesday, August 20th, during my global "Build Modern Apps with Enterprise Mobility Services" webinar. I’m going to move away from deprecated IAppServer interface and use FireDAC JSON Reflection framework for creating new generation multi-tier database applications.

See you online! In the meantime make sure to register for the webinar!

C++Builder XE6 multi-tier database app with FireDAC JSON Reflection

Welcome to The C++ Mobile Day webinar! Right now I’m listening to David I explaining basics of building native mobile apps for Android and iOS from the same C++ codebase with C++Builder XE6. In less than three hours there will be my, prerecorded session "Create C++ Secure Mobile Applications that Work with Enterprise Web Services and Multi-tier Architectures".

In this session I’m going to demonstrate how to use C++Builder XE6 to build a multi-tier database application with DataSnap framework. The server is a web app that accesses data from the InterBase database and the client is a mobile Android or iOS app that is using secure HTTPS protocol for connecting to the server and exchanging JSON data through REST interfaces.

FireDAC JSON Reflection support has been introduced in RAD Studio XE5 Update 2 and the first person to blog about it was Delphi Product Manager Marco Cantu in this blog post.

I have promised in the session to make the source code of the demo available, so here it is! It is available for download from Embarcadero CodeCentral here.

The demo illustrates best practices for using DataSnap framework in the RAD Studio XE6.

These are the preferred technologies:

  • Database: InterBase
  • Database Access Framework: FireDAC
  • Data format: JSON
  • Client/Server Architecture: REST
  • Communication Protocol: HTTPS
  • Client-side in-memory dataset: FireDAC "TFDMemTable"
  • UI technology: Visual LiveBindings

In the RAD Studio XE6 there is an Object Pascal DataSnap demo in C:\Users\Public\Documents\Embarcadero\Studio\14.0\Samples\Object Pascal\DataSnap\FireDACJSONReflect that I have translated to C++. The original demo has the FireMonkey desktop client and in my case it is a mobile client.

The "C++ Mobile Day" DataSnap demo contains two projects. "CPPDepartments_REST_server" and "CPPDepartments".

The server project has been created using the C++Builder XE6 "DataSnap WebBroker Application" wizard. It uses HTTPS for communication, DataSnap encryption and compression transport filters and role-based authentication/authorization. The server exposes two server methods for retrieving JSON data and one method for accepting data updates to the underlying InterBase "EMPLOYEE" sample database.

The application works with two tables in the database: DEPARTMENT and EMPLOYEE. Here is the screenshot from FireDAC Explorer that shows the structure of both tables:

The server module contains the database FireDAC connection component and three query components.

The first query, FDQueryDepartmentNames, returns the list of department numbers and names. It has the following SQL statement:

select DEPT_NO, DEPARTMENT from DEPARTMENT

The result from this query is used at the client to build the list of departments. In order to retrieve this information the client app needs to call the "GetDepartmentNamesJSON" server method that returns data encoded as TJSONObject. The implementation of this method is very interesting.


#include "System.Json.hpp"
#include "Data.FireDACJSONReflect.hpp"

TJSONObject* TServerMethods1::GetDepartmentNamesJSON()
{
  FDQueryDepartmentNames->Close();

  TFDJSONDataSets *ds = new TFDJSONDataSets();
  TFDJSONDataSetsWriter::ListAdd(ds, FDQueryDepartmentNames);

  TJSONObject *obj = new TJSONObject();
  TFDJSONInterceptor::DataSetsToJSONObject(ds, obj);
  return obj;
}

Notice that we do not care about the types of fields returned from the query. The "TFDJSONDataSetsWriter" class provides static "ListAdd" method that is using reflection to convert results of the query into "TFDJSONDataSets" object and the "TFDJSONInterceptor" class uses DataSetsToJSONObject static method to convert the contents of datasets into plain JSON object that is returned from the server method to client.

The next two queries - FDQueryDepartment and FDQueryDepartmentEmployees - are used to retrieve more detailed information for a given department from DEPARTMENT and from EMPLOYEE tables. These are parameterized queries:

select * from DEPARTMENT where DEPT_NO = :DEPT
select * from EMPLOYEE where DEPT_NO = :DEPT

The information returned from both queries is exposed to clients via "GetDepartmentEmployeesJSON" server method. What is interesting here is that we can in just one operation receive data from multiple queries. That’s a very nice capability!


const System::String sEmployees = "Employees";
const System::String sDepartment = "Department";

TJSONObject* TServerMethods1::GetDepartmentEmployeesJSON(System::UnicodeString AID)
{
  FDQueryDepartmentEmployees->Active = false;
  FDQueryDepartment->Active = false;
  FDQueryDepartment->Params->operator [](0)->Value = AID;
  FDQueryDepartmentEmployees->Params->operator [](0)->Value = AID;

  // Create dataset list
  TFDJSONDataSets *ds = new TFDJSONDataSets();
  // Add departments dataset
  TFDJSONDataSetsWriter::ListAdd(ds, sDepartment, FDQueryDepartment);
  // Add employees dataset
  TFDJSONDataSetsWriter::ListAdd(ds, sEmployees, FDQueryDepartmentEmployees);

  TJSONObject *obj = new TJSONObject();
  TFDJSONInterceptor::DataSetsToJSONObject(ds, obj);
  return obj;
}

These two methods are used by a client app to receive information about departments. First we get the list of departments names and their IDs. When a client selects a department from the list, then the detailed information about department and its employees is returned from the second server method.

The third server method is used to send data updates from client and updating the underlying database. Here is the source code.


void TServerMethods1::ApplyChangesDepartmentEmployeesJSON(TJSONObject* AJSONObject)
{
  TFDJSONDeltas *LDeltas = new TFDJSONDeltas();
  TFDJSONInterceptor::JSONObjectToDataSets(AJSONObject, LDeltas);

  TFDJSONErrors *errs = new TFDJSONErrors();

  // Apply the department delta
  TFDJSONDeltasApplyUpdates::ListApplyUpdates(LDeltas, sDepartment, FDQueryDepartment->Command, errs);

  // If no errors, apply the employee delta
  if (errs->Count == 0) {
	TFDJSONDeltasApplyUpdates::ListApplyUpdates(LDeltas, sEmployees, FDQueryDepartmentEmployees->Command, errs);
  }

  // Raise an exception if any errors.
  if (errs->Count > 0) {
	 throw new Exception(errs->Strings->Text);
  }
}

This method does not return any value, but it accepts JSON object with updates to data. Again, this code is quite generic. We do not care about the underlying field types. The "TFDJSONDeltasApplyUpdates::ListApplyUpdates" static method is using reflection to apply updates to the underlying database tables. In just one operation we can update multiple tables!

The client application has been created with "FireMonkey Mobile App - C++Builder" wizard. This project can be compiled as an Android or an iOS app from the very same source code.

The first step is to use "DataSnap REST Client Module" wizard to generate DataSnap client proxy code for accessing the server functionality. "ClientClassesUnit1" and "ClientModuleUnit1" units have been generated with this wizard. In order to have more cleaner design I have also added a data module ("uDMDepartmentsCPP") to the project where I have placed three FireDAC in-memory dataset components for storing data coming from the three queries on the server.

Additionally I had to add the "TFDStanStorageBinLink" component to the form, because otherwise the client app gives an error at runtime. The first dataset is used only for storing the read-only data with the list of departments and their names. The next two datasets are used for working with data coming from the parameterized server queries and the changes made to in-memory data done through user interface are sent back to server. It is important to set "CachedUpdates" property on both table to "True" for things to work.

I’m using visual live bindings for binding data to visual controls. For this reason it is necessary to define field definitions in the FDMemTables to we can bind to them at design time. Field types are not important, but the names of the field definitions need to correspond to fields in datasets received from the server.

The user interface of the client application contains one tab control that occupies the whole screen, with just three tabs. The first tab contains the list view components for the list of department names. When the end user clicks on any department name, then the second tab is displayed with information about selected department. The last tab contains connection settings with host, port, protocol, username and password needed to connect to a specific server.

The first tab has the "refresh" button used for retrieving department names and identifiers. I’m using Visual LiveBindings for binding data from the "FDMemTableDepartmentNames" dataset to the list view. In order to be able to display the DEPT_NO information, you need to change the "ItemAppearance.ItemAppearance" property to "ListItemRightDetail". In this way the "Item.Detail" property is added to list view and we can bind it to DEPT_NO field.

I have encapsulated the logic to retrieve department names in the data module’s "GetDepartmentNames" method.


#include "uDMDepartmentsCPP.h"
#include "Data.FireDACJSONReflect.hpp"
#include "DataSnap.DSClientREST.hpp"
#include "ClientModuleUnit1.h"

// ...

void TDMDepartmentsCPP::GetDepartmentNames()
{
  try
  {
    TJSONObject* LJSONObject(ClientModule1->ServerMethods1Client->GetDepartmentNamesJSON());
    std::auto_ptr<TFDJSONDataSets> LDataSets(new TFDJSONDataSets());
    TFDJSONInterceptor::JSONObjectToDataSets(LJSONObject, LDataSets.get());
    FDMemTableDepartmentNames->Active = false;
    TFDAdaptedDataSet * LDataSet =  TFDJSONDataSetsReader::GetListValue(LDataSets.get(), 0);
    FDMemTableDepartmentNames->AppendData(*LDataSet);
  } catch (TDSRestProtocolException& E)
  {
    HandleRESTException(ClientModule1->DSRestConnection1, "Get Departments error", &E);
  }
}

We start from getting JSON data from the server using "ClientModule1" class that was generated with the "DataSnap REST Client Module" wizard. Next we convert JSON to a dataset and append it to FDMemTableDepartmentNames table. The Visual LiveBindings take care about displaying this data in the list view. That’s a very powerful mechanism.

I’m not including the source for the "HandleRESTException" method. You can find in the download.

When the end user clicks on the department names the following code is executed to download department and employee detailed information for a selected department.


void TDMDepartmentsCPP::GetDepartmentDetails(const System::String ADEPTNO)
{
  try
  {
    TJSONObject* LJSONObject(ClientModule1->ServerMethods1Client->GetDepartmentEmployeesJSON(ADEPTNO));
    std::auto_ptr<TFDJSONDataSets> LDataSets(new TFDJSONDataSets());
    TFDJSONInterceptor::JSONObjectToDataSets(LJSONObject, LDataSets.get());

    {
    TFDAdaptedDataSet * LDataSet =  TFDJSONDataSetsReader::GetListValueByName(LDataSets.get(), sDepartment);
    // Update UI
    FDMemTableDepartment->Active = False;
    FDMemTableDepartment->AppendData(*LDataSet);
    }

    {
    TFDAdaptedDataSet * LDataSet =  TFDJSONDataSetsReader::GetListValueByName(LDataSets.get(), sEmployees);
    // Update UI
    FDMemTableEmployees->Active = False;
    FDMemTableEmployees->AppendData(*LDataSet);
    }

  } catch (TDSRestProtocolException& E)
  {
    HandleRESTException(ClientModule1->DSRestConnection1, "Get Departments error", &E);
  }
}

The data stored in the "FDMemTableDepartment" and "FDMemTableEmployee" can be modified through the user interface. When the end user clicks on the "Apply Updates" button the following code is used to send the updates back to the server.


void TDMDepartmentsCPP::ApplyUpdates()
{
  // Post if editing
  if (dsEditModes.Contains(FDMemTableDepartment->State))
  {
    FDMemTableDepartment->Post();
  }

  if (dsEditModes.Contains(FDMemTableEmployees->State))
  {
    FDMemTableEmployees->Post();
  }

  // Create a delta list
  TFDJSONDeltas * LDeltas = new TFDJSONDeltas();
  // Add deltas
  TFDJSONDeltasWriter::ListAdd(LDeltas, sEmployees, FDMemTableEmployees);
  TFDJSONDeltasWriter::ListAdd(LDeltas, sDepartment, FDMemTableDepartment);

  TJSONObject * LJSONObject(new TJSONObject());
  TFDJSONInterceptor::DataSetsToJSONObject(LDeltas, LJSONObject);
  try
  {
    // Call server method.  Pass the delta list.
    ClientModule1->ServerMethods1Client->ApplyChangesDepartmentEmployeesJSON(LJSONObject);
  }
  catch (TDSRestProtocolException& E)
  {
    HandleRESTException(ClientModule1->DSRestConnection1, "Get Departments error", &E);
  }
}

That’s it! Using the new FireDAC JSON Reflection functionality in C++Builder XE6 it is super easy to build secure, multitier database applications!

The source code of this demo is available for download from Embarcadero Code Central.

Delphi Developer Days come to Amsterdam, June 12-13, 2014

I can’t wait to Delphi Developer Days coming to Amsterdam in a very near future and specifically June 12 and 13. There are still some places left, so hurry up registering at Delphi Developer Days 2014!

If you are interested in Delphi and you are based in the Netherlands, Belgium, Luxembourg or you can just super easily fly in with your favourite airlines to Schiphol Amsterdam airport, just do it! Cary Jansen and Bob Swart are simply great Delphi world-wide super heroes! What I really like about the Delphi Developer Days is this thick book full of the latest Object Pascal code snippets and in-depth hands-on comments;-)

I will be very proud to do the keynote presentation at DDD 2014 in Amsterdam this year. Big thanks to Cary, Loy and Bob for inviting me!

On Tour with Delphi and C++Builder XE6

Travelling… It is like with everything in our lives. When it is too much, you start not to like it. When it is too rare, you start to miss it. Human nature.

I just like coding in Delphi and C++Builder, and just cannot help it. I like showing off the latest new features. And some existing ones as well:-)

The new mantra: one source code and multiple target platforms! And the mantra that stood the challenge: building apps from reusable, visual components that you can manipulate at design time…

Some photos from my recent trips below. My last stop was in Brno in Czech. Great people, great beer and food;-)

It was great meeting Radek Cervinka, Embarcadero MVP and the spirit behind of delphi.cz!

Delphi in Czech Republic is very, very strong. It is all about passion and clearly Peter Houf from Embarcadero.cz is passionate! I was demonstrating a lot of FireDAC demos and Peter has the whole series of articles about FireDAC online on his blog at http://petrhouf.blogspot.cz/.

The previous stop was in Denmark. Two presentations - Copenhagen and Aarhus.

Jens Fudge is our Embarcadero MVP in Denmark.

The two days just before XE6 events were all about Delphi trainings created and delivered by Jens Fudge!

And there was Budapest. It was great showing XE6 on the cinema screen!

Big interest in Appmethod on Android Developer Days in Ankara

I have spent almost the whole day yesterday at the Appmethod booth at the Android Developer Days in Ankara, the capital of Turkey. That was great and very encouraging experience. The event was organized in the biggest technical university in Turkey and it was very well attended with close to two thousand people.

Appmethod booth was very well located at the main entrance to the exhibition hall. The team from btgrubu, Embarcadero partner in Turkey, was doing great job explaining what Appmethod is and the benefits of creating native, compiled apps in the visual way from the same codebase for both Android and iOS.

There were constantly interested young students and developers interested in live demonstration of Appmethod and reception was very warm. Some of them were clearly amazed with Appmethod and what it can do!

Students and young developers are amazed with Embarcadero Appmethod! I loved their open minds and enthusiasm!

Bad Behavior has blocked 2 access attempts in the last 7 days.

Close