Appendix B. Loading a Dict from XML

This example shows how you might obtain a Gnome::Gda::Dict by loading it from an XML file instead of querying the database. It also saves the dict back to XML when the program finishs.

Source Code

File: examplewindow.h

#include <memory>

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

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow(const Glib::RefPtr<Gnome::Gda::Dict>& dict);
    
private:
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  void create_model(const Glib::RefPtr<Gnome::Gda::Dict>& dict);
#else
  void create_model(const Glib::RefPtr<Gnome::Gda::Dict>& dict, std::auto_ptr<Glib::Error>& error);
#endif
  Glib::RefPtr<Gnome::Gda::DataModelQuery> m_model;
    
  Gtk::VBox m_box;
  Gtk::Label m_label;
  Gnome::Db::Grid* m_grid;
};

File: main.cc

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

#include <iostream>

#include "examplewindow.h"

#ifdef GLIBMM_EXCEPTIONS_ENABLED
void do_example(const Glib::RefPtr<Gnome::Gda::Dict>& dict)
#else
void do_example(const Glib::RefPtr<Gnome::Gda::Dict>& dict, std::auto_ptr<Glib::Error>& error)
#endif // GLIBMM_EXCEPTIONS_ENABLED
{
  // File to try to read dictionary from
  std::string filename = "my_dict.xml";

  Glib::RefPtr<Gnome::Gda::Client> client = Gnome::Gda::Client::create();
  Glib::ustring connection_string = "DB_DIR=" LIBGNOMEDB_DATADIR ";DB_NAME=demo_db";

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  Glib::RefPtr<Gnome::Gda::Connection> cnc = client->open_connection_from_string("SQLite", connection_string, "" /* username */, "" /* password */);
#else
  Glib::RefPtr<Gnome::Gda::Connection> cnc = client->open_connection_from_string("SQLite", connection_string, "" /* username */, "" /* password */, Gnome::Gda::ConnectionOptions(0), error);
  if(error.get() != NULL) return;
#endif // GLIBMM_EXCEPTIONS_ENABLED
  dict->set_connection(cnc);

  // Load from XML file if present, query database otherwise
  if(Glib::file_test(filename, Glib::FILE_TEST_IS_REGULAR))
  {
#ifdef GLIBMM_EXCEPTIONS_ENABLED
    dict->load_xml_file(filename);
#else
    dict->load_xml_file(filename, error);
    if(error.get() != NULL) return;
#endif // GLIBMM_EXCEPTIONS_ENABLED
  }
  else
  {
#ifdef GLIBMM_EXCEPTIONS_ENABLED
    dict->update_dbms_meta_data();
#else
    dict->update_dbms_meta_data(error);
    if(error.get() != NULL) return;
#endif // GLIBMM_EXCEPTIONS_ENABLED
  }

  ExampleWindow window(dict);
  Gtk::Main::run(window);

  // Save dict back to XML after program termination
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  dict->save_xml_file(filename);
#else
  dict->save_xml_file(filename, error);
#endif // GLIBMM_EXCEPTIONS_ENABLED
}


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

  Glib::RefPtr<Gnome::Gda::Dict> dict = Gnome::Gda::Dict::create();

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  try
  {
    do_example(dict);
  }
  catch(const Glib::Error& err)
  {
    std::cerr << "Exception caught: " << err.what() << std::endl;
    return 1;
  }
#else
  std::auto_ptr<Glib::Error> error;
  do_example(dict, error);
  if(error.get() != NULL)
  {
    std::cerr << "Exception caught: " << error->what() << std::endl;
    return 1;
  }
#endif // GLIBMM_EXCEPTIONS_ENABLED

  return 0;
}

File: examplewindow.cc

#include "examplewindow.h" 

#include <libgdamm.h>
#include <iostream>

#ifdef GLIBMM_EXCEPTIONS_ENABLED
void ExampleWindow::create_model(const Glib::RefPtr<Gnome::Gda::Dict>& dict)
#else
void ExampleWindow::create_model(const Glib::RefPtr<Gnome::Gda::Dict>& dict, std::auto_ptr<Glib::Error>& error)
#endif // GLIBMM_EXCEPTIONS_ENABLED
{
  Glib::RefPtr<Gnome::Gda::Query> query = Gnome::Gda::Query::create(dict);

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  query->set_sql_text("SELECT ref, category, name, price, wh_stored FROM products");
#else
  query->set_sql_text("SELECT ref, category, name, price, wh_stored FROM products", error);
  if(error.get() != NULL) return;
#endif // GLIBMM_EXCEPTIONS_ENABLED
  
  m_model = Gnome::Gda::DataModelQuery::create(query);

  const Glib::ustring update_query =
                 "UPDATE products set "
                 "ref=##/*name:'+0' type:gchararray*/, "
                 "category=##/*name:'+1' type:gint*/,"
                 "name=##/*name:'+2' type:gchararray*/, "
                 "wh_stored=##/*name:'+4' type:gint*/ "
                 "WHERE ref=##/*name:'-0' type:gchararray*/";

  const Glib::ustring delete_query =
                 "DELETE FROM products WHERE ref=##/*name:'-0' type:gchararray*/";

  const Glib::ustring insert_query =
                 "INSERT INTO products (ref, category, name, price, wh_stored) "
                 "VALUES (##/*name:'+0' type:gchararray*/, "
                 "##/*name:'+1' type:gint*/, "
                 "##/*name:'+2' type:gchararray*/, "
                 "1.0, "
                 "##/*name:'+4' type:gint*/)";

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  m_model->set_modification_query(update_query);
  m_model->set_modification_query(delete_query);
  m_model->set_modification_query(insert_query);
#else
  m_model->set_modification_query(update_query, error);
  m_model->set_modification_query(delete_query, error);
  m_model->set_modification_query(insert_query, error);
#endif
}

ExampleWindow::ExampleWindow(const Glib::RefPtr<Gnome::Gda::Dict>& dict) :
  m_label("The following Gnome::Db::Grid widget displays data from the 'products' table.\n\n"
          "As modification queries are provided, the data is read-write\n(except for the 'price' "
          "field as these queries voluntarily omit that field).")
{    
  m_box.set_border_width(6);
  m_box.pack_start(m_label, Gtk::PACK_SHRINK);

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  try
  {
    create_model(dict);
  }
  catch(const Glib::Error& err)
  {
    std::cerr << "Exception caught: " << err.what() << std::endl;
    exit(1);
  }
#else
  std::auto_ptr<Glib::Error> error;
  create_model(dict, error);
  if(error.get() != NULL)
  {
    std::cerr << "Exception caught: " << error->what() << std::endl;
    exit(1);
  }
#endif

  /* Create the demo widget */
  m_grid = Gtk::manage(new Gnome::Db::Grid(m_model));
  m_box.pack_start(*m_grid);
  add(m_box);
  set_default_size(0, 400);
  show_all();
}