Adjusted to new version of libpqxx.
[gnucomo.git] / src / lib / database.cpp
index 4377025..c585712 100644 (file)
@@ -8,7 +8,7 @@
 ***********************
 **      FILE NAME      : database.cpp
 **      SYSTEM NAME    : Gnucomo - Gnu Computer Monitoring
-**      VERSION NUMBER : $Revision: 1.6 $
+**      VERSION NUMBER : $Revision: 1.13 $
 **
 **  DESCRIPTION      :  Implementation of the gnucomo database classes
 **
 ********************************
 **      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
 **      CREATION DATE   : Sep 10, 2002
-**      LAST UPDATE     : Jan 31, 2003
+**      LAST UPDATE     : Aug 17, 2003
 **      MODIFICATIONS   : 
 **************************************************************************/
 
 /*****************************
    $Log: database.cpp,v $
-   Revision 1.6  2003-02-05 09:33:42  arjen
+   Revision 1.13  2011-03-24 10:21:47  arjen
+   Adjusted to new version of libpqxx.
+
+   Revision 1.12  2003/12/22 10:28:26  arjen
+   Catch an exception if we can not setup a database transaction.
+
+   Revision 1.11  2003/12/04 10:40:28  arjen
+   Fixed name conflict with 'double log(double)'
+
+   Revision 1.10  2003/12/03 08:23:17  arjen
+   Write messages to the log stream instead of cout.
+
+   Revision 1.9  2003/08/17 11:39:56  arjen
+   Changed the gnucomo_database class to the new PostgreSQL
+   library, libpqxx
+
+   Revision 1.8  2003/07/31 15:44:02  arjen
+   Removed debug output.
+
+   Revision 1.7  2003/02/19 12:07:55  arjen
+   Use the SQL function currval() to obtain the identification number
+   of the most recently created notification.
+
+   Revision 1.6  2003/02/05 09:33:42  arjen
    gnucomo_database::new_notification() retruns the id number of the
    newly created notification record.
 
 
 *****************************/
 
-static const char *RCSID = "$Id: database.cpp,v 1.6 2003-02-05 09:33:42 arjen Exp $";
+static const char *RCSID = "$Id: database.cpp,v 1.13 2011-03-24 10:21:47 arjen Exp $";
 
 #include <AXE/date.h>
 
+//#define DEBUG
+
 #include "database.h"
 
-extern bool verbose;   /*  Defined in the main application */
+extern std::ostream *Log;
 
 /*=========================================================================
 **  NAME           : gnucomo_database
@@ -68,24 +93,70 @@ extern bool verbose;   /*  Defined in the main application */
 **  VARS CHANGED   :
 **  FUNCTIONS USED :
 **  SEE ALSO       :
-**  LAST MODIFIED  : Sep 26, 2002
+**  LAST MODIFIED  : Aug 17, 2003
 **=========================================================================
 */
 
+static int gdb_refcount = 0;
+
 gnucomo_database::gnucomo_database(gnucomo_config *c)
 {
    cfg = c;
 
-   if (verbose)
+   dbconn = new pqxx::connection(cfg->Database());
+
+   if (!dbconn->is_open())
+   {
+      std::cerr << "Connection to database failed.\n";
+   }
+   else
    {
-      std::cout <<  "Database connection string = " << cfg->Database() << "\n";
+      try
+      {
+         // Create the transaction object
+
+         //dbxact = new pqxx::transaction<pqxx::serializable>(*dbconn, "GnuCoMo");
+         dbxact = new pqxx::work(*dbconn, "GnuCoMo");
+      }
+      catch (std::exception &e)
+      {
+         *Log << "Cannot setup the database transaction: " << e.what() << "\n";
+         *Log << "You are probably using incompatible versions of PostgreSQL an libpqxx.\n";
+         exit(1);
+      }
+      gdb_refcount++;
    }
+}
+
+gnucomo_database::gnucomo_database(const gnucomo_database &gdb)
+{
+   dbconn = gdb.dbconn;
+   dbxact = gdb.dbxact;
+   gdb_refcount++;
+}
 
-   db = new PgDatabase(cfg->Database());
+void gnucomo_database::operator = (const gnucomo_database &gdb)
+{
+   dbconn = gdb.dbconn;
+   dbxact = gdb.dbxact;
+   gdb_refcount++;
+}
 
-   if (db->ConnectionBad())
+   //      A destructor must Commit the transaction and
+   //      destroy the transaction before destroying the
+   //      connection.
+   //      The connection can only be destroyed by the last
+   //      object alive.
+
+gnucomo_database::~gnucomo_database()
+{
+   if (--gdb_refcount == 0 && dbconn != 0 && dbxact != 0)
    {
-      std::cerr << "Can not connect to database: " << db->ErrorMessage();
+      dbxact->commit();
+      delete dbxact;
+      dbxact = 0;
+      delete dbconn;
+      dbconn = 0;
    }
 }
 
@@ -104,7 +175,7 @@ gnucomo_database::gnucomo_database(gnucomo_config *c)
 **  VARS CHANGED   :
 **  FUNCTIONS USED :
 **  SEE ALSO       :
-**  LAST MODIFIED  : Sep 16, 2002
+**  LAST MODIFIED  : Aug 15, 2003
 **=========================================================================
 */
 
@@ -119,7 +190,7 @@ String gnucomo_database::find_host(const String hostname)
 
    if (Query(check_host) > 0)
    {
-      objectid = String(db->GetValue(0, "objectid"));
+      objectid = Field(0, "objectid");
    }
 
    return objectid;
@@ -139,7 +210,7 @@ String gnucomo_database::new_notification(String objectid, String issue, String
 
    String issueid("");
 
-   std::cout << "Creating notification for " << issue << ": " << remark << "\n";
+   *Log << "Creating notification for " << issue << ": " << remark << "\n";
 
    qry = "select type_of_issueid, suggested_priority from type_of_issue where name='";
    qry += issue + "'";
@@ -152,17 +223,13 @@ String gnucomo_database::new_notification(String objectid, String issue, String
       insertion += issueid + "', '" + now.format("%Y-%m-%d %T") + "', 'new', '";
       insertion += Field(0, "suggested_priority") + "')";
 
-      qry = "select notificationid from notification where objectid='";
-      qry += objectid + "' and type_of_issueid = '";
-      qry += issueid + "' order by notificationid";
-
       Query(insertion);
-      int tuples = Query(qry);
 
-      if (tuples > 0)
-      {
-         notif_id = Field(tuples - 1, "notificationid");
+      Query("select currval('notification_notificationid_seq')");
+      notif_id = Field(0, "currval");
 
+      if (notif_id != "")
+      {
          insertion = "insert into action_user (actionid, username, notificationid,";
          insertion += "    timestamp, statuscode, remarks) values ('1', 'gnucomo', '";
          insertion += notif_id + "', '" + now.format("%Y-%m-%d %T") + "', 'new', '";
@@ -175,6 +242,10 @@ String gnucomo_database::new_notification(String objectid, String issue, String
          std::cerr << "Error inserting notification.\n";
       }
    }
+   else
+   {
+      std::cerr << "DATABASE ERROR: Type of issue " << issue << " not found.\n";
+   }
 
    return notif_id;
 }