PageRenderTime 24ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/flash/video/gnash-bzr/src/gnash-build/extensions/mysql/mysql_db.cpp

https://github.com/o1iver/Code-Backup
C++ | 426 lines | 319 code | 60 blank | 47 comment | 22 complexity | 1f6eaa35936b51b3e4383d5e362a80ae MD5 | raw file
  1. // mysql_db.cpp: MySQL database interface ActionScript objects, for Gnash.
  2. //
  3. // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
  4. // Foundation, Inc
  5. //
  6. // This program is free software; you can redistribute it and/or modify
  7. // it under the terms of the GNU General Public License as published by
  8. // the Free Software Foundation; either version 3 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // This program is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU General Public License
  17. // along with this program; if not, write to the Free Software
  18. // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  19. #ifdef HAVE_CONFIG_H
  20. #include "gnashconfig.h"
  21. #endif
  22. #include "namedStrings.h"
  23. #include <cstdarg>
  24. #include <mysql/errmsg.h>
  25. #include <mysql/mysql.h>
  26. #include <iostream>
  27. #include <vector>
  28. #include "log.h"
  29. #include "Array_as.h"
  30. #include "as_value.h"
  31. #include "fn_call.h"
  32. #include "mysql_db.h"
  33. #include "Globals.h"
  34. #include "builtin_function.h" // need builtin_function
  35. using namespace std;
  36. namespace gnash
  37. {
  38. as_value mysql_connect(const fn_call& fn);
  39. as_value mysql_qetData(const fn_call& fn);
  40. as_value mysql_disconnect(const fn_call& fn);
  41. as_value mysql_query(const fn_call& fn);
  42. as_value mysql_row(const fn_call& fn);
  43. as_value mysql_fields(const fn_call& fn);
  44. as_value mysql_fetch(const fn_call& fn);
  45. as_value mysql_store(const fn_call& fn);
  46. as_value mysql_free(const fn_call& fn);
  47. LogFile& dbglogfile = LogFile::getDefaultInstance();
  48. static void
  49. attachInterface(as_object& obj)
  50. {
  51. Global_as& gl = getGlobal(obj);
  52. obj.init_member("connect", gl.createFunction(mysql_connect));
  53. obj.init_member("qetData", gl.createFunction(mysql_qetData));
  54. obj.init_member("disconnect", gl.createFunction(mysql_disconnect));
  55. obj.init_member("query", gl.createFunction(mysql_query));
  56. obj.init_member("fetch_row", gl.createFunction(mysql_fetch));
  57. obj.init_member("num_fields", gl.createFunction(mysql_fields));
  58. obj.init_member("free_result", gl.createFunction(mysql_free));
  59. obj.init_member("store_results", gl.createFunction(mysql_store));
  60. }
  61. class MySQL : public Relay
  62. {
  63. public:
  64. typedef std::vector< std::vector<const char *> > query_t;
  65. MySQL();
  66. ~MySQL();
  67. bool connect(const char *host, const char *dbname, const char *user, const char *passwd);
  68. int getData(const char *sql, query_t &result);
  69. bool disconnect();
  70. // These are wrappers for the regular MySQL API
  71. bool guery(MYSQL *db, const char *sql);
  72. bool guery(const char *sql);
  73. int num_fields();
  74. int num_fields(MYSQL_RES *result);
  75. MYSQL_ROW fetch_row();
  76. MYSQL_ROW fetch_row(MYSQL_RES *result);
  77. void free_result();
  78. void free_result(MYSQL_RES *result);
  79. MYSQL_RES *store_result();
  80. MYSQL_RES *store_result(MYSQL *db);
  81. private:
  82. MYSQL *_db;
  83. MYSQL_RES *_result;
  84. MYSQL_ROW _row;
  85. };
  86. static as_value
  87. mysql_ctor(const fn_call& fn)
  88. {
  89. as_object* obj = ensure<ValidThis>(fn);
  90. obj->setRelay(new MySQL());
  91. return as_value();
  92. }
  93. MySQL::MySQL() :
  94. _db(NULL),
  95. _result(NULL),
  96. _row(NULL)
  97. {
  98. }
  99. MySQL::~MySQL()
  100. {
  101. disconnect();
  102. }
  103. int
  104. MySQL::num_fields()
  105. {
  106. if (_result) {
  107. return num_fields(_result);
  108. }
  109. return -1;
  110. }
  111. int
  112. MySQL::num_fields(MYSQL_RES *result)
  113. {
  114. return mysql_num_fields(result);
  115. }
  116. MYSQL_ROW
  117. MySQL::fetch_row()
  118. {
  119. if (_result) {
  120. return fetch_row(_result);
  121. }
  122. return NULL;
  123. }
  124. MYSQL_ROW
  125. MySQL::fetch_row(MYSQL_RES *result)
  126. {
  127. return mysql_fetch_row(result);
  128. }
  129. void
  130. MySQL::free_result()
  131. {
  132. if (_result) {
  133. free_result(_result);
  134. }
  135. }
  136. void
  137. MySQL::free_result(MYSQL_RES *result)
  138. {
  139. mysql_free_result(result);
  140. }
  141. MYSQL_RES *
  142. MySQL::store_result()
  143. {
  144. if (_db) {
  145. return store_result(_db);
  146. }
  147. return NULL;
  148. }
  149. MYSQL_RES *
  150. MySQL::store_result(MYSQL *db)
  151. {
  152. _result = mysql_store_result(db);
  153. return _result;
  154. }
  155. bool
  156. MySQL::connect(const char* host, const char* dbname, const char* user, const char* passwd)
  157. {
  158. // GNASH_REPORT_FUNCTION;
  159. // Closes a previously opened connection &
  160. // also deallocates the connection handle
  161. disconnect();
  162. if ((_db = mysql_init(NULL)) == NULL ) {
  163. log_error(_("Couldn't initialize database"));
  164. return false;
  165. }
  166. if (mysql_real_connect(_db, host, user, passwd, dbname, 0, NULL, 0) == NULL) {
  167. log_error(_("Couldn't connect to database"));
  168. return false;
  169. }
  170. return true;
  171. }
  172. bool
  173. MySQL::guery(const char *sql)
  174. {
  175. // GNASH_REPORT_FUNCTION;
  176. if (_db) {
  177. return guery(_db, sql);
  178. }
  179. return -1;
  180. }
  181. bool
  182. MySQL::guery(MYSQL *db, const char *sql)
  183. {
  184. // GNASH_REPORT_FUNCTION;
  185. int res = mysql_real_query(db, sql, strlen(sql));
  186. switch (res) {
  187. case CR_SERVER_LOST:
  188. case CR_COMMANDS_OUT_OF_SYNC:
  189. case CR_SERVER_GONE_ERROR:
  190. log_error (_("MySQL connection error: %s"), mysql_error(_db));
  191. // Try to reconnect to the database
  192. // closeDB();
  193. // openDB();
  194. break;
  195. case -1:
  196. case CR_UNKNOWN_ERROR:
  197. log_error (_("MySQL error on query for:\n\t%s\nQuery was: %s"),
  198. mysql_error(_db), sql);
  199. return false;
  200. break;
  201. default:
  202. return true;
  203. }
  204. return false;
  205. }
  206. int
  207. MySQL::getData(const char *sql, query_t &qresult)
  208. {
  209. // GNASH_REPORT_FUNCTION;
  210. bool qstatus = false;
  211. int res = mysql_real_query(_db, sql, strlen(sql));
  212. switch (res) {
  213. case CR_SERVER_LOST:
  214. case CR_COMMANDS_OUT_OF_SYNC:
  215. case CR_SERVER_GONE_ERROR:
  216. log_error(_("MySQL connection error: %s"), mysql_error(_db));
  217. // Try to reconnect to the database
  218. // closeDB();
  219. // openDB();
  220. break;
  221. case -1:
  222. case CR_UNKNOWN_ERROR:
  223. log_error (_("MySQL error on query for:\n\t%s\nQuery was: %s"),
  224. mysql_error(_db), sql);
  225. // return false;
  226. break;
  227. // default:
  228. // return true;
  229. }
  230. _result = mysql_store_result(_db);
  231. // int nrows = mysql_num_rows(result);
  232. #if 0
  233. for (size_t i=0; i<mysql_num_fields(_result); i++) {
  234. MYSQL_FIELD *fields = mysql_fetch_fields(_result);
  235. log_debug(_("Field name is: %s: "), fields->name);
  236. }
  237. #endif
  238. while((_row = mysql_fetch_row(_result))) {
  239. vector<const char *> row_vec;
  240. for (size_t i=0; i<mysql_num_fields(_result); i++) {
  241. // log_debug("Column[%d] is: \"%s\"", i, row[i]);
  242. row_vec.push_back(_row[i]);
  243. }
  244. qresult.push_back(row_vec);
  245. qstatus = true;
  246. }
  247. mysql_free_result(_result);
  248. return(qstatus);
  249. }
  250. bool
  251. MySQL::disconnect()
  252. {
  253. // GNASH_REPORT_FUNCTION;
  254. if (_db != NULL) {
  255. mysql_close(_db);
  256. _db = NULL;
  257. }
  258. return true;
  259. }
  260. // Entry points for ActionScript methods
  261. as_value
  262. mysql_connect(const fn_call& fn)
  263. {
  264. MySQL* ptr = ensure<ThisIsNative<MySQL> >(fn);
  265. if (fn.nargs == 4) {
  266. string host = fn.arg(0).to_string();
  267. string db = fn.arg(1).to_string();
  268. string user = fn.arg(2).to_string();
  269. string passwd = fn.arg(3).to_string();
  270. return as_value(ptr->connect(host.c_str(), db.c_str(),
  271. user.c_str(), passwd.c_str()));
  272. }
  273. return as_value(false);
  274. }
  275. as_value
  276. mysql_qetData(const fn_call& fn)
  277. {
  278. // GNASH_REPORT_FUNCTION;
  279. if (fn.nargs > 0) {
  280. string sql = fn.arg(0).to_string();
  281. as_object* arr = fn.arg(1).to_object(getGlobal(fn));
  282. MySQL::query_t qresult;
  283. for (size_t i=0; i<qresult.size(); i++) {
  284. vector<const char *> row;
  285. row = qresult[i];
  286. for (size_t j=0; j< row.size(); j++) {
  287. as_value entry = row[j];
  288. callMethod(arr, NSV::PROP_PUSH, entry);
  289. }
  290. }
  291. return as_value(true);
  292. }
  293. log_aserror("Mysql.getData(): missing arguments");
  294. return as_value(false);
  295. }
  296. as_value
  297. mysql_free(const fn_call& fn)
  298. {
  299. // GNASH_REPORT_FUNCTION;
  300. MySQL* ptr = ensure<ThisIsNative<MySQL> >(fn);
  301. ptr->free_result();
  302. return as_value(true);
  303. }
  304. as_value
  305. mysql_fields(const fn_call& fn)
  306. {
  307. // GNASH_REPORT_FUNCTION;
  308. MySQL* ptr = ensure<ThisIsNative<MySQL> >(fn);
  309. return as_value(ptr->num_fields());
  310. }
  311. as_value
  312. mysql_fetch(const fn_call& fn)
  313. {
  314. MySQL* ptr = ensure<ThisIsNative<MySQL> >(fn);
  315. if (fn.nargs > 0) {
  316. MYSQL_ROW res = ptr->fetch_row();
  317. as_value aaa = *res;
  318. Global_as& gl = getGlobal(fn);
  319. as_object* arr = gl.createArray();
  320. callMethod(arr, NSV::PROP_PUSH, aaa);
  321. return as_value(arr);
  322. }
  323. log_aserror("Mysql.fetch(): missing arguments");
  324. return as_value();
  325. }
  326. as_value
  327. mysql_store(const fn_call& fn)
  328. {
  329. // GNASH_REPORT_FUNCTION;
  330. MySQL* ptr = ensure<ThisIsNative<MySQL> >(fn);
  331. as_object* obj = reinterpret_cast<as_object*>(ptr->store_result());
  332. return as_value(obj);
  333. }
  334. as_value
  335. mysql_query(const fn_call& fn)
  336. {
  337. // GNASH_REPORT_FUNCTION;
  338. MySQL* ptr = ensure<ThisIsNative<MySQL> >(fn);
  339. if (fn.nargs > 0) {
  340. string sql = fn.arg(0).to_string();
  341. return as_value(ptr->guery(sql.c_str()));
  342. }
  343. log_aserror("Missing arguments to MySQL.query");
  344. return as_value();
  345. }
  346. as_value
  347. mysql_disconnect(const fn_call& fn)
  348. {
  349. MySQL* ptr = ensure<ThisIsNative<MySQL> >(fn);
  350. return as_value(ptr->disconnect());
  351. }
  352. extern "C" {
  353. void mysql_class_init(as_object &obj)
  354. {
  355. Global_as& gl = getGlobal(obj);
  356. as_object* proto = gl.createObject();
  357. as_object *cl = gl.createClass(&mysql_ctor, proto);
  358. attachInterface(*proto);
  359. obj.init_member("MySQL", cl);
  360. }
  361. }
  362. } // end of gnash namespace
  363. // Local Variables:
  364. // mode: C++
  365. // indent-tabs-mode: t
  366. // End: