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

July 3rd, 2014

C++ Builder supports iOS and Android application development since version XE6. This article discusses the basics of developing database applications for iOS and Android in C++ Builder using UniDAC.

UniDAC is a suite of universal data access components for connecting to  SQL Server, SQLite, Oracle, MySQL, PostgreSQL, SAP ASE, xBase (DBF), Amazon Redshift, and InterBase from iOS and Android (you can use UniDAC to develop Windows applications that connect to almost any popular database, but this is beyond the scope of this article).

Connecting to a Database

You can access a database from iOS or Android in almost the same way you  access it from Windows, but you should be aware of some aspects of  connecting and deploying files to a mobile device when working with a local database. This article contains connection instructions and sample code for each database supported by UniDAC.

Connecting in Design-time

Let’s create an Android application that connects to MySQL. Select File > New > Multi-Device Application – C++ Builder.

C++ Builder Multi-Device Application

Select Blank Application, then place the TUniConnection and TMySQLUniProvider components onto the form. Set the ProviderName property of TUniConnection to MySQL and assign values to the  Username, Password, Server, and Port properties.

You can test database connectivity by setting the Connected property to True. If the values specified are correct, you will be able to view the list of available databases in the Database dropdown.

C++ Builder MySQL Connection from iOS

Compiling the Project

Select Project > Add to Project… and add the MySQL provider library, which is located in “C:\Program Files (x86)\Devart\UniDAC for RAD Studio 10.3\Lib\Android64”. For C++ Builder 10.3 Rio, the filename is libmyprovider260.a.

Add MySQL Provider Library to C++ Builder Project

C++ Builder Provider Library for MySQL

The table below contains database servers and their corresponding provider libraries for mobile application development in C++ Builder 10.3 Rio using UniDAC.

Database System Standard Edition Professional Edition
ASE libaseprovider260.a libtdsprovider260.a
SQL Server libmsprovider260.a libtdsprovider260.a
SQLite libliteprovider260.a
sqlite3.o
MySQL libmyprovider260.a
Oracle liboraprovider260.a
PostgreSQL libpgprovider260.a
InterBase ToGo libibprovider260.a
Amazon Redshift librsprovider260.a
libpgprovider260.a
xBase libdbfprovider260.a
libvquery260.a
sqlite3.o

If you don’t add this file to the project, 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.

Connecting in Run-Time

Put the needed providers onto the form and add their library files (similar to what you did in design-time). Note that despite having the same name, the provider libraries for Android and iOS are different and located in their respective folders:

“C:\Program Files (x86)\Devart\UniDAC for RAD Studio 10.3\Lib\Android64”
“C:\Program Files (x86)\Devart\UniDAC for RAD Studio 10.3\Lib\iOSDevice64”

You need to 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 lines to the cpp file:

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

If you are planning to use a local database on a mobile device, add this line to the header file to get access to the IOUtils namespace:

#include <System.IOUtils.hpp>

ASE

ASE has no client for Android or iOS, therefore a connection to an ASE server can only be established directly via TCP/IP by setting the Direct property to True:

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

Sample

  TUniConnection * Connection;

  Connection = new TUniConnection(Form1);

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

SQL Server

SQL Server has no MS SQL Native Client for Android or iOS, therefore a connection to SQL Server can only be established directly via TCP/IP by setting the Provider property to prDirect:

SpecificOptions->Values["Provider"] = "prDirect";

Sample

  TUniConnection * Connection;

  Connection = new TUniConnection(Form1);

  try {
	Connection->ProviderName = "SQL Server";
        Connection->Server = "server";
        Connection->Username = "user_name";
        Connection->Password = "password";
        Connection->Database = "database_name";
        Connection->SpecificOptions->Values["Provider"] = "prDirect";
        Connection->Connect();
        ShowMessage("Connected successfully");
  }
  __finally {
	Connection->Free;
  }

SQLite

If you don’t deploy a database with your application, set the ForceCreateDatabase property to True to create a database file automatically when the user first launches your application.

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

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

Oracle has no client for Android or iOS, therefore a connection to an Oracle server can only be established directly via TCP/IP by setting the Direct property to True:

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

To establish a connection to Oracle from Android or iOS, assign your host, port, and service name or system identifier to the Server property.

To connect using the Service Name, the format is as follows:

Server = "Host:Port:sn/ServiceName";
Server = "Host:Port:sn=ServiceName"; (deprecated format)

To connect using the SID, the format is as follows:

Server = "Host:Port:SID";
Server = "Host:Port:sid=SID"; (deprecated format)

If the port number is followed by a colon, and the service name prefix (sn=) or the SID prefix (sid=) is not defined, then by default, the connection will be established using SID. In majority of Oracle servers, the service name is the same as the SID. Consult the Oracle documentation for more information.

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 has no client for Android or iOS, therefore a connection to a MySQL server can only be established directly via TCP/IP by setting the Direct property to True:

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

UniDAC supports only a direct connection to PostgreSQL, therefore there’s no property that instructs the client on how to connect to the server — you only need to set the server address, port, and the user credentials.

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

You can connect to a local or remote InterBase ToGo database from iOS and Android devices.

To connect to a local database, set the path to the database on the device:

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

If you need to establish a connection to a remote server, specify the server address and database name:

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

Note that the prefix System::Sysutils::IncludeTrailingPathDelimiter (System::Ioutils::TPath:: GetDocumentsPath) is required to connect to a local 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;
  }

Amazon Redshift

UniDAC supports only a direct connection to Redshift, therefore there’s no property that instructs the client on how to connect to the server — you only need to set the server address, port, and the user credentials.

Sample

  TUniConnection * Connection;

  Connection = new TUniConnection(Form1);

  try {
	Connection->ProviderName = "Redshift";
        Connection->Server = "server";
        Connection->Username = "user_name";
        Connection->Password = "password";
        Connection->Database = "database_name";
        Connection->Port= 5439;
        Connection->Connect();
        ShowMessage("Connected successfully");
  }
  __finally {
	Connection->Free;
  }

xBase

xBase databases don’t use the client-server model, therefore a connection to an xBase database can only be established directly via TCP/IP by setting the Direct property to True:

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

To connect to an xBase database, you need to set the path to the database and its format.

Sample

  TUniConnection * Connection;

  Connection = new TUniConnection(Form1);

  try {
	Connection->ProviderName = "DBF";
        Connection->Database = "folder_name";
        Connection->SpecificOptions->Values["DBFFormat"] = "dfVisualFoxPro";
        Connection->SpecificOptions->Values["Direct"] = "True";
        Connection->Connect();
        ShowMessage("Connected successfully");
  }
  __finally {
	Connection->Free;
  }

Deploying the Application

The deployment of an application to a mobile device is described in the article “How to Develop Android Database Applications in RAD Studio“.

The Difference Between the Android and iOS Application Deployment

The deployment path is different on Android and iOS. If you want to deploy your application to both platforms, make sure that the deployment paths are specified correctly for both Android and iOS.

NOTE: Remember to replace the default value (“.”) of Remote Path  with one of the values below.

С++ Builder Function 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

Despite having the same name, the providers for Android and iOS are different and located in their respective folders.

Debug

The debugging process is described in the article Remote Debugging of Android Applications in RAD Studio via Wi-Fi

Wrapping up

You can build powerful applications with C++ Builder and UniDAC that work with ASE, SQL Server, SQLite, MySQL, Oracle, PostgreSQL, InterBase, Amazon Redshift, and xBase databases from Android and iOS devices.

Comments are closed.