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