Devart Blog

How to develop Database Applications with UniDAC for iOS and Android in C++Builder XE6

Posted by on July 3rd, 2014

In RAD Studio XE6 there appeared an opportunity to develop applications for iOS and Android on C++. Let’s consider the peculiarities of database application development on C++ using UniDAC.

UniDAC is Universal Data Access Components that allow to connect to SQLite, Oracle, MySQL, PostgreSQL, and InterBase (since version XE3) from iOS and Android (you can use UniDAC for connection from Windows to almost all the known databases, but this is beyond the scope of this blog).

Connection to database

Work with databases on iOS and Android in general is no different from the one on Windows, but there are some nuances when setting connection and deploying files to a mobile device if you work with a local DB. We will consider here how to establish connection to each supported database.

Design-time

Let’s create a new Android application on C++ working with a MySQL server. For this, in the File|New menu select FireMonkey Mobile Application – C++ Builder.

In the appeared dialog select Blank Application.

Then place the TUniConnection and TMySQLUniProvider components onto the form, which will be named as UniConnection1 and MySQLUniProvider1 respectively. Set up the UniConnection1 component by setting the ProviderName property to MySQL and filling in the required properties: UserName, Password, Server, Port.

If the listed properties are set correctly, then you can select a value for the Database property from the combobox. Now you can test connection by setting the Connected property to True. Take into account, that this test connection is performed on Win32 for XE6, not for the mobile application you are developing.

Compilation

Add the libmyproveder200.a file to the project, as it is shown below:

See the correspondence of object module names to database servers in the table below:

Database server Object module name
SQLite libliteproveder200.a
MySQL libmyproveder200.a
Oracle liboraproveder200.a
PostgreSQL libpgproveder200.a
Interbase libibproveder200.a

If you don’t add this file, you will get an error message during compilation:

“[ldandroid Error] C:\Users\Public\Documents\Embarcadero\Studio\14.0\PlatformSDKs\android-ndk-r9c\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\bin\arm-linux-androideabi-ld.exe: .\Android\Debug\Unit1.o: in function _ZTX6TForm1:.\Android\Debug\Unit1.o.ll(.data.rel.ro._ZTX6TForm1+0x6): error: undefined reference to ‘vtable for Mysqluniprovider::TMySQLUniProvider'”

Compile the project.

Run-Time

You should place those providers onto the form, which you will use, and add object modules of these providers (as it was shown in the design-time sample). But take into account that for Android and iOS these modules have the same names, but are located in different folders:

“C:\Program Files\Devart\UniDAC for RAD Studio XE6\Lib\Android\”
“C:\Program Files\Devart\UniDAC for RAD Studio XE6\Lib\iOSDevice\”

You should either place the TUniConnection component onto the form or add the following lines to the header file:

#include "DBAccess.hpp"
#include "Uni.hpp"

and the following – to the cpp file:

#pragma link "DBAccess"
#pragma link "Uni"

If you are going to open access to a local database on a mobile device, then add the line to the header file:

#include <System.IOUtils.hpp>

in order to get access to IOUtils namespace.

SQLite

If you don’t deploy the database file to a mobile device, you should set:

SpecificOptions->Values["ForceCreateDatabase"] = "True"

In this case, on the first application launch, a database file will be created automatically.

Sample

  TUniConnection * Connection;

  Connection = new TUniConnection(Form1);

  try {
	Connection->ProviderName = "SQLite";
	Connection->SpecificOptions->Values["ForceCreateDatabase"] = "True";
	Connection->Database = System::Sysutils::IncludeTrailingPathDelimiter(
	  System::Ioutils::TPath::GetDocumentsPath()) + "db.sqlite3";
	Connection->Connect();
	ShowMessage("Connected successfully");
  }
  __finally {
	Connection->Free;
  }

Oracle

It is impossible to install Oracle client to a mobile device, because Oracle client for Android and iOS simply doesn’t exist. Therefore the only way to establish connection to Oracle from a mobile device is to connect directly via TCP/IP. For this, the Direct option should be set to True:

SpecificOptions->Values["Direct"] = "True";

In addition, the server name must be set correctly, since, if we have no client – we have no tnsnames.ora file with the server list as well. Therefore, to establish connection from Android and iOS, we need to know the server Host and Port, as well as its SID or Service Name.

To connect via the SID, the server should be set in the following way:

Server = "Host:Port:sid=SID";

or a simplified way:

Server = "Host:Port:SID";

To connect via the Service Name – as follows:

Server = "Host:Port:sn=ServiceName";

In other words, the ‘sid=’ prefix of the third parameter indicates that connection is established via the SID, and the ‘sn=’ prefix indicates that connection is established via the Service Name. If no prefix is specified, then, by default, it is considered, that we want to establish connection via the SID.

The majority of Oracle servers have the same SID and Service Name, so you, most likely, won’t have to go into such nuances, since you can learn more about this in the Oracle documentation.

Sample

  TUniConnection * Connection;

  Connection = new TUniConnection(Form1);

  try {
	Connection->ProviderName = "Oracle";
	Connection->SpecificOptions->Values["Direct"] = "True";
	Connection->Server = "server:1521:orcl";
	Connection->Username = "user_name";
	Connection->Password = "password";
	Connection->Connect();
	ShowMessage("Connected successfully");
  }
  __finally {
	Connection->Free;
  }

MySQL

MySQL client software for Android and iOS also doesn’t exist, therefore connection to MySQL server will also be established directly via TCP/IP. For this, let’s set the corresponding option:

SpecificOptions->Values["Direct"] = "True";

Sample

  TUniConnection * Connection;

  Connection = new TUniConnection(Form1);

  try {
	Connection->ProviderName = "MySQL";
	Connection->SpecificOptions->Values["Direct"] = "True";
	Connection->Server = "server";
	Connection->Port = 3306;
	Connection->Username = "user_name";
	Connection->Password = "password";
	Connection->Connect();
	ShowMessage("Connected successfully");
  }
  __finally {
	Connection->Free;
  }

PostgreSQL

With PostgreSQL, everything is more simple. Since UniDAC only allow establish direct connection via TCP/IP, it is enough for us to specify the Server and Port and perform Connect.

Sample

  TUniConnection * Connection;

  Connection = new TUniConnection(Form1);

  try {
	Connection->ProviderName = "PostgreSQL";
	Connection->Server = "server";
	Connection->Port = 5432;
	Connection->Database = "database_name";
	Connection->SpecificOptions->Values["Schema"] = "schema_name";
	Connection->Username = "user_name";
	Connection->Password = "password";
	Connection->Connect();
	ShowMessage("Connected successfully");
  }
  __finally {
	Connection->Free;
  }

InterBase

Using InterBase ToGo, you can connect to both local or remote DB.

To connect to a local db, just the path to the local DB on the device should be set:

Database = System::Sysutils::IncludeTrailingPathDelimiter(
	     System::Ioutils::TPath::GetDocumentsPath()) + "db.gdb";

If you need to establish connection to a remote server, you should specify not only the database, but the server as well:

UniConnection.Server = "server";
UniConnection.Database = "C:\db.gdb";

Please note that the System::Sysutils::IncludeTrailingPathDelimiter (System::Ioutils::TPath:: GetDocumentsPath) prefix should be specified when connecting to a local DB, and it is not needed for connection to a remote database.

Local database sample
  TUniConnection * Connection;

  Connection = new TUniConnection(Form1);

  try {
	Connection->ProviderName = "InterBase";
	Connection->Database = System::Sysutils::IncludeTrailingPathDelimiter(
	  System::Ioutils::TPath::GetDocumentsPath()) + "db.gdb";
	Connection->Username = "user_name";
	Connection->Password = "password";
	Connection->Connect();
	ShowMessage("Connected successfully");
  }
  __finally {
	Connection->Free;
  }
Remote database sample
  TUniConnection * Connection;

  Connection = new TUniConnection(Form1);

  try {
	Connection->ProviderName = "InterBase";
	Connection->Server = "server";
	Connection->Database = "C:\db.gdb";
	Connection->Username = "user_name";
	Connection->Password = "password";
	Connection->Connect();
	ShowMessage("Connected successfully");
  }
  __finally {
	Connection->Free;
  }

Deployment to mobile device

The deployment to mobile device process is described in the How to Develop Android Database Applications in RAD Studio XE5″ article.

Difference between Android and iOS application deployment

Please note that the deployment path is different for Android and iOS. If you want to deploy your application to both platforms, then make sure the deployment paths are specified correctly for both of them.

NOTE: Don’t forget to change the Remote Path default value “.” with one of the described above.

Deployment Path Destination on Device
TPath::GetDocumentsPath .\assets\internal /data/data/com.embarcadero.MyProjects/files
TPath::GetSharedDocumentsPath .\assets /mnt/sdcard/Android/data/com.embarcadero.MyProjects/files

In addition, thus the providers for Android and iOS have similar names, they differ from each other. The providers are supplied with UniDAC, but each of them is located in a folder corresponding to a platform.

Debug

We won’t focus on the debug process in this article, since it was described in details in the previous article: Remote Debug of Android Applications in RAD Studio XE5 via Wi-Fi

Conclusion

RAD Studio XE5 release allowed creating applications with Devart Data Access Components in Delphi for work with SQLite, Oracle, MySQL, PostgreSQL and InterBase from both mobile platforms: Android and iOS. RAD Studio XE6 release made it possible not for Delphi only, but for C++Builder as well. But we are not going to stop. Many users ask us to support connection to SQL Server from Android and iOS – and we will make every effort to give them such a capability.

Leave a Reply