Recently I have been creating a number of applications using InterBase on iOS and Android using FireDAC components to talk to the database. One route to achieving this is by create the database file and table structure either via iSQL or using IBConsole GUI first before using it in your project. Once you have the database file (which is simple enough to do) you then have to deploy the file along with the application using the deployment wizard. This all adds a little size to the application package initially along with some extra configuration.
In the attempt to be lazy (and to save a few bytes in my application package), I decided that as most the time, I only really want to connect to a database that I then add the data to that maybe I should do this via code. This would save me having to deploy a database file and also setup the paths for deployment reducing my work upfront.
Luckily, this is easy to achieve with FireDAC.
Table of Contents
Creating a blank database from the IDE
You can actually create a blank database file directly from the IDE by adding a TFDConnection to your application code. Double clicking on the connection opens the FireDAC Connection Editor. If you choose IB as the driver you will then see a list of values. You can set the username and password (e.g. SYSDBA / masterkey) to any registered local user. If you set the Database property to a local file path and then choose CreateDatabase and set it to True and “Test” the connection it will create a database file. Obviously, if the file exists it will error as the file is already there, but this is what you need to be able to do from code to get a blank database.
Creating a blank database on the fly
Understanding what properties need to be set, you can now call them directly from code at run time. To test this, I created a single TButton application with a TMemo to show output in a new FireMonkey Mobile Application.
Setting database file path
First task is setting the local file path at run time. There are two ways to do this with FireDAC. You can either set the path yourself e.g.
1 2 |
DBPath := TPath.GetDocumentsPath+PathDelim+<span style="color:#0000ff;"><span style="color:#0000ff;">'interbase'</span></span>+PathDelim+<span style="color:#0000ff;"><span style="color:#0000ff;">'MyDB.ib'</span></span>;<br> FDConnection1.Params.Values[<span style="color: #0000ff"><span style="color: #0000ff">'Database'</span></span>] := DBPath; |
or you can use ask FireDAC to sort out the documents path using $(doc) variable in the path string. This is useful if you want to hardcode this into the path property.
Setting CreateDatabase paramater
To avoid creating an error, we can set the CreateDatabase to True if the database file does not exist by using the function FileExists(FilePath : string) to check for the local file. This can be done as the database is local and we are running embedded.
1 |
FDConnection1.Params.Values[<span style="color: #0000ff"><span style="color: #0000ff">'CreateDatabase'</span></span>] := BoolToStr(<strong>not</strong> FileExists(DBPath),True); |
Creating a table, inserting values, reading them back.
Now there is access to a local database file, the next step is to create the table if it does not exist already. This can be done using calls to query the database meta data easily. While InterBase does not yet support language syntax for creating a table if it does not exist, you can collect the tables easily.
To try this on mobile a simple one button application with a memo for the output is enough
1 |
<a href="http://blogs.embarcadero.com/files/2014/02/screen-shot-2014-02-14-at-220158_11185.png"><img alt='screen-shot-2014-02-14-at-220158_11185-6021255' src='https://blogs.embarcadero.com/wp-content/uploads/2014/02/screen-shot-2014-02-14-at-220158_11185-6021255.png' alt=" " width="500" height="423"></a> |
Using a TFDConnection, TFDGUIxWaitCursor and TFDPhysIBDriverLink I have also used TFDQuery and TFDTransaction to run the database transaction.
The following code block is my entire demo button click. You can see how it uses the FDConnection to GetTableNames into a StringList and then check for the value in the string list. Following that if the table doesn’t exist, it creates the table and inserts a number of records using the block insert support that InterBase has that FireDAC supports. Once the data is inserted, then it is fetched all using the same query.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<span style="color:#000080;"><strong>procedure</strong></span> TForm4.Button1Click(Sender: TObject);<br> <span style="color:#000080;"><strong>var</strong></span><br> I: Integer;<br> Tables : TStringList;<br> DBPath: string;<br> <span style="color:#000080;"><strong>begin</strong></span><br> // Here to make it easier to debug to my standard local DB store on WIndows.<br> <span style="color:#339966;">{$IFNDEF MSWINDOWS}</span><br> DBPath := TPath.GetDocumentsPath+PathDelim+<span style="color:#0000ff;">'interbase'</span>+PathDelim+<span style="color:#0000ff;">'MyDB.ib'</span>;<br> <span style="color:#339966;">{$ELSE}</span><br> DBPath := <span style="color:#0000ff;">'c:dataMyDB.IB'</span>;<br> <span style="color:#339966;"> {$ENDIF}</span><br> <span style="color:#000080;"><strong>try</strong></span><br> FDConnection1.Params.Values[<span style="color: #0000ff">'Database'</span>] := DBPath;<br> FDConnection1.Params.Values[<span style="color: #0000ff">'CreateDatabase'</span>] := BoolToStr(not FileExists(DBPath),True);<br> FDConnection1.Open;<br> Tables := TStringList.Create;<br> <span style="color:#000080;"><strong>try<br> </strong></span> FDConnection1.GetTableNames('','','',Tables); // Get Tables |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<span style="color:#000080;"><strong>if</strong></span> Tables.IndexOf(<span style="color:#0000ff;">'FOO'</span>) = -1 <span style="color:#000080;"><strong>then begin</strong></span><br> FDQuery1.SQL.Text := <span style="color:#0000ff;">'CREATE TABLE FOO (FOO_ID INTEGER)'</span>;<br> FDQuery1.ExecSQL;<br> FDQuery1.SQL.Text := <span style="color:#0000ff;">'INSERT INTO FOO (FOO_ID) VALUES (:FOO)'</span>;<br> FDQuery1.Params.ArraySize := 10;<br> <span style="color:#000080;"><strong>for</strong></span> I := <span style="color:#000080;">0 <strong>to</strong> 9 <strong>do</strong> </span><br> FDQuery1.ParamByName(<span style="color:#0000ff;">'FOO'</span>).AsIntegers[I] := I;<br> FDTransaction1.StartTransaction;<br> <span style="color:#000080;"><strong>try</strong></span><br> FDQuery1.Execute(FDQuery1.Params.ArraySize,0);<br> FDTransaction1.Commit;<br> <span style="color:#000080;"><strong>except</strong></span><br> FDTransaction1.Rollback;<br> <span style="color:#000080;"><strong>end;</strong></span><br> <span style="color:#000080;"><strong>end;</strong></span><br> <span style="color:#000080;"><strong>finally</strong></span><br> Tables.Free;<br> <span style="color:#000080;"><strong>end;</strong></span><br> FDQuery1.SQL.Text := <span style="color:#0000ff;">'SELECT * FROM FOO'</span>; // Selecting values<br> FDQuery1.Open;<br> Memo1.BeginUpdate;<br> <span style="color:#000080;"><strong>try</strong></span><br> Memo1.Lines.Clear;<br> <span style="color:#000080;"><strong>while</strong></span> <span style="color:#000080;"><strong>not</strong></span> FDQuery1.Eof <span style="color:#000080;"><strong>do begin</strong></span><br> Memo1.Lines.Add(FDQuery1.FieldByName(<span style="color:#0000ff;">'FOO_ID'</span>).AsString);<br> FDQuery1.Next;<br> <span style="color:#000080;"><strong>end;</strong></span><br> <span style="color:#000080;"><strong>finally</strong></span><br> Memo1.EndUpdate;<br> <span style="color:#000080;"><strong>end;</strong></span><br> <span style="color:#000080;"><strong>except</strong></span><br> <span style="color:#000080;"><strong>on</strong></span> e:exception <span style="color:#000080;"><strong>do</strong></span><br> ShowMessage(e.Message);<br> <span style="color:#000080;"><strong>end;</strong></span><br> <br> <span style="color:#000080;"><strong>end;</strong></span> |
Running the application provides the following output
To Conclude
Using InterBase on mobile you can get a lot of benefits, especially when you are storing local data. Using the properties exposed in FireDAC you can easily create and manage a local database on the device without having to deploy one from the start. This helps with making deployment simpler. If you do need to deploy a database you can still do this as InterBase supports the same on disk structure for Windows, Mac, Linux, Solaris, Android and iOS.
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition