Subversion Repositories HomeAutomation

Rev

Rev 1947 | Go to most recent revision | Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
1945 runge 1
/*
2
 *
3
 *  Copyright (C) 2012  Mattias Runge
4
 *
5
 *  This program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation; either version 2 of the License, or
8
 *  (at your option) any later version.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License along
16
 *  with this program; if not, write to the Free Software Foundation, Inc.,
17
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
 *
19
 */
20
 
21
#include "MySql.h"
22
 
23
#include <mysql.h>
24
#include <boost/lexical_cast.hpp>
25
 
26
#include "vm/Manager.h"
27
#include "common/log.h"
28
#include "common/exception.h"
29
 
30
namespace atom {
31
namespace vm {
32
namespace plugin {
33
 
34
MySql::Resources MySql::resources_;
35
 
36
static const std::string log_module_ = "vm::plugin::mysql";
37
 
38
MySql::MySql(boost::asio::io_service& io_service) : Plugin(io_service)
39
{
40
  this->name_ = "mysql";
41
 
42
  this->ExportFunction("MySqlExport_Connect",       MySql::Export_Connect);
43
  this->ExportFunction("MySqlExport_Close",         MySql::Export_Close);
44
  this->ExportFunction("MySqlExport_Query",         MySql::Export_Query);
45
  this->ExportFunction("MySqlExport_SelectDb",      MySql::Export_SelectDb);
46
  this->ExportFunction("MySqlExport_AffectedRows",  MySql::Export_AffectedRows);
47
}
48
 
49
MySql::~MySql()
50
{
51
}
52
 
53
void MySql::InitializeDone()
54
{
55
  Plugin::InitializeDone();
56
}
57
 
58
void MySql::CallOutput(unsigned int request_id, std::string output)
59
{
60
  atom::log::Info(log_module_, output);
61
}
62
 
63
Value MySql::Export_Connect(const v8::Arguments& args)
64
{
65
  ATOM_VM_PLUGIN_SCOPE;
66
 
67
  MYSQL* resource = NULL;
68
 
69
  atom::log::Debug(log_module_, "%s called!", __FUNCTION__);
70
 
71
  try
72
  {
73
    ATOM_VM_PLUGIN_NUM_PARAMS(3);
74
 
75
    v8::String::AsciiValue server(args[0]);
76
    v8::String::AsciiValue username(args[1]);
77
    v8::String::AsciiValue password(args[2]);
78
 
79
 
80
    /* Initialize MySQL resource */
81
    resource = mysql_init(NULL);
82
 
83
    if (NULL == resource)
84
    {
85
      throw atom::exception::initialization_failed;
86
    }
87
 
88
 
89
    /* Connect to database */
90
    if (mysql_real_connect(resource, *server, *username, *password, NULL, 0, NULL, 0) == NULL)
91
    {
92
      atom::log::Error(log_module_, "Failed to connect to database %s, error code %d, error message \"%s\".", *server, mysql_errno(resource), mysql_error(resource));
93
      throw atom::exception::connect_failed;
94
    }
95
 
96
 
97
    /* Add resource to list */
98
    MySql::resources_[(uintptr_t)resource] = resource;
99
 
100
 
101
    return handle_scope.Close(v8::Uint32::New((uintptr_t)resource));
102
  }
103
  catch (std::exception& exception)
104
  {
105
    if (NULL != resource)
106
    {
107
      mysql_close(resource);
108
      resource = NULL;
109
    }
110
 
111
    atom::log::Exception(log_module_, exception);
112
 
113
    return handle_scope.Close(v8::Boolean::New(false));
114
  }
115
}
116
 
117
Value MySql::Export_Close(const v8::Arguments& args)
118
{
119
  ATOM_VM_PLUGIN_SCOPE;
120
 
121
  atom::log::Debug(log_module_, "%s called!", __FUNCTION__);
122
 
123
  try
124
  {
125
    ATOM_VM_PLUGIN_NUM_PARAMS(1);
126
 
127
 
128
    /* Check that the resource exist */
129
    if (NULL == MySql::resources_[(uintptr_t)args[0]->Uint32Value()])
130
    {
131
      throw atom::exception::missing_resource;
132
    }
133
 
134
 
135
    /* Close connection */
136
    mysql_close(MySql::resources_[(uintptr_t)args[0]->Uint32Value()]);
137
    MySql::resources_.erase((uintptr_t)args[0]->Uint32Value());
138
 
139
 
140
    return handle_scope.Close(v8::Boolean::New(true));
141
  }
142
  catch (std::exception& exception)
143
  {
144
    atom::log::Exception(log_module_, exception);
145
 
146
    return handle_scope.Close(v8::Boolean::New(false));
147
  }
148
}
149
 
150
Value MySql::Export_Query(const v8::Arguments& args)
151
{
152
  ATOM_VM_PLUGIN_SCOPE;
153
 
154
  MYSQL_RES* result = NULL;
155
 
156
  atom::log::Debug(log_module_, "%s called!", __FUNCTION__);
157
 
158
  try
159
  {
160
    ArgumentListPointer result_array = ArgumentListPointer(new ArgumentList);
161
 
162
    ATOM_VM_PLUGIN_NUM_PARAMS(2);
163
 
164
    v8::String::AsciiValue query(args[1]);
165
 
166
 
167
    /* Check that the resource exist */
168
    if (NULL == MySql::resources_[(uintptr_t)args[0]->Uint32Value()])
169
    {
170
      throw atom::exception::missing_resource;
171
    }
172
 
173
 
174
    /* Execute the query */
175
    if (0 != mysql_query(MySql::resources_[(uintptr_t)args[0]->Uint32Value()], *query))
176
    {
177
      throw atom::exception::action_failed;
178
    }
179
 
180
 
181
    /* Get the result */
182
    result = mysql_store_result(MySql::resources_[(uintptr_t)args[0]->Uint32Value()]);
183
 
184
    if (NULL == result)
185
    {
186
      if (mysql_field_count(MySql::resources_[(uintptr_t)args[0]->Uint32Value()]) > 0)
187
      {
188
        throw atom::exception::action_failed;
189
      }
190
    }
191
    else
192
    {
193
 
194
      MYSQL_ROW           row;
195
      uint32_t            number_of_fields = mysql_num_fields(result);
196
      MYSQL_FIELD*        fields = mysql_fetch_fields(result);
197
      uint32_t            row_index = 0;
198
 
199
      v8::Local<v8::Array> result_array = v8::Array::New();
200
 
201
 
202
      while (NULL != (row = mysql_fetch_row(result)))
203
      {
204
        v8::Local<v8::Object> vars = v8::Object::New();
205
 
206
 
207
        for (uint32_t index = 0; index < number_of_fields; index++)
208
        {
209
          vars->Set(v8::String::New(fields[index].name), v8::String::New(row[index]));
210
 
211
//          atom::log::Info(log_module_, "%s = %s\n", fields[index].name, row[index]);
212
        }
213
 
214
        result_array->Set(row_index, vars);
215
        row_index++;
216
      }
217
 
218
      mysql_free_result(result);
219
      result = NULL;
220
 
221
      return handle_scope.Close(v8::Handle<v8::Value>(result_array));
222
    }
223
 
224
    return handle_scope.Close(v8::Boolean::New(true));
225
  }
226
  catch (std::exception& exception)
227
  {
228
    if (NULL != result)
229
    {
230
      mysql_free_result(result);
231
      result = NULL;
232
    }
233
 
234
    atom::log::Exception(log_module_, exception);
235
 
236
    return handle_scope.Close(v8::Boolean::New(false));
237
  }
238
}
239
 
240
Value MySql::Export_SelectDb(const v8::Arguments& args)
241
{
242
  ATOM_VM_PLUGIN_SCOPE;
243
 
244
  atom::log::Debug(log_module_, "%s called!", __FUNCTION__);
245
 
246
  try
247
  {
248
    ATOM_VM_PLUGIN_NUM_PARAMS(2);
249
 
250
    v8::String::AsciiValue database(args[1]);
251
 
252
 
253
    /* Check that the resource exist */
254
    if (NULL == MySql::resources_[(uintptr_t)args[0]->Uint32Value()])
255
    {
256
      throw atom::exception::missing_resource;
257
    }
258
 
259
 
260
    /* Select database */
261
    if (0 != mysql_select_db(MySql::resources_[(uintptr_t)args[0]->Uint32Value()], *database))
262
    {
263
       throw atom::exception::action_failed;
264
    }
265
 
266
 
267
    return handle_scope.Close(v8::Boolean::New(true));
268
  }
269
  catch (std::exception& exception)
270
  {
271
    atom::log::Exception(log_module_, exception);
272
 
273
    return handle_scope.Close(v8::Boolean::New(false));
274
  }
275
}
276
 
277
Value MySql::Export_AffectedRows(const v8::Arguments& args)
278
{
279
  ATOM_VM_PLUGIN_SCOPE;
280
 
281
  atom::log::Debug(log_module_, "%s called!", __FUNCTION__);
282
 
283
  try
284
  {
285
    ATOM_VM_PLUGIN_NUM_PARAMS(1);
286
 
287
 
288
    /* Check that the resource exist */
289
    if (NULL == MySql::resources_[(uintptr_t)args[0]->Uint32Value()])
290
    {
291
      throw atom::exception::missing_resource;
292
    }
293
 
294
 
295
    /* Select database */
296
    uint32_t number_of_rows = mysql_affected_rows(MySql::resources_[(uintptr_t)args[0]->Uint32Value()]);
297
 
298
 
299
    return handle_scope.Close(v8::Uint32::New(number_of_rows));
300
  }
301
  catch (std::exception& exception)
302
  {
303
    atom::log::Exception(log_module_, exception);
304
 
305
    return handle_scope.Close(v8::Boolean::New(false));
306
  }
307
}
308
 
309
 
310
}; // namespace plugin
311
}; // namespace vm
312
}; // namespace atom