fb497eca437273747352c1aa3d5eee3f5ddcf838
[gnucomo.git] / src / lib / database.cpp
1
2 /**************************************************************************
3 **  (c) Copyright 2002, Andromeda Technology & Automation
4 ** This is free software; you can redistribute it and/or modify it under the
5 ** terms of the GNU General Public License, see the file COPYING.
6 ***************************************************************************
7 ** MODULE INFORMATION *
8 ***********************
9 **      FILE NAME      : database.cpp
10 **      SYSTEM NAME    : Gnucomo - Gnu Computer Monitoring
11 **      VERSION NUMBER : $Revision: 1.12 $
12 **
13 **  DESCRIPTION      :  Implementation of the gnucomo database classes
14 **
15 **  EXPORTED OBJECTS : 
16 **  LOCAL    OBJECTS : 
17 **  MODULES  USED    :
18 ***************************************************************************
19 **  ADMINISTRATIVE INFORMATION *
20 ********************************
21 **      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
22 **      CREATION DATE   : Sep 10, 2002
23 **      LAST UPDATE     : Aug 17, 2003
24 **      MODIFICATIONS   : 
25 **************************************************************************/
26
27 /*****************************
28    $Log: database.cpp,v $
29    Revision 1.12  2003-12-22 10:28:26  arjen
30    Catch an exception if we can not setup a database transaction.
31
32    Revision 1.11  2003/12/04 10:40:28  arjen
33    Fixed name conflict with 'double log(double)'
34
35    Revision 1.10  2003/12/03 08:23:17  arjen
36    Write messages to the log stream instead of cout.
37
38    Revision 1.9  2003/08/17 11:39:56  arjen
39    Changed the gnucomo_database class to the new PostgreSQL
40    library, libpqxx
41
42    Revision 1.8  2003/07/31 15:44:02  arjen
43    Removed debug output.
44
45    Revision 1.7  2003/02/19 12:07:55  arjen
46    Use the SQL function currval() to obtain the identification number
47    of the most recently created notification.
48
49    Revision 1.6  2003/02/05 09:33:42  arjen
50    gnucomo_database::new_notification() retruns the id number of the
51    newly created notification record.
52
53    Revision 1.5  2003/01/20 07:31:42  arjen
54    Removed some debug output.
55
56    Revision 1.4  2003/01/18 08:52:32  arjen
57    New C++ function: gnucomo_database::new_notification()
58
59    Revision 1.3  2002/11/09 08:04:27  arjen
60    Added a reference to the GPL
61
62    Revision 1.2  2002/11/04 10:13:36  arjen
63    Use proper namespace for iostream classes
64
65    Revision 1.1  2002/10/05 10:25:49  arjen
66    Creation of gcm_input and a first approach to a web interface
67
68 *****************************/
69
70 static const char *RCSID = "$Id: database.cpp,v 1.12 2003-12-22 10:28:26 arjen Exp $";
71
72 #include <AXE/date.h>
73
74 #include "database.h"
75
76 extern std::ostream *Log;
77
78 /*=========================================================================
79 **  NAME           : gnucomo_database
80 **  SYNOPSIS       : gnucomo_database(gnucomo_config &c);
81 **  PARAMETERS     : 
82 **  RETURN VALUE   : Database constructor. Establishes a connection with
83 **                   the database server.
84 **
85 **  DESCRIPTION    : 
86 **
87 **  VARS USED      :
88 **  VARS CHANGED   :
89 **  FUNCTIONS USED :
90 **  SEE ALSO       :
91 **  LAST MODIFIED  : Aug 17, 2003
92 **=========================================================================
93 */
94
95 static int gdb_refcount = 0;
96
97 gnucomo_database::gnucomo_database(gnucomo_config *c)
98 {
99    cfg = c;
100
101    dbconn = new pqxx::Connection(cfg->Database());
102
103    if (!dbconn->is_open())
104    {
105       std::cerr << "Connection to database failed.\n";
106    }
107    else
108    {
109       try
110       {
111          // Create the transaction object
112
113          dbxact = new pqxx::Transaction(*dbconn, "GnuCoMo");
114       }
115       catch (std::exception &e)
116       {
117          *Log << "Cannot setup the database transaction: " << e.what() << "\n";
118          *Log << "You are probably using incompatible versions of PostgreSQL an libpqxx.\n";
119          exit(1);
120       }
121       gdb_refcount++;
122    }
123 }
124
125 gnucomo_database::gnucomo_database(const gnucomo_database &gdb)
126 {
127    dbconn = gdb.dbconn;
128    dbxact = gdb.dbxact;
129    gdb_refcount++;
130 }
131
132 void gnucomo_database::operator = (const gnucomo_database &gdb)
133 {
134    dbconn = gdb.dbconn;
135    dbxact = gdb.dbxact;
136    gdb_refcount++;
137 }
138
139    //      A destructor must Commit the transaction and
140    //      destroy the transaction before destroying the
141    //      connection.
142    //      The connection can only be destroyed by the last
143    //      object alive.
144
145 gnucomo_database::~gnucomo_database()
146 {
147    if (--gdb_refcount == 0 && dbconn != 0 && dbxact != 0)
148    {
149       dbxact->Commit();
150       delete dbxact;
151       dbxact = 0;
152       delete dbconn;
153       dbconn = 0;
154    }
155 }
156
157 /*=========================================================================
158 **  NAME           : find_host
159 **  SYNOPSIS       : String gnucomo_database::find_host(String hostname);
160 **  PARAMETERS     : 
161 **  RETURN VALUE   : Find a hostname in the 'object' table of the gnucomo database
162 **                   and return its object id.
163 **                   Return an empty string as objectid if the hostname is
164 **                   not found.
165 **
166 **  DESCRIPTION    : 
167 **
168 **  VARS USED      :
169 **  VARS CHANGED   :
170 **  FUNCTIONS USED :
171 **  SEE ALSO       :
172 **  LAST MODIFIED  : Aug 15, 2003
173 **=========================================================================
174 */
175
176 String gnucomo_database::find_host(const String hostname)
177 {
178    String objectid("");
179    String check_host("select objectid from object where ");
180
181    check_host += "objectname = '";
182    check_host += hostname;
183    check_host += "'";
184
185    if (Query(check_host) > 0)
186    {
187       objectid = Field(0, "objectid");
188    }
189
190    return objectid;
191 }
192
193 /*
194  *  Create a new notification with an action_user and return the notification id
195  */
196
197 String gnucomo_database::new_notification(String objectid, String issue, String remark)
198 {
199    String qry;
200    UTC    now = Now();
201
202    String insertion;
203    String notif_id("");
204
205    String issueid("");
206
207    *Log << "Creating notification for " << issue << ": " << remark << "\n";
208
209    qry = "select type_of_issueid, suggested_priority from type_of_issue where name='";
210    qry += issue + "'";
211    if (Query(qry) == 1)
212    {
213       issueid = Field(0, "type_of_issueid");
214       insertion = "insert into notification (objectid, type_of_issueid, timestamp, ";
215       insertion += "   statuscode, priority) values ('";
216       insertion += objectid + "', '";
217       insertion += issueid + "', '" + now.format("%Y-%m-%d %T") + "', 'new', '";
218       insertion += Field(0, "suggested_priority") + "')";
219
220       Query(insertion);
221
222       Query("select currval('notification_notificationid_seq')");
223       notif_id = Field(0, "currval");
224
225       if (notif_id != "")
226       {
227          insertion = "insert into action_user (actionid, username, notificationid,";
228          insertion += "    timestamp, statuscode, remarks) values ('1', 'gnucomo', '";
229          insertion += notif_id + "', '" + now.format("%Y-%m-%d %T") + "', 'new', '";
230          insertion += remark + "')";
231
232          Query(insertion);
233       }
234       else
235       {
236          std::cerr << "Error inserting notification.\n";
237       }
238    }
239    else
240    {
241       std::cerr << "DATABASE ERROR: Type of issue " << issue << " not found.\n";
242    }
243
244    return notif_id;
245 }
246