Welcome back to our series about creating a reminder application in C++Builder!
Our last article discussed how to set up C++Builder, design the user interface by dragging and dropping components, and write code to control some components.
If you haven't read: Building Your First App Using C++ Builder (Part 1)
This part will integrate SQLite into the application and attempt to store reminders added by users into the database.
After adding reminders to the database, we will display reminders to users when they are requested.
C++Builder allows you to make use of several databases in one program with its FireDAC library. We will integrate our SQLite database into this application.
To accomplish this, we need to begin by downloading and installing the SQLite database. Feel free to choose whichever database you want to use.
Note that firedac allows you to integrate multiple databases into your application. Once you have downloaded and set up your database, you will need to choose the type of database and link it to your application.
Double click on Fdconnection in the design form. This action will open the firedac connection editor. Here you can select the name of the database you intend to use and provide more details about the database.
All we need to modify for this simple app is the Driver Id and the location of the database we have created on the desktop (next to the Database tag).
After completing this step, we can start writing code to retrieve data from the database and store data collected from the user into the database.
We created a database on the desktop located in the following path:
C:\\Users\\uk\\OneDrive\\Desktop\\reminderdb.db
When we click the add reminder button, we want to take the user's current time, and date selected using the time and DateTime pickers, respectively, and store them into the database.
We will need to write some SQL statements to create a reminder table in the database if it does not exist already and insert the date/time values as a string into the database whenever the onClick event is triggered.
We have also added a "Show Reminders" button to retrieve reminders from the database and display them in the Memo.
Double click on the "Add Reminder" button to create an empty fastcall function for the 'AddReminder' button. In this function, we will make use of our FDConnection to connect to the database.
The driver name and path to the database need to be specified. This will help the program identify the location of the database it will be communicating with it.
FDConnection1->DriverName = "SQLite";
FDConnection1->Params->Values["Database"] = "C:\\Users\\uk\\OneDrive\\Desktop\\reminderdb.db";
Once this is done, you can write code that will modify, insert, update, delete, or retrieve data from the database. Begin by opening the connection to the database using this command,
FDConnection1->Open();
This command goes hand in hand with the close database command, and once we have finished executing all queries, we will need to close the connection to the database using:
FDConnection1->Close();
After establishing and opening the communication portal, we will execute an SQL statement to create the reminder table if it does not exist in the reminder database.
We need only two fields for the table, i.e., the id field and the DateTime field, stored in string format.
To create a table, we can call the ExecSQL statement to execute a SQL query.
This ExecSQL function can be called whenever you want to create tables, insert or delete data, but it can't be used if data needs to be retrieved from the database.
Add the following statement to create a table if it does not exist in the database.
FDConnection1->ExecSQL("CREATE TABLE IF NOT EXISTS Reminder (Id int, time TEXT NOT NULL)");
Next, we want to insert the time into the database. We can still make use of the ExecSQL function after retrieving the DateTime value using the code we wrote in the previous part of this article:
String date = dateTime.FormatString("dd/mm/yyyy HH:mm");
FDConnection1->ExecSQL("INSERT INTO Reminder (time) VALUES ('"+date+"')");
To retrieve added reminders from the database, double click on the "Show Reminders" button to create an empty fastcall function for retrieving reminders.
We will make use of TFDQuery. TFDQuery is used to execute queries and will allow us to make use of result sets.
Here's some sample code illustrating how to make use of TFDquery. Here we want to select all reminders from the Reminder table and display them to the user.
TFDQuery *query;
query = new TFDQuery(this);
query->Connection = FDConnection1;
query->SQL->Text = "SELECT * FROM Reminder";
query->Open();
To make use of TFDQuery, the following header needs to be added to your code:
#include <FireDAC.DApt.hpp>
Code for outputting retrieved data
TVarRec args[1] = {"time"};
Memo1->Lines->Add(System::UnicodeString::Format("|%25s |", args,ARRAYSIZE(args) - 1));
while (!query->Eof) {
TVarRec arguments[1] = { query->FieldByName("time")->AsString};
Memo1->Lines->Add(System::UnicodeString::Format("|%-25s |", arguments, ARRAYSIZE(arguments) - 1));
query->Next();
}
When all the different sections of code shared are added together, we get the following program:
#include <FireDAC.DApt.hpp>
void __fastcall TForm2::buttonAddReminderOnClick(TObject *Sender)
{
TDateTime dateTime;
ReplaceDate(dateTime, DateTimePicker1->Date);
ReplaceTime(dateTime, TimePicker1->Time);
Memo1->Text = "";
FDConnection1->DriverName = "SQLite";
FDConnection1->Params->Values["Database"] = "C:\\Users\\k_umm\\OneDrive\\Desktop\\reminderdb.db";
try
{
FDConnection1->Open();
FDConnection1->ExecSQL("CREATE TABLE IF NOT EXISTS Reminder (id INTEGER PRIMARY KEY AUTOINCREMENT, time TEXT NOT NULL)");
String date = dateTime.FormatString("dd/mm/yyyy HH:mm");
FDConnection1->ExecSQL("INSERT INTO Reminder (time) VALUES ('"+date+"')");
FDConnection1->Close();
}
catch (Exception& E)
{
Memo1->Text = E.Message;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm2::buttonShowReminderOnClick(TObject *Sender)
{
FDConnection1->DriverName = "SQLite";
FDConnection1->Params->Values["Database"] = "C:\\Users\\k_umm\\OneDrive\\Desktop\\reminderdb.db";
try
{
FDConnection1->Open();
TFDQuery *query;
query = new TFDQuery(this);
query->Connection = FDConnection1;
query->SQL->Text = "SELECT * FROM Reminder";
query->Open();
TVarRec args[1] = {"time"};
Memo1->Lines->Add(System::UnicodeString::Format("|%25s |", args, ARRAYSIZE(args) - 1));
while (!query->Eof) {
TVarRec arguments[1] = { query->FieldByName("time")->AsString};
Memo1->Lines->Add(System::UnicodeString::Format("|%-25s |", arguments, ARRAYSIZE(arguments) - 1));
query->Next();
}
query->Close();
FDConnection1->Close();
}
catch (Exception& E)
{
Memo1->Text = E.Message;
}
}
So far, we have built a mini reminder app that gets input from the user and stores it in the database.
Our users will also expect to receive notifications during the specified periods.
FireDate is supported by Android, macOS, and iOS. It can be used by passing information about the date and time when the notification should be triggered.
MyNotification->FireDate = System::Dateutils::EncodeDateTime(2015, 12, 16, 17, 30, 00, 00);
You can find more information about how to make use of notifications in your application here:
For some sample code that you can refer to, click here.