Statistics
| Branch: | Tag: | Revision:

one / src / sql / MySqlDB.cc @ b7febc83

History | View | Annotate | Download (5.38 KB)

1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)             */
3
/*                                                                            */
4
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
5
/* not use this file except in compliance with the License. You may obtain    */
6
/* a copy of the License at                                                   */
7
/*                                                                            */
8
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
9
/*                                                                            */
10
/* Unless required by applicable law or agreed to in writing, software        */
11
/* distributed under the License is distributed on an "AS IS" BASIS,          */
12
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
13
/* See the License for the specific language governing permissions and        */
14
/* limitations under the License.                                             */
15
/* -------------------------------------------------------------------------- */
16

    
17
#include "MySqlDB.h"
18
#include <mysql/errmsg.h>
19

    
20
/*********
21
 * Doc: http://dev.mysql.com/doc/refman/5.5/en/c-api-function-overview.html
22
 ********/
23

    
24
/* -------------------------------------------------------------------------- */
25

    
26
MySqlDB::MySqlDB(
27
        const string& _server,
28
        int           _port,
29
        const string& _user,
30
        const string& _password,
31
        const string& _database)
32
{
33
    server   = _server;
34
    port     = _port;
35
    user     = _user;
36
    password = _password;
37
    database = _database;
38

    
39
    // Initialize the MySQL library
40
    mysql_library_init(0, NULL, NULL);
41

    
42
    // Initialize a connection handler
43
    db = mysql_init(NULL);
44

    
45
    // Connect to the server
46
    if (!mysql_real_connect(db, server.c_str(), user.c_str(),
47
                            password.c_str(), 0, port, NULL, 0))
48
    {
49
        throw runtime_error("Could not open database.");
50
    }
51

    
52
    pthread_mutex_init(&mutex,0);
53
}
54

    
55
/* -------------------------------------------------------------------------- */
56

    
57
MySqlDB::~MySqlDB()
58
{
59
    // Close the connection to the MySQL server
60
    mysql_close(db);
61

    
62
    // End use of the MySQL library
63
    mysql_library_end();
64

    
65
    pthread_mutex_destroy(&mutex);
66
}
67

    
68
/* -------------------------------------------------------------------------- */
69

    
70
int MySqlDB::exec(ostringstream& cmd, Callbackable* obj)
71
{
72
    int          rc;
73

    
74
    const char * c_str;
75
    string       str;
76

    
77
    str   = cmd.str();
78
    c_str = str.c_str();
79

    
80
    lock();
81

    
82
    rc = mysql_query(db, c_str);
83

    
84
    if (rc != 0)
85
    {
86
        ostringstream   oss;
87
        const char *    err_msg = mysql_error(db);
88
        int             err_num = mysql_errno(db);
89

    
90
        if( err_num == CR_SERVER_GONE_ERROR || err_num == CR_SERVER_LOST )
91
        {
92
            oss << "MySQL connection error " << err_num << " : " << err_msg;
93

    
94
            // Try to re-connect
95
            if (mysql_real_connect(db, server.c_str(), user.c_str(),
96
                                    password.c_str(), database.c_str(),
97
                                    port, NULL, 0))
98
            {
99
                oss << "... Reconnected.";
100
            }
101
            else
102
            {
103
                oss << "... Reconnection attempt failed.";
104
            }
105
        }
106
        else
107
        {
108
            oss << "SQL command was: " << c_str;
109
            oss << ", error " << err_num << " : " << err_msg;
110
        }
111

    
112
        NebulaLog::log("ONE",Log::ERROR,oss);
113

    
114
        unlock();
115

    
116
        return -1;
117
    }
118

    
119

    
120
    if ( (obj != 0) && (obj->isCallBackSet()) )
121
    {
122

    
123
        MYSQL_RES *         result;
124
        MYSQL_ROW           row;
125
        MYSQL_FIELD *       fields;
126
        unsigned int        num_fields;
127

    
128
        // Retrieve the entire result set all at once
129
        result = mysql_store_result(db);
130

    
131
        if (result == NULL)
132
        {
133
            ostringstream   oss;
134
            const char *    err_msg = mysql_error(db);
135
            int             err_num = mysql_errno(db);
136

    
137
            oss << "SQL command was: " << c_str;
138
            oss << ", error " << err_num << " : " << err_msg;
139

    
140
            NebulaLog::log("ONE",Log::ERROR,oss);
141

    
142
            unlock();
143

    
144
            return -1;
145
        }
146

    
147
        // Fetch the names of the fields
148
        num_fields  = mysql_num_fields(result);
149
        fields      = mysql_fetch_fields(result);
150

    
151
        char ** names = new char*[num_fields];
152

    
153
        for(unsigned int i = 0; i < num_fields; i++)
154
        {
155
            names[i] = fields[i].name;
156
        }
157

    
158
        // Fetch each row, and call-back the object waiting for them
159
        while((row = mysql_fetch_row(result)))
160
        {
161
            obj->do_callback(num_fields, row, names);
162
        }
163

    
164
        // Free the result object
165
        mysql_free_result(result);
166

    
167
        delete[] names;
168
    }
169

    
170
    unlock();
171

    
172
    return 0;
173
}
174

    
175
/* -------------------------------------------------------------------------- */
176

    
177
char * MySqlDB::escape_str(const string& str)
178
{
179
    char * result = new char[str.size()*2+1];
180

    
181
    mysql_real_escape_string(db, result, str.c_str(), str.size());
182

    
183
    return result;
184
}
185

    
186
/* -------------------------------------------------------------------------- */
187

    
188
void MySqlDB::free_str(char * str)
189
{
190
    delete[] str;
191
}
192

    
193
/* -------------------------------------------------------------------------- */