Your First Bond Application
Learn how to make your first desktop database application without writing a single line of source code.
Ensure you have set up and configured Postgres before beginning.
Set up your project
Create a directory for your bond project
$ mkdir simple $ cd simple
Create a postgres database
$ createdb -U postgres bondsimple
This example uses the superuser postgres but in practice you will create your own postgresql user.
Set up your database
Create your database stucture in SQL
CREATE TABLE "paymenttype" ( "id" serial primary key, "description" text, ); CREATE TABLE "payment" ( "id" serial primary key, "paymenttypeid" integer references paymenttype (id), "paymentdate" date default date(now()), "amount" double precision default '0', "note" text );
Save this into a file called simple.sql
Insert it into your database.
$ psql -f simple.sql -U postgres bondsimple
psql is a commandline interface to Postgres.
Explanation of parameters:
-f refers to the SQL file to read
-U is the Postgres username bondsimple, the last parameter is the name of the database
Configure your Bond frontend
The file bondfrontend.conf tells Bond which database to connect to and controls debugging messages.
Note that by default the postgres user does not need a password when connecting from localhost. The IDENT information provided by the operating system is sufficient to authenticate with the postgres server.
The bondfrontend.conf file:
#to connect to postgres db_host = localhost db_username = postgres db_password = db_name = bondsimple #to enable debug debug_enabled = true debug_stream_stdout = stdout debug_stream_stderr = stderr debug_breakonerror = false debug_breakonwarning = false debug_level = 90 #to use gtk uiplugin = gtk #the name of your main xml file bondxml = simple.xml #dtd validation is a good idea to find error in xml dtd_validation = true
Writing your application in XML
The best thing about Bond is how you can write a database frontend by just using XML.
Create simple.xml with the basics needed:
<!DOCTYPE bond SYSTEM "../../bond-4.0.dtd"> <bond xmlns="http://bond.treshna.com/ns/v2.0" xmlns:xi="http://www.w3.org/2003/XInclude"> <project name="Simple bond example" defaultvisible="false" author="treshna Enterprises Ltd"/> <window name="payment-win" title="Payment details" visible="true"> </window> </bond>
Save this file.
Use the following command to see your application. You will see a blank window appear with the title ‘Payment Details’.
$ bondfronted
You should see a window like the following:
Basic content
A blank window isn’t much fun so next we’ll link to the database, create a menubar and and some widgets.
Insert the following XML between the window tags to link to the database.
<dbobject name="payment-win"> <table>payment</table> <loadall/> </dbobject>
This creates a database object link to the table named payment and includes all the fields.
Because you’re using GTK you need a box and cells to put widgets inside. Insert the following after the djobject. We will place the menu and toolbar within the cells of this vbox.
<vbox spacing="0"> <cell> </cell> <cell> </cell> </vbox>
The Menu
To create a menu with just one item we need the following:
- A menu bar to put the menu labels in. <menubar>
- A menu label. This example shows the label ‘Payment’ and ‘P’ is the short key. <menu label=”_Payment”>
- A menu item. This has the predefined icon “gtk-close”. <menuitem stock=”gtk-close”>
- A trigger on the item. This catches a click on the item. <trigger event=”click”>
- An actions. This calls the close function. <api call=”close”>
- A widget reference. This refers to payment-win which is the window name. It is used as an argument to the API function. <widget>payment-win</widget>
Add the following XML between the first cell tags in the vbox.
<menubar> <menu label="_Payment"> <menuitem stock="gtk-close"> <trigger event="click"> <api call="close"> <widget>payment-win</widget> </api> </trigger> </menuitem> </menu> </menubar>
Your XML code should now look like this:
<!DOCTYPE bond SYSTEM "../../bond-4.0.dtd"> <bond xmlns="http://bond.treshna.com/ns/v2.0" xmlns:xi="http://www.w3.org/2003/XInclude"> <project name="Simple bond example" defaultvisible="false" author="treshna Enterprises Ltd"/> <window name="payment-win" title="Payment details" visible="true"> <dbobject name="payment-win"> <table>payment</table> <loadall/> </dbobject> <vbox spacing="0"> <cell> <menubar> <menu label="_Payment"> <menuitem stock="gtk-close"> <trigger event="click"> <api call="close"> <widget>payment-win</widget> </api> </trigger> </menuitem> </menu> </menubar> </cell> <cell> </cell> </vbox> </window> </bond>
Execute your application with
$ bondfrontendYour application should now look like the image below.
Adding a toolbar
This is very similar to adding the menu bar.
We will add the following actions:
- “close” to close the windows
- “add” to add a new record
- “delete” to delete the curent record
- “save” to save the curent record
First we create a toolbar tag, eg. <toolbar style=”icons”> </toolbar>
For each toolbar element we create a <toolbutton> tag which contains a trigger event and an api call.
Insert the following XML between the 2nd set of cell tags.
<toolbar style="icons"> <toolbutton stock="gtk-close"> <trigger event="click"> <api call="close"> <widget>payment-win</widget> </api> </trigger> </toolbutton> <toolbutton stock="gtk-add"> <trigger event="click"> <api call="add"> <widget>payment-win</widget> </api> </trigger> </toolbutton> <toolbutton stock="gtk-delete"> <trigger event="click"> <api call="delete" confirm="true"> <widget>payment-win</widget> </api> </trigger> </toolbutton> <toolbutton stock="gtk-save"> <trigger event="click"> <api call="save"> <widget>payment-win</widget> </api> </trigger> </toolbutton> </toolbar>
Adding widgets for our data
We need widgets for:
- The data layout
- A readonly field for the payment id
- A text entry box for the date field
- A combo list for the payment type
- A text entry box for the amount of the payment
- A large text entry box for the notes
- The list of records
We will refer to the SQL for the database structure for field names and data types:
CREATE TABLE "paymenttype" ( "id" serial primary key, "description" text ); CREATE TABLE "payment" ( "id" serial primary key, "paymenttypeid" integer references paymenttype (id), "paymentdate" date default date(now()), "amount" double precision default '0', "note" text );
The layout
This makes a table with 3 rows. We’re going to place our widgets in these new cells.
Add another set of <cell></cell> in the vbox tag.
Insert the following XML between the new cell tags.
<box rows="6" columns="4"> <cell expand="false" xpos="1"> </cell> <cell expand="false" xpos="2"> </cell> <cell expand="true" xpos="1" ypos="6" xspan="2"> </cell> </box>
The payment id
This tag is the easiest.
Insert the following label tag into the first cell in the box tag.
<label>id</label>
We also need a read-only field to show the payment id. This simply shows the value of the id field of the current dbobject. The current dbobject is defined by the window, payment-win which is using the payment table.
Insert the following entry tag into the second cell in the box tag.
<entry readonly="true" alignment="right" minwidth="20"> <field>id</field> </entry>
Your XML should now look like this:
<cell> <box rows="6" columns="4"> <cell expand="false" xpos="1"> <label>id</label> </cell> <cell expand="false" xpos="2"> <entry readonly="true" alignment="right" minwidth="20"> <field>id</field> </entry> </cell> <cell expand="true" xpos="1" ypos="6" xspan="2"> </cell> </box> </cell>
Text entry box for the date field
Create a label tag for the date
<label>date</label>
We need an entry box. It’s the same as the id tag but it’s editable.
The inputrestrict tag restricts the type of data which the user can enter.
<entry minwidth="130" readonly="false"> <field>paymentdate</field> <inputrestrict>date</inputrestrict> </entry>
We need to surround our label and entry tags with cell tags that control the position. Notice the xpos and ypos parameters.
Add the following XML to the box tag:
<cell expand="true" xpos="1" ypos="2"> <label>date</label> </cell> <cell xpos="2" ypos="2"> <entry minwidth="130" readonly="false"> <field>paymentdate</field> <inputrestrict>date</inputrestrict> </entry> </cell>
Combo list for the payment type
This displays the payment type. There is a foreign key relationship in the database between payment.paymenttypeid and paymentype.id. See the SQL for more details.
To display the descriptions of the paymenttype we need another dbobject. This XML loads the paymenttype table.
<dbobject> <sql> SELECT * FROM paymenttype </sql> </dbobject>
We need two fields. The display field and the reference field. In this case the field we will display is ‘description’ and the reference field is ‘id’.
<primaryfield>id</primaryfield> <showfield>description</showfield>
We also need to specify the link to the payment table.
<field>paymenttypeid</field>
To create the combo box, which is a dropdown tag. We use the following XML. We’re up to the third row now and we want this to appear on the right so we set xpos to 2.
Insert the following XML:
<cell xpos="2" ypos="3"> <dropdown> <lookup> <dbobject> <sql>SELECT * FROM paymenttype</sql> </dbobject> <primaryfield>id</primaryfield> <showfield>description</showfield> </lookup> <field>paymenttypeid</field> </dropdown> </cell>
Text entry box for the amount of the payment
Create a label tag and an entry tag. Add two cell tags to control the position.
Insert the following XML into the box tag.
<cell expand="true" xpos="1" ypos="4"> <label>amount</label> </cell> <cell expand="true" xpos="2" ypos="4"> <entry alignment="right" minwidth="75"> <field>amount</field> </entry> </cell>
Large text entry box for the notes
A textview tag is bigger than an entry box
Add the following XML to the box tag. The xspan=2 parameter means that the textview tag spans the width of two columns.
<cell expand="true" xpos="1" ypos="5" xspan="2"> <textview> <field>note</field> </textview> </cell>
The list of records
Our last widget is the list of saved records in the database.
It will display the date and amount of each payment. By referring to our SQL we know that the fields are called: paymentdate and amount.
List tags contain column tags which in turn contain field tags. Our list tag has a name, can be sorted and has a minimum height of 130.
The column tags have titles and contain one field tag each.
The final cell tags have been already added:
<cell expand="true" xpos="1" ypos="6" xspan="2"> </cell>Insert the following XML into the last cell tags in the box tag.
<list name="paymentlist" sortable="true" minheight="130"> <column title="Date"> <field>paymentdate</field> </column> <column title="Amount"> <field>amount</field> </column> </list>
The final XML
Your XML file should now look like this:
<!DOCTYPE bond SYSTEM "../../bond-4.0.dtd"> <bond xmlns="http://bond.treshna.com/ns/v2.0" xmlns:xi="http://www.w3.org/2003/XInclude"> <project name="Simple bond example" defaultvisible="false" author="treshna Enterprises Ltd"/> <window name="payment-win" title="Payment details" visible="true"> <dbobject name="payment-win"> <table>payment</table> <loadall/> </dbobject> <vbox spacing="0"> <cell> <menubar> <menu label="_Payment"> <menuitem stock="gtk-close"> <trigger event="click"> <api call="close"> <widget>payment-win</widget> </api> </trigger> </menuitem> </menu> </menubar> </cell> <cell> <toolbar style="icons"> <toolbutton stock="gtk-close"> <trigger event="click"> <api call="close"> <widget>payment-win</widget> </api> </trigger> </toolbutton> <toolbutton stock="gtk-add"> <trigger event="click"> <api call="add"> <widget>payment-win</widget> </api> </trigger> </toolbutton> <toolbutton stock="gtk-delete"> <trigger event="click"> <api call="delete" confirm="true"> <widget>payment-win</widget> </api> </trigger> </toolbutton> <toolbutton stock="gtk-save"> <trigger event="click"> <api call="save"> <widget>payment-win</widget> </api> </trigger> </toolbutton> </toolbar> </cell> <cell> <box rows="6" columns="4"> <cell expand="false" xpos="1"> <label>id</label> </cell> <cell expand="false" xpos="2"> <entry readonly="true" alignment="right" minwidth="20"> <field>id</field> </entry> </cell> <cell expand="true" xpos="1" ypos="2"> <label>date</label> </cell> <cell xpos="2" ypos="2"> <entry minwidth="130" readonly="false"> <field>paymentdate</field> <inputrestrict>date</inputrestrict> </entry> </cell> <cell xpos="2" ypos="2"> <entry minwidth="130" readonly="false"> <field>paymentdate</field> <inputrestrict>date</inputrestrict> </entry> </cell> <cell xpos="2" ypos="3"> <dropdown> <lookup> <dbobject> <sql>SELECT * FROM paymenttype</sql> </dbobject> <primaryfield>id</primaryfield> <showfield>description</showfield> </lookup> <field>paymenttypeid</field> </dropdown> </cell> <cell expand="true" xpos="1" ypos="4"> <label>amount</label> </cell> <cell expand="true" xpos="2" ypos="4"> <entry alignment="right" minwidth="75"> <field>amount</field> </entry> </cell> <cell expand="true" xpos="1" ypos="5" xspan="2"> <textview> <field>note</field> </textview> </cell> <cell expand="true" xpos="1" ypos="6" xspan="2"> <list name="paymentlist" sortable="true" minheight="130"> <column title="Date"> <field>paymentdate</field> </column> <column title="Amount"> <field>amount</field> </column> </list> </cell> </box> </cell> </vbox> </window> </bond>
Testing your program
Just run $ bondfrontend from the command line while in the simple directory and your application should look like the sample one below.
Congratulations you just made a database application without writing a single line of source code.