GDA Backend implementation

GDA provides most of the core backend functionalities, required to access databases.

UML diagram for Classes

classes-uml.png

Table Class

Table class is an implementation of DbTable interface. It uses GDA to get access to a database's table description.

In order to load data, you need to set a Gda.Connection and a table's name. Then update() method will introspect table information using GDA's MetaStore object and executing SELECT commands to retrive meta data to strore store it, you don't need to call update() again unless your table definition has changed.

Table class UML definition

UML definition

table-class-uml.png

Using a Table class to access a table meta data

This setup a table to be added to a database's table:

   1 var t = new Table ();
   2   t.name = "created_table";
   3   t.connection = connection;
   4   var field = new FieldInfo ();
   5   // Setup column id
   6   field.name = "id";
   7   field.value_type = typeof (int);
   8   field.attributes = DbFieldInfo.Attribute.PRIMARY_KEY | 
   9                      DbFieldInfo.Attribute.AUTO_INCREMENT;
  10   t.set_field (field);
  11   
  12   // Setup column name
  13   var field1 = new FieldInfo ();
  14   field1.name = "name";
  15   field1.value_type = typeof (string);
  16   field1.attributes = DbFieldInfo.Attribute.NONE;
  17   t.set_field (field1);
  18   
  19   // Setup column company
  20   var field2 = new FieldInfo ();
  21   field2.name = "company";
  22   field2.value_type = typeof (int);
  23   field2.default_value = 1;
  24   
  25   // Setup column's foreign key
  26   var fk = new DbFieldInfo.ForeignKey ();
  27   var rt = new Table ();
  28   rt.name = "company";
  29   fk.reftable = rt;
  30   fk.refcol.add ("id");
  31   fk.update_rule = DbFieldInfo.ForeignKey.Rule.CASCADE;
  32   fk.delete_rule = DbFieldInfo.ForeignKey.Rule.SET_DEFAULT;
  33   field2.fkey = fk;
  34   t.set_field (field2);
  35   
  36   // Append new table
  37   t.append ();

In the above code a new table will be added. Create a new Table object, set its name and connection, use Table.set_field() to set column definitions. You must create DbFieldInfo objects, setting its name, type and attributes is enough to be set in a table. If your column must be a PRIMARY_KEY you must set DbFieldInfo.attributes to DbFieldInfo.Attribute.PRIMARY_KEY; if it is autoincrement key you must use | operator to add a DbFieldInfo.Attribute.AUTO_INCREMENT attribute.

If the column will refer to a column in other table as a foreign key you must set DbFieldInfo.fkey. DbFieldInfo.ForeignKey object is used for column's foreign keys.

Deleting tables

If you want to delete a table you must create a new Table object, set a name and a Gda.Connection; finally you just call Table.drop() method.

This code describes how to delete a table in a database:

   1 var t = new Table ();
   2 t.name = "table_name";
   3 t.connection = connection;
   4 t.drop ();

Iterating through Fields definitions

You can iterate over Table's fields descriptions using Vala foreach statement, by using Record.fields property; it's a Gee.Collection of DbFieldInfo objects, then you can use:

   1 foreach (DbFieldInfo f in table.fields) {
   2   /* work with DbField object */
   3 }

The same apply for all keys you set by using Table.primary_keys property.

Access rows in a table

All rows in a table can be accessed using Table.records property, as a Gee.Collection of DbRecord objects. Internally, when this property is accessed a SELECT * FROM table SQL command is executed, you can filter them using Gee.Traversable.filter() function.

Table's dependencies

In order to introspect a database table, you must create a new Table object, set a name and a Gda.Connection, then call Table.update(). After this you are able to know its dependencies.

ForeignKeys

You can access to all DbTable objects referenced in foreign keys for each column in the table definition, using Table.depends, through a Gee.Collection of DbTable objects.

Tables referencing your table

Using Table.referenced property, you can access to a Gee.Collection of DbTable objects that depends on your table.

Record Class

Record class is an implementation of DbRecord interface. It uses GDA to get access to a database's row in a table.

In order to load data, you need to set a Gda.Connection, a table and a key. Then update() method execute a SELECT command using the key to find the required row in the table.

Record class UML definition

This diagram describes Record class and its implementations.

figures/record-class-uml.png

Using a Record class to access a row in a table

This codes initiate a Record class, set a table to use, a key and a connection in order to call update():

   1 var r = new Record ();
   2 var t = new Table ();
   3 t.name = "customer";
   4 r.table = t;
   5 r.connection = connection;
   6 r.set_key_value ("id", 1);
   7 r.update ();

In the above code, connection is opened before to be set to Record.connection property. You need to setup a Table class to set to Record.table property, but just set Table.name property to the table's name is required. Use Record.set_key_value() method to set the value to the column used in the table as the primary key and to allow update() method to find the correct row (the WHERE clause in SELECT statement), if more than one key exists you must set it; you must know the column and type of value to set.

Using a Record class to add a new row in a table

This code set up a row to be added to a database's table:

   1 var r = new Record ();
   2 var t = new Table ();
   3 t.name = "customer";
   4 r.table = t;
   5 r.connection = connection;
   6 r.set_field_value ("name", "Clausse Rayman");
   7 r.set_field_value ("company", "Packing Sources, Ltd.");
   8 r.append ();

In the above code a new row will be added. Create a new Record object, set a table to add a new row to; use Record.set_field_value() to set values to columns in the table, you must know columns and data type to set. At the end callRecord.save() to add the new row.

Record.set_field_value() doesn't know if the columns and type is correct, just store the value to used in an INSERT statement; if key is set by database engine it will be added automatically, if not you must set it in order to execute save() with no errors.

Update data in a row

Once you have set a key and a table to a Record object, you can call Record.set_field_value() to change row's column's values, once done, you can call Record.save() to call an UPDATE command and update database's row/column values.

Updating columns' values

This code sets a key and a table to find a row and set a column's value, then call save() to update data in the database:

   1 var r = new Record ();
   2 r.connection = connection;
   3 /* Set a value to the key you want to use to select the correct row */
   4 r.set_key_value ("id", 1);
   5 r.set_field_value ("name", "Jack Swan");
   6 r.save ();

Deleting rows

If you want to delete a row in a database's table, just create a new Record object, set a key, a table and a connection, then call Record.drop().

How to delete a row in a table

This code shows how to setup and delete a row to be deleted in a database's table:

   1 var r = new Record ();
   2 r.connection = connection;
   3 var t = new Table ();
   4 t.name = "table_name";
   5 r.table = t;
   6 r.set_key_value ("id", 1);
   7 r.drop ();

Iterating through Fields

You can iterate over Record's fields using Vala foreach statement, by using Record.fields property; it's a Gee.Collection of DbField objects, then you can use:

   1   foreach (DbField f in record.fields) {
   2     /* work with DbField object */
   3   }

The same apply for all keys you set by using Record.keys property.

Subclassing Record class

Record class could be used as base for others. Is useful to wrap Record.set_field_value() into your class property to hide database access. Use try{} catch{} to avoid warnings for unhandled error.

   1   class MyRecord : Record
   2   {
   3     public MyRecord () { /* Your init code */ }
   4     
   5     public string name
   6     {
   7       get 
   8       { 
   9         try {
  10           return this.get_value ("name");
  11         }
  12         catch (Error e) {
  13           GLib.warning ("ERROR on getting value from name property: " + e.message)
  14         } 
  15       }
  16       
  17       set 
  18       { 
  19         try {
  20           return this.set_field_value ("name", value);
  21         }
  22         catch (Error e) {
  23           GLib.warning ("ERROR on setting value to name property: " + e.message)
  24         } 
  25       }
  26     }
  27   }

The above code declares a MyRecord.name property witch uses Record.get_value() and Record.set_field_value() from its base class, to get and set its value.

Projects/GdaValaExtensions/GdaClasses (last edited 2014-01-23 22:10:30 by DanielEspinosaOrtiz)