Simple Example

To begin our introduction to libgnomedbmm, we'll start with the simplest program possible. This program will create a window with a Gnome::Db::Grid widget that shows a table stored in a database.

Figure 3.1. Simple Example

Simple Example

Source Code

File: main.cc

#include <iostream>
#include <libgnomedbmm.h>
#include <gtkmm.h>

int main(int argc, char* argv[])
{
  Gtk::Main kit(argc, argv);
  Gnome::Db::init("Example", "1.0", argc, argv);

  Glib::RefPtr<Gnome::Gda::Client> client = Gnome::Gda::Client::create();
 
  Glib::RefPtr<Gnome::Gda::DataModel> model;

  // Create a connection to an example SQLite database. The function might
  // fail, so we have to catch potential exceptions.
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  try
  {
    Glib::RefPtr<Gnome::Gda::Connection> connection = client->open_connection_from_string("SQLite", "DB_DIR=" LIBGNOMEDB_DATADIR ";DB_NAME=demo_db", "" /* username */, "" /* password */);
    model = connection->execute_select_command("SELECT * FROM products");
  }
  catch(const Glib::Error& e)
  {
    std::cerr << e.what() << std::endl;
    return 1;
  }
#else
  std::auto_ptr<Glib::Error> error;
  Glib::RefPtr<Gnome::Gda::Connection> connection = client->open_connection_from_string("SQLite", "DB_DIR=" LIBGNOMEDB_DATADIR ";DB_NAME=demo_db", "" /* username */, "" /* password */, Gnome::Gda::ConnectionOptions(0), error);
  if(connection)
    model = connection->execute_select_command("SELECT * FROM products", error);

  if(error.get() != NULL)
  {
    std::cerr << error->what() << std::endl;
    return 1;
  }
#endif


  Gnome::Db::Grid grid(model);
  Gtk::Window window;

  window.set_title("Libgnomedbmm example window");
  window.set_default_size(400, 400);
  window.add(grid);
  window.show_all();

  kit.run(window);
  return 0;
}

We will now explain each line of the example

#include <gtkmm.h>
#include <libgnomedbmm.h>

All libgnomedbmm programs must include the libgnomedbmm headers. As we also want to show a window (in which the grid will be placed), we also need to include the gtkmm headers. The libgnomedbmm.h header includes the entire API including libgdamm and gtkmm.h all of gtkmm. This is usually not a good idea, because it indirectly includes many headers, slowing down compilation, but for simple programs it suffices.

The next line:

Gtk::Main kit(argc, argv);
Gnome::Db::init("Example", "1.0", argc, argv);

Creates a Gtk::Main object. This is needed in all gtkmm (and therefore libgnomedbmm) applications. The constructor for this object initializes gtkmm, and checks the arguments passed to your application on the command line, looking for standard options such as -display. It takes these from the argument list, leaving anything it does not recognize for your application to parse or ignore. This ensures that all gtkmm applications accept the same set of standard arguments.

Roughly the same applies to the call to Gnome::Db::init(), except that it also wants to know your program's name and version.

Glib::RefPtr<Gnome::Gda::Client> client = Gnome::Gda::Client::create();

This creates a Gnome::Gda::Client object which manages an arbitrary amount of connections to database sources.

Glib::RefPtr<Gnome::Gda::Connection> connection = client->open_connection_from_string("SQLite", "DB_DIR=" LIBGNOMEDB_DATADIR ";DB_NAME=demo_db", "", "");

This tells the client to open a new connection represented by the Gnome::Gda::Connection object. The first argument to the open_connection_from_string() call specifies the database provider. In this example we use SQLite because it does not depend on an external database server running, but other popular providers such as MySQL and PostgreSQL are also supported. The available providers depends on the configure flags with which the underlying libgda library has been compiled.

The second argument is a connection string that consists of semicolon-separated key-value pairs. Each database provider (SQLite, PostgreSQL, etc) may support different keys. For SQLite, DB_DIR and DB_NAME specify the directory and filename (without the extension) of the database file to load. The USER, PASSWORD, HOST, DATABASE and PORT keys are available for nearly any provider.

LIBGNOMEDB_DATADIR is a string constant defined by our automake build system that points to the directory where our SQLlite database file has been installed.

The third and fourth arguments are the username and password with which to connect to the database provider. These parameters override the settings given in the connection string, if any. In this example no authentication is required so we leave them empty.

There is also an optional fifth argument that allows you to specify some further flags for the connection, such as specifying that the database should be opened as read-only. More information about these additional options can be found in the reference documentation.

Glib::RefPtr<Gnome::Gda::DataModel> model = connection->execute_select_command("SELECT * FROM products");

This command executes a SQL SELECT statement and stores the result into a Gnome::Gda::DataModel. A Gnome::Gda::DataModel holds data in a tabular form, with all values in a given column having the same data type.

Gnome::Db::Grid grid(model);

The Gnome::Db::Grid widget can show several rows from a Gnome::Gda::DataModel.

Gtk::Window window;
window.set_title("Libgnomedbmm example window");
window.set_default_size(400, 400);
window.add(grid);
window.show_all();

These few lines set up a window, add the grid to it and show the window on the screen.

kit.run(window);
return 0;

This enters the GTK+ main loop that returns when the window is closed by the user. If we had connected some signal handler we would also have been notified when certain events happened.

Note that most of the Gnome::Gda calls at the beginning of the example might fail, in which case they will throw an exception. Error handling has been omitted here to keep the example simple. However, in a real-world application you should always be prepared for failure situations, such as the database server not being available.

After putting the source code in simple.cc you can compile the above program with gcc using:

g++ simple.cc -o simple `pkg-config libgnomedbmm-3.0 --cflags --libs` -DLIBGNOMEDB_DATADIR=`pkg-config --variable=prefix libgnomedb-3.0`/share/gnome-db/demo

Note that you must surround the pkg-config invocations with backquotes. Backquotes cause the shell to execute the command inside them, and to use the command's output as part of the command line.

The extra --variable=prefix pkg-config command here is just to obtain the path to the installed libgnomedbmm example database file. You may instead hard-code the path into your C++ code, if you find that simpler.

Although we have shown the compilation command for this simple example, you really should use the automake and autoconf tools, as described in "Autoconf, Automake, Libtool", by G. V. Vaughan et al. The examples used in this book are included in the libgnomedbmm-documentation package, with appropriate build files, so we won't show the build commands in future. You'll just need to find the appropriate directory and type make.

To simplify compilation, we use pkg-config, which is present in all (properly installed) libgnomedbmm installations. This program 'knows' what compiler switches are needed to compile programs that use libgnomedbmm. The --cflags option causes pkg-config to output a list of include directories for the compiler to look in; the --libs option requests the list of libraries for the compiler to link with and the directories to find them in. Try running it from your shell-prompt to see the results on your system.