PageRenderTime 29ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/server/src/mozilla/aptana_iws/database/jxMySQL50/jxMySQL50.cpp

https://github.com/absynce/Jaxer
C++ | 1366 lines | 926 code | 265 blank | 175 comment | 140 complexity | 28a5a7648abb57af74e86581198397ae MD5 | raw file
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2. * vim: set sw=4 ts=4 et: */
  3. /* ***** BEGIN LICENSE BLOCK *****
  4. * Version: GPL 3
  5. *
  6. * This program is Copyright (C) 2007-2008 Aptana, Inc. All Rights Reserved
  7. * This program is licensed under the GNU General Public license, version 3 (GPL).
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
  12. * NONINFRINGEMENT. Redistribution, except as permitted by the GPL,
  13. * is prohibited.
  14. *
  15. * You can redistribute and/or modify this program under the terms of the GPL,
  16. * as published by the Free Software Foundation. You should
  17. * have received a copy of the GNU General Public License, Version 3 along
  18. * with this program; if not, write to the Free Software Foundation, Inc., 51
  19. * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20. *
  21. * Aptana provides a special exception to allow redistribution of this file
  22. * with certain other code and certain additional terms
  23. * pursuant to Section 7 of the GPL. You may view the exception and these
  24. * terms on the web at http://www.aptana.com/legal/gpl/.
  25. *
  26. * You may view the GPL, and Aptana's exception and additional terms in the file
  27. * titled license-jaxer.html in the main distribution folder of this program.
  28. *
  29. * Any modifications to this file must keep this entire header intact.
  30. *
  31. * ***** END LICENSE BLOCK ***** */
  32. #if defined(_WIN32) || defined(_WIN64)
  33. #include <winsock2.h>
  34. #endif
  35. extern "C" {
  36. #include "my_global.h"
  37. #include "mysql.h"
  38. #include "errmsg.h"
  39. }
  40. #include "nsCOMPtr.h"
  41. #include "nsIClassInfoImpl.h"
  42. #include "nsString.h"
  43. #include "nsPrintfCString.h"
  44. #include "jxMySQL50.h"
  45. #include "jxMySQL50ResultSet.h"
  46. #include "jxMySQL50Statement.h"
  47. #include "jxMySQL50Defs.h"
  48. #include "aptICoreLog.h"
  49. ////////////////////////////////////////////////////////////////////////
  50. jxMySQL50::jxMySQL50()
  51. {
  52. mConnection = mysql_init((MYSQL *) nsnull);
  53. mConnected = PR_FALSE;
  54. mHost = nsnull;
  55. mUser = nsnull;
  56. mPassword = nsnull;
  57. mDatabase = nsnull;
  58. mPort = 0;
  59. mSocket = nsnull;
  60. mOptions = 0;
  61. mErrno = NS_OK;
  62. mMySQLError[0] = 0;
  63. mMySQLErrno = 0;
  64. }
  65. jxMySQL50::~jxMySQL50()
  66. {
  67. // Release any held resources so we don't leak memory
  68. if (mConnection != nsnull) { mysql_close(mConnection); }
  69. if (mHost != nsnull) { nsMemory::Free(mHost); }
  70. if (mUser != nsnull) { nsMemory::Free(mUser); }
  71. if (mPassword != nsnull) { nsMemory::Free(mPassword); }
  72. if (mDatabase != nsnull) { nsMemory::Free(mDatabase); }
  73. if (mSocket != nsnull) { nsMemory::Free(mSocket); }
  74. }
  75. // NS_IMPL_ISUPPORTS2_CI(jxMySQL50, jxIMySQL50, jxIXPCBridge)
  76. NS_IMPL_ISUPPORTS1_CI(jxMySQL50, jxIMySQL50)
  77. // NS_IMPL_ISUPPORTS1(jxMySQL50, jxIMySQL50)
  78. /* [noscript] readonly attribute jxMYSQLPtr mysql; */
  79. NS_IMETHODIMP jxMySQL50::GetMysql(MYSQL * *aMysql)
  80. {
  81. if (! aMysql )
  82. {
  83. mErrno = JX_MYSQL50_ERROR_NULL_POINTER;
  84. return mErrno;
  85. }
  86. *aMysql = mConnection;
  87. return NS_OK;
  88. }
  89. /* attribute AString host; */
  90. NS_IMETHODIMP jxMySQL50::GetHost(nsAString & aHost)
  91. {
  92. aHost.Assign(NS_ConvertUTF8toUTF16(mHost));
  93. return NS_OK;
  94. }
  95. NS_IMETHODIMP jxMySQL50::SetHost(const nsAString & aHost)
  96. {
  97. // process the host arg
  98. if (aHost.Length() == 0)
  99. {
  100. if (mHost != nsnull) { nsMemory::Free(mHost); }
  101. mHost = nsnull;
  102. }
  103. else {
  104. mHost = ToNewUTF8String(aHost);
  105. }
  106. return NS_OK;
  107. }
  108. /* attribute AString user; */
  109. NS_IMETHODIMP jxMySQL50::GetUser(nsAString & aUser)
  110. {
  111. aUser.Assign(NS_ConvertUTF8toUTF16(mUser));
  112. return NS_OK;
  113. }
  114. NS_IMETHODIMP jxMySQL50::SetUser(const nsAString & aUser)
  115. {
  116. // process the user arg
  117. if (aUser.Length() == 0)
  118. {
  119. if (mUser != nsnull) { nsMemory::Free(mUser); }
  120. mUser = nsnull;
  121. }
  122. else {
  123. mUser = ToNewUTF8String(aUser);
  124. }
  125. return NS_OK;
  126. }
  127. /* attribute AString password; */
  128. NS_IMETHODIMP jxMySQL50::GetPassword(nsAString & aPassword)
  129. {
  130. aPassword.Assign(NS_ConvertUTF8toUTF16(mPassword));
  131. return NS_OK;
  132. }
  133. NS_IMETHODIMP jxMySQL50::SetPassword(const nsAString & aPassword)
  134. {
  135. // process the Password arg
  136. if (aPassword.Length() == 0)
  137. {
  138. if (mPassword != nsnull) { nsMemory::Free(mPassword); }
  139. mPassword = nsnull;
  140. }
  141. else {
  142. mPassword = ToNewUTF8String(aPassword);
  143. }
  144. return NS_OK;
  145. }
  146. /* attribute AString database; */
  147. NS_IMETHODIMP jxMySQL50::GetDatabase(nsAString & aDatabase)
  148. {
  149. aDatabase.Assign(NS_ConvertUTF8toUTF16(mDatabase));
  150. return NS_OK;
  151. }
  152. NS_IMETHODIMP jxMySQL50::SetDatabase(const nsAString & aDatabase)
  153. {
  154. // process the Database arg
  155. if (aDatabase.Length() == 0)
  156. {
  157. if (mDatabase != nsnull) { nsMemory::Free(mDatabase); }
  158. mDatabase = nsnull;
  159. }
  160. else {
  161. mDatabase = ToNewUTF8String(aDatabase);
  162. }
  163. if (mysql_select_db(mConnection, mDatabase))
  164. {
  165. mErrno = JX_MYSQL50_MYSQL_ERROR;
  166. return mErrno;
  167. }
  168. return NS_OK;
  169. }
  170. /* attribute unsigned long port; */
  171. NS_IMETHODIMP jxMySQL50::GetPort(PRUint32 *aPort)
  172. {
  173. *aPort = mPort;
  174. return NS_OK;
  175. }
  176. NS_IMETHODIMP jxMySQL50::SetPort(PRUint32 aPort)
  177. {
  178. mPort = aPort;
  179. return NS_OK;
  180. }
  181. /* attribute AString socket; */
  182. NS_IMETHODIMP jxMySQL50::GetSocket(nsAString & aSocket)
  183. {
  184. aSocket.Assign(NS_ConvertUTF8toUTF16(mSocket));
  185. return NS_OK;
  186. }
  187. NS_IMETHODIMP jxMySQL50::SetSocket(const nsAString & aSocket)
  188. {
  189. // process the socket arg
  190. if (aSocket.Length() == 0)
  191. {
  192. if (mSocket != nsnull) { nsMemory::Free(mSocket); }
  193. mSocket = nsnull;
  194. }
  195. else {
  196. mSocket = ToNewUTF8String(aSocket);
  197. }
  198. return NS_OK;
  199. }
  200. /* attribute AString characterSet; */
  201. NS_IMETHODIMP jxMySQL50::GetCharacterSet(nsAString & aCharacterSet)
  202. {
  203. aCharacterSet.Assign(NS_ConvertUTF8toUTF16(mysql_character_set_name(mConnection)));
  204. return NS_OK;
  205. }
  206. #if 0
  207. NS_IMETHODIMP jxMySQL50::SetCharacterSet(const nsAString & aCharacterSet)
  208. {
  209. if (! mConnected)
  210. {
  211. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  212. return mErrno;
  213. }
  214. char * str = ToNewUTF8String(aCharacterSet);
  215. if (mysql_set_character_set(mConnection, str))
  216. {
  217. mErrno = JX_MYSQL50_MYSQL_ERROR;
  218. nsMemory::Free(str);
  219. return mErrno;
  220. }
  221. nsMemory::Free(str);
  222. return NS_OK;
  223. }
  224. #endif
  225. /* attribute unsigned long options; */
  226. NS_IMETHODIMP jxMySQL50::GetOptions(PRUint32 *aOptions)
  227. {
  228. *aOptions = mOptions;
  229. return NS_OK;
  230. }
  231. /* [noscript] readonly attribute boolean connected; */
  232. NS_IMETHODIMP jxMySQL50::GetConnected(PRBool *aConnected)
  233. {
  234. if (! mConnected)
  235. {
  236. *aConnected = PR_FALSE;
  237. }
  238. else {
  239. *aConnected = PR_TRUE;
  240. }
  241. return NS_OK;
  242. }
  243. /* readonly attribute unsigned long CLIENT_COMPRESS; */
  244. NS_IMETHODIMP jxMySQL50::GetCLIENT_COMPRESS(PRUint32 *aCLIENT_COMPRESS)
  245. {
  246. *aCLIENT_COMPRESS = CLIENT_COMPRESS;
  247. return NS_OK;
  248. }
  249. /* readonly attribute unsigned long CLIENT_FOUND_ROWS; */
  250. NS_IMETHODIMP jxMySQL50::GetCLIENT_FOUND_ROWS(PRUint32 *aCLIENT_FOUND_ROWS)
  251. {
  252. *aCLIENT_FOUND_ROWS = CLIENT_FOUND_ROWS;
  253. return NS_OK;
  254. }
  255. /* readonly attribute unsigned long CLIENT_IGNORE_SPACE; */
  256. NS_IMETHODIMP jxMySQL50::GetCLIENT_IGNORE_SPACE(PRUint32 *aCLIENT_IGNORE_SPACE)
  257. {
  258. *aCLIENT_IGNORE_SPACE = CLIENT_IGNORE_SPACE;
  259. return NS_OK;
  260. }
  261. /* readonly attribute unsigned long CLIENT_INTERACTIVE; */
  262. NS_IMETHODIMP jxMySQL50::GetCLIENT_INTERACTIVE(PRUint32 *aCLIENT_INTERACTIVE)
  263. {
  264. *aCLIENT_INTERACTIVE = CLIENT_INTERACTIVE;
  265. return NS_OK;
  266. }
  267. /* readonly attribute unsigned long CLIENT_LOCAL_FILES; */
  268. NS_IMETHODIMP jxMySQL50::GetCLIENT_LOCAL_FILES(PRUint32 *aCLIENT_LOCAL_FILES)
  269. {
  270. *aCLIENT_LOCAL_FILES = CLIENT_LOCAL_FILES;
  271. return NS_OK;
  272. }
  273. /* readonly attribute unsigned long CLIENT_MULTI_RESULTS; */
  274. NS_IMETHODIMP jxMySQL50::GetCLIENT_MULTI_RESULTS(PRUint32 *aCLIENT_MULTI_RESULTS)
  275. {
  276. *aCLIENT_MULTI_RESULTS = CLIENT_MULTI_RESULTS;
  277. return NS_OK;
  278. }
  279. /* readonly attribute unsigned long CLIENT_MULTI_STATEMENTS; */
  280. NS_IMETHODIMP jxMySQL50::GetCLIENT_MULTI_STATEMENTS(PRUint32 *aCLIENT_MULTI_STATEMENTS)
  281. {
  282. *aCLIENT_MULTI_STATEMENTS = CLIENT_MULTI_STATEMENTS;
  283. return NS_OK;
  284. }
  285. /* readonly attribute unsigned long CLIENT_NO_SCHEMA; */
  286. NS_IMETHODIMP jxMySQL50::GetCLIENT_NO_SCHEMA(PRUint32 *aCLIENT_NO_SCHEMA)
  287. {
  288. *aCLIENT_NO_SCHEMA = CLIENT_NO_SCHEMA;
  289. return NS_OK;
  290. }
  291. /* readonly attribute unsigned long CLIENT_ODBC; */
  292. NS_IMETHODIMP jxMySQL50::GetCLIENT_ODBC(PRUint32 *aCLIENT_ODBC)
  293. {
  294. *aCLIENT_ODBC = CLIENT_ODBC;
  295. return NS_OK;
  296. }
  297. /* readonly attribute unsigned long CLIENT_SSL; */
  298. NS_IMETHODIMP jxMySQL50::GetCLIENT_SSL(PRUint32 *aCLIENT_SSL)
  299. {
  300. *aCLIENT_SSL = CLIENT_SSL;
  301. return NS_OK;
  302. }
  303. /* readonly attribute unsigned long OPT_CONNECT_TIMEOUT; */
  304. NS_IMETHODIMP jxMySQL50::GetOPT_CONNECT_TIMEOUT(PRUint32 *aOPT_CONNECT_TIMEOUT)
  305. {
  306. *aOPT_CONNECT_TIMEOUT = MYSQL_OPT_CONNECT_TIMEOUT;
  307. return NS_OK;
  308. }
  309. /* readonly attribute unsigned long OPT_COMPRESS; */
  310. NS_IMETHODIMP jxMySQL50::GetOPT_COMPRESS(PRUint32 *aOPT_COMPRESS)
  311. {
  312. *aOPT_COMPRESS = MYSQL_OPT_COMPRESS;
  313. return NS_OK;
  314. }
  315. /* readonly attribute unsigned long OPT_NAMED_PIPE; */
  316. NS_IMETHODIMP jxMySQL50::GetOPT_NAMED_PIPE(PRUint32 *aOPT_NAMED_PIPE)
  317. {
  318. *aOPT_NAMED_PIPE = MYSQL_OPT_NAMED_PIPE;
  319. return NS_OK;
  320. }
  321. /* readonly attribute unsigned long INIT_COMMAND; */
  322. NS_IMETHODIMP jxMySQL50::GetINIT_COMMAND(PRUint32 *aINIT_COMMAND)
  323. {
  324. *aINIT_COMMAND = MYSQL_INIT_COMMAND;
  325. return NS_OK;
  326. }
  327. /* readonly attribute unsigned long READ_DEFAULT_FILE; */
  328. NS_IMETHODIMP jxMySQL50::GetREAD_DEFAULT_FILE(PRUint32 *aREAD_DEFAULT_FILE)
  329. {
  330. *aREAD_DEFAULT_FILE = MYSQL_READ_DEFAULT_FILE;
  331. return NS_OK;
  332. }
  333. /* readonly attribute unsigned long READ_DEFAULT_GROUP; */
  334. NS_IMETHODIMP jxMySQL50::GetREAD_DEFAULT_GROUP(PRUint32 *aREAD_DEFAULT_GROUP)
  335. {
  336. *aREAD_DEFAULT_GROUP = MYSQL_READ_DEFAULT_GROUP;
  337. return NS_OK;
  338. }
  339. /* readonly attribute unsigned long SET_CHARSET_DIR; */
  340. NS_IMETHODIMP jxMySQL50::GetSET_CHARSET_DIR(PRUint32 *aSET_CHARSET_DIR)
  341. {
  342. *aSET_CHARSET_DIR = MYSQL_SET_CHARSET_DIR;
  343. return NS_OK;
  344. }
  345. /* readonly attribute unsigned long SET_CHARSET_NAME; */
  346. NS_IMETHODIMP jxMySQL50::GetSET_CHARSET_NAME(PRUint32 *aSET_CHARSET_NAME)
  347. {
  348. *aSET_CHARSET_NAME = MYSQL_SET_CHARSET_NAME;
  349. return NS_OK;
  350. }
  351. /* readonly attribute unsigned long OPT_LOCAL_INFILE; */
  352. NS_IMETHODIMP jxMySQL50::GetOPT_LOCAL_INFILE(PRUint32 *aOPT_LOCAL_INFILE)
  353. {
  354. *aOPT_LOCAL_INFILE = MYSQL_OPT_LOCAL_INFILE;
  355. return NS_OK;
  356. }
  357. /* readonly attribute unsigned long OPT_PROTOCOL; */
  358. NS_IMETHODIMP jxMySQL50::GetOPT_PROTOCOL(PRUint32 *aOPT_PROTOCOL)
  359. {
  360. *aOPT_PROTOCOL = MYSQL_OPT_PROTOCOL;
  361. return NS_OK;
  362. }
  363. /* readonly attribute unsigned long SHARED_MEMORY_BASE_NAME; */
  364. NS_IMETHODIMP jxMySQL50::GetSHARED_MEMORY_BASE_NAME(PRUint32 *aSHARED_MEMORY_BASE_NAME)
  365. {
  366. *aSHARED_MEMORY_BASE_NAME = MYSQL_SHARED_MEMORY_BASE_NAME;
  367. return NS_OK;
  368. }
  369. /* readonly attribute unsigned long OPT_READ_TIMEOUT; */
  370. NS_IMETHODIMP jxMySQL50::GetOPT_READ_TIMEOUT(PRUint32 *aOPT_READ_TIMEOUT)
  371. {
  372. *aOPT_READ_TIMEOUT = MYSQL_OPT_READ_TIMEOUT;
  373. return NS_OK;
  374. }
  375. /* readonly attribute unsigned long OPT_WRITE_TIMEOUT; */
  376. NS_IMETHODIMP jxMySQL50::GetOPT_WRITE_TIMEOUT(PRUint32 *aOPT_WRITE_TIMEOUT)
  377. {
  378. *aOPT_WRITE_TIMEOUT = MYSQL_OPT_WRITE_TIMEOUT;
  379. return NS_OK;
  380. }
  381. /* readonly attribute unsigned long OPT_USE_RESULT; */
  382. NS_IMETHODIMP jxMySQL50::GetOPT_USE_RESULT(PRUint32 *aOPT_USE_RESULT)
  383. {
  384. *aOPT_USE_RESULT = MYSQL_OPT_USE_RESULT;
  385. return NS_OK;
  386. }
  387. /* readonly attribute unsigned long OPT_USE_REMOTE_CONNECTION; */
  388. NS_IMETHODIMP jxMySQL50::GetOPT_USE_REMOTE_CONNECTION(PRUint32 *aOPT_USE_REMOTE_CONNECTION)
  389. {
  390. *aOPT_USE_REMOTE_CONNECTION = MYSQL_OPT_USE_REMOTE_CONNECTION;
  391. return NS_OK;
  392. }
  393. /* readonly attribute unsigned long OPT_USE_EMBEDDED_CONNECTION; */
  394. NS_IMETHODIMP jxMySQL50::GetOPT_USE_EMBEDDED_CONNECTION(PRUint32 *aOPT_USE_EMBEDDED_CONNECTION)
  395. {
  396. *aOPT_USE_EMBEDDED_CONNECTION = MYSQL_OPT_USE_EMBEDDED_CONNECTION;
  397. return NS_OK;
  398. }
  399. /* readonly attribute unsigned long OPT_GUESS_CONNECTION; */
  400. NS_IMETHODIMP jxMySQL50::GetOPT_GUESS_CONNECTION(PRUint32 *aOPT_GUESS_CONNECTION)
  401. {
  402. *aOPT_GUESS_CONNECTION = MYSQL_OPT_GUESS_CONNECTION;
  403. return NS_OK;
  404. }
  405. /* readonly attribute unsigned long SET_CLIENT_IP; */
  406. NS_IMETHODIMP jxMySQL50::GetSET_CLIENT_IP(PRUint32 *aSET_CLIENT_IP)
  407. {
  408. *aSET_CLIENT_IP = MYSQL_SET_CLIENT_IP;
  409. return NS_OK;
  410. }
  411. /* readonly attribute unsigned long SECURE_AUTH; */
  412. NS_IMETHODIMP jxMySQL50::GetSECURE_AUTH(PRUint32 *aSECURE_AUTH)
  413. {
  414. *aSECURE_AUTH = MYSQL_SECURE_AUTH;
  415. return NS_OK;
  416. }
  417. /* readonly attribute unsigned long REPORT_DATA_TRUNCATION; */
  418. NS_IMETHODIMP jxMySQL50::GetREPORT_DATA_TRUNCATION(PRUint32 *aREPORT_DATA_TRUNCATION)
  419. {
  420. *aREPORT_DATA_TRUNCATION = MYSQL_REPORT_DATA_TRUNCATION;
  421. return NS_OK;
  422. }
  423. /* readonly attribute unsigned long OPT_RECONNECT; */
  424. NS_IMETHODIMP jxMySQL50::GetOPT_RECONNECT(PRUint32 *aOPT_RECONNECT)
  425. {
  426. *aOPT_RECONNECT = MYSQL_OPT_RECONNECT;
  427. return NS_OK;
  428. }
  429. /* readonly attribute unsigned long OPT_SSL_VERIFY_SERVER_CERT; */
  430. NS_IMETHODIMP jxMySQL50::GetOPT_SSL_VERIFY_SERVER_CERT(PRUint32 *aOPT_SSL_VERIFY_SERVER_CERT)
  431. {
  432. *aOPT_SSL_VERIFY_SERVER_CERT = MYSQL_OPT_SSL_VERIFY_SERVER_CERT;
  433. return NS_OK;
  434. }
  435. /* void autocommit (in boolean mode); */
  436. NS_IMETHODIMP jxMySQL50::Autocommit(PRBool mode, PRBool *_retval)
  437. {
  438. // If we get a non-zero return value
  439. if ( mysql_autocommit(mConnection, mode))
  440. {
  441. // error
  442. *_retval = PR_FALSE;
  443. mErrno = JX_MYSQL50_MYSQL_ERROR;
  444. return mErrno;
  445. }
  446. // Succeeded so return TRUE
  447. *_retval = PR_TRUE;
  448. return NS_OK;
  449. }
  450. /* boolean changeUser (in AString user, in AString password, in AString dbname); */
  451. NS_IMETHODIMP jxMySQL50::ChangeUser(const nsAString & argUser, const nsAString & argPassword, const nsAString & argDatabase, PRBool *_retval)
  452. {
  453. if (! mConnected)
  454. {
  455. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  456. return mErrno;
  457. }
  458. // process the user arg
  459. if (argUser.Length() == 0 || argPassword.Length() == 0)
  460. {
  461. mErrno = JX_MYSQL50_ERROR_NULL_POINTER;
  462. return mErrno;
  463. }
  464. mUser = ToNewUTF8String(argUser);
  465. mPassword = ToNewUTF8String(argPassword);
  466. // process the database arg
  467. if (argDatabase.Length() != 0)
  468. {
  469. if (mDatabase != nsnull) { nsMemory::Free(mDatabase); }
  470. mDatabase = ToNewUTF8String(argDatabase);
  471. }
  472. else
  473. {
  474. if (mDatabase != nsnull) { nsMemory::Free(mDatabase); }
  475. mDatabase = nsnull;
  476. }
  477. // If the change failed
  478. if (mysql_change_user(mConnection, mUser, mPassword, mDatabase))
  479. {
  480. // Return FALSE
  481. *_retval = PR_FALSE;
  482. mErrno = JX_MYSQL50_MYSQL_ERROR;
  483. return mErrno;
  484. }
  485. *_retval = PR_TRUE;
  486. mConnected = PR_TRUE;
  487. return NS_OK;
  488. }
  489. /* AString clientInfo (); */
  490. NS_IMETHODIMP jxMySQL50::ClientInfo(nsAString & _retval)
  491. {
  492. _retval.Assign(NS_ConvertUTF8toUTF16(mysql_get_client_info()));
  493. return NS_OK;
  494. }
  495. /* unsigned long clientVersion (); */
  496. NS_IMETHODIMP jxMySQL50::ClientVersion(PRUint32 *_retval)
  497. {
  498. *_retval = mysql_get_client_version();
  499. return NS_OK;
  500. }
  501. /* void close (); */
  502. NS_IMETHODIMP jxMySQL50::Close()
  503. {
  504. if (! mConnected)
  505. {
  506. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  507. return mErrno;
  508. }
  509. mysql_close(mConnection);
  510. mConnected = PR_FALSE;
  511. mConnection = mysql_init((MYSQL *) nsnull);
  512. return NS_OK;
  513. }
  514. /* boolean commit (); */
  515. NS_IMETHODIMP jxMySQL50::Commit(PRBool *_retval)
  516. {
  517. if (! mConnected)
  518. {
  519. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  520. return mErrno;
  521. }
  522. if (mysql_commit(mConnection))
  523. {
  524. // Return FALSE
  525. *_retval = PR_FALSE;
  526. mErrno = JX_MYSQL50_MYSQL_ERROR;
  527. return mErrno;
  528. }
  529. *_retval = PR_TRUE;
  530. return NS_OK;
  531. }
  532. /* AString info (); */
  533. NS_IMETHODIMP jxMySQL50::Info(nsAString & _retval)
  534. {
  535. _retval.Assign(NS_ConvertUTF8toUTF16(mysql_info(mConnection)));
  536. return NS_OK;
  537. }
  538. /* unsigned long long insertID (); */
  539. NS_IMETHODIMP jxMySQL50::InsertID(PRUint64 *_retval)
  540. {
  541. if (! mConnected)
  542. {
  543. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  544. return mErrno;
  545. }
  546. *_retval = mysql_insert_id(mConnection);
  547. return NS_OK;
  548. }
  549. /* boolean rollback (); */
  550. NS_IMETHODIMP jxMySQL50::Rollback(PRBool *_retval)
  551. {
  552. if (! mConnected)
  553. {
  554. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  555. return mErrno;
  556. }
  557. if (mysql_rollback(mConnection))
  558. {
  559. // Return FALSE
  560. *_retval = PR_FALSE;
  561. mErrno = JX_MYSQL50_MYSQL_ERROR;
  562. return mErrno;
  563. }
  564. *_retval = PR_TRUE;
  565. return NS_OK;
  566. }
  567. /* AString serverInfo (); */
  568. NS_IMETHODIMP jxMySQL50::ServerInfo(nsAString & _retval)
  569. {
  570. if (! mConnected)
  571. {
  572. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  573. return mErrno;
  574. }
  575. _retval.Assign(NS_ConvertUTF8toUTF16(mysql_get_server_info(mConnection)));
  576. return NS_OK;
  577. }
  578. /* AString SQLState (); */
  579. NS_IMETHODIMP jxMySQL50::SQLState(nsAString & _retval)
  580. {
  581. if (! mConnected)
  582. {
  583. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  584. return mErrno;
  585. }
  586. _retval.Assign(NS_ConvertUTF8toUTF16(mysql_sqlstate(mConnection)));
  587. return NS_OK;
  588. }
  589. /* unsigned long serverVersion (); */
  590. NS_IMETHODIMP jxMySQL50::ServerVersion(PRUint32 *_retval)
  591. {
  592. if (! mConnected)
  593. {
  594. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  595. return mErrno;
  596. }
  597. *_retval = mysql_get_server_version(mConnection);
  598. return NS_OK;
  599. }
  600. /* AString serverInfo (); */
  601. NS_IMETHODIMP jxMySQL50::HostInfo(nsAString & _retval)
  602. {
  603. if (! mConnected)
  604. {
  605. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  606. return mErrno;
  607. }
  608. _retval.Assign(NS_ConvertUTF8toUTF16(mysql_get_host_info(mConnection)));
  609. return NS_OK;
  610. }
  611. /* AString escape (in AString input); */
  612. NS_IMETHODIMP jxMySQL50::Escape(const nsAString & input, nsAString & _retval)
  613. {
  614. char *newstr;
  615. PRInt32 escapestr_len, newstr_len;
  616. if (! mConnected)
  617. {
  618. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  619. return mErrno;
  620. }
  621. char * str = ToNewUTF8String(input);
  622. escapestr_len = strlen(str);
  623. newstr = static_cast<char*>(nsMemory::Alloc((escapestr_len*2) + 1));
  624. if (!newstr)
  625. {
  626. mErrno = JX_MYSQL50_ERROR_OUT_OF_MEMORY;
  627. return mErrno;
  628. }
  629. newstr_len = mysql_real_escape_string(mConnection, newstr, str, escapestr_len);
  630. _retval.Assign(NS_ConvertUTF8toUTF16(newstr));
  631. nsMemory::Free(str);
  632. nsMemory::Free(newstr);
  633. return NS_OK;
  634. }
  635. /* long nextResult (); */
  636. NS_IMETHODIMP jxMySQL50::NextResult(jxIMySQL50ResultSet **aReturn)
  637. {
  638. // If we didn't get a valid place to return the ResultSet object pointer,
  639. // then cause an exception to be returned to JavaScript
  640. if (! aReturn )
  641. {
  642. mErrno = JX_MYSQL50_ERROR_NULL_POINTER;
  643. return mErrno;
  644. }
  645. // If we're not connected to a db server at the moment,
  646. // then cause an exception to be returned to JavaScript
  647. if (! mConnected)
  648. {
  649. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  650. return mErrno;
  651. }
  652. // Spin up a ResultSet object, toss an exception if we can't create
  653. nsCOMPtr<jxIMySQL50ResultSet> res(do_CreateInstance(JX_MYSQL50RESULTSET_CONTRACTID));
  654. if (!res)
  655. {
  656. mErrno = JX_MYSQL50_ERROR_CANT_CREATEINSTANCE;
  657. return mErrno;
  658. }
  659. // Attach ourselves to the ResultSet object so it can make calls back to us if needed
  660. res->SetMySQL50(this);
  661. // Return the ResultSet object to our caller
  662. *aReturn = res;
  663. NS_ADDREF(*aReturn);
  664. // Tell server to bump to next result set
  665. int status = mysql_next_result(mConnection);
  666. if (status == 0)
  667. {
  668. // Do some work to gether up results.
  669. // error already set for this if failed.
  670. return res->StoreResult(mConnection);
  671. }else if (status == -1)
  672. {
  673. // no more results
  674. res->SetType(eNULL);
  675. }else
  676. {
  677. //error
  678. res->SetType(eERROR);
  679. mErrno = JX_MYSQL50_MYSQL_ERROR;
  680. return mErrno;
  681. }
  682. return NS_OK;
  683. }
  684. enum
  685. {
  686. JX_SERVER_GONE_ERROR = CR_SERVER_GONE_ERROR
  687. };
  688. /* long ping (); */
  689. NS_IMETHODIMP jxMySQL50::Ping(PRInt32 *_retval)
  690. {
  691. if (! mConnected) {
  692. *_retval = JX_SERVER_GONE_ERROR;
  693. return NS_OK;
  694. }
  695. *_retval = mysql_ping(mConnection);
  696. return NS_OK;
  697. }
  698. /* unsigned long protocolVersion (); */
  699. NS_IMETHODIMP jxMySQL50::ProtocolVersion(PRUint32 *_retval)
  700. {
  701. if (! mConnected)
  702. {
  703. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  704. return mErrno;
  705. }
  706. *_retval = mysql_get_proto_info(mConnection);
  707. return NS_OK;
  708. }
  709. /* unsigned long warningCount (); */
  710. NS_IMETHODIMP jxMySQL50::WarningCount(PRUint32 *_retval)
  711. {
  712. if (! mConnected)
  713. {
  714. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  715. return mErrno;
  716. }
  717. *_retval = mysql_warning_count(mConnection);
  718. return NS_OK;
  719. }
  720. /* AString stat (); */
  721. NS_IMETHODIMP jxMySQL50::Stat(nsAString & _retval)
  722. {
  723. if (! mConnected)
  724. {
  725. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  726. return mErrno;
  727. }
  728. _retval.Assign(NS_ConvertUTF8toUTF16(mysql_stat(mConnection)));
  729. return NS_OK;
  730. }
  731. /* boolean threadSafe (); */
  732. NS_IMETHODIMP jxMySQL50::ThreadSafe(PRBool *_retval)
  733. {
  734. *_retval = mysql_thread_safe();
  735. return NS_OK;
  736. }
  737. /*[noscript] SetErrno(in unsigned long err) */
  738. NS_IMETHODIMP jxMySQL50::SetErrorNumber(PRUint32 err)
  739. {
  740. mErrno = err;
  741. return NS_OK;
  742. }
  743. /*[noscript] void saveMySQLError() */
  744. NS_IMETHODIMP jxMySQL50::SaveMySQLError()
  745. {
  746. if (mErrno == JX_MYSQL50_MYSQL_ERROR)
  747. {
  748. mMySQLError[0] = 0;
  749. mMySQLErrno = mysql_errno(mConnection);
  750. const char *p = mysql_error(mConnection);
  751. size_t n = strlen(p);
  752. if (n<1023)
  753. strcpy(mMySQLError, p);
  754. else
  755. {
  756. strncpy(mMySQLError, p, 1023);
  757. mMySQLError[1023] = 0;
  758. }
  759. }
  760. return NS_OK;
  761. }
  762. /* unsigned long errno (); */
  763. NS_IMETHODIMP jxMySQL50::Errno(PRUint32 *_retval)
  764. {
  765. if (mErrno == JX_MYSQL50_MYSQL_ERROR)
  766. {
  767. *_retval = mysql_errno(mConnection);
  768. if (*_retval == 0)
  769. *_retval = mMySQLErrno;
  770. }else
  771. *_retval = mErrno;
  772. return NS_OK;
  773. }
  774. /* AString error (); */
  775. NS_IMETHODIMP jxMySQL50::Error(nsAString & aError)
  776. {
  777. aError.Truncate();
  778. if (mErrno == JX_MYSQL50_MYSQL_ERROR)
  779. {
  780. if (mysql_errno(mConnection) == 0)
  781. aError.Assign(NS_ConvertUTF8toUTF16(mMySQLError));
  782. else
  783. aError.Assign(NS_ConvertUTF8toUTF16(mysql_error(mConnection)));
  784. return NS_OK;
  785. }
  786. NON_MYSQL_ERROR(mErrno, aError);
  787. if (aError.Length() == 0)
  788. {
  789. const char* me = mysql_error(mConnection);
  790. AppendUTF8toUTF16(nsPrintfCString(0x1000, "Unknown error %lX. Last MYSQL error is %s", mErrno, (me && *me) ? me : ""), aError);
  791. }
  792. #if 0
  793. switch (mErrno)
  794. {
  795. case JX_MYSQL50_ERROR_NOT_CONNECTED:
  796. aError.AssignLiteral("Not connected to MYSQL DB");
  797. break;
  798. case JX_MYSQL50_ERROR_CANT_CREATEINSTANCE:
  799. aError.AssignLiteral("Create object failed");
  800. break;
  801. case JX_MYSQL50_ERROR_STMT_ALREADY_INITIALIZED:
  802. aError.AssignLiteral("Statement already initialized");
  803. break;
  804. case JX_MYSQL50_ERROR_STMT_NULL:
  805. aError.AssignLiteral("Statement is null");
  806. break;
  807. case JX_MYSQL50_ERROR_UNEXPECTED_ERROR:
  808. aError.AssignLiteral("Unexpected error");
  809. break;
  810. case JX_MYSQL50_NULL_RESULTSET:
  811. aError.AssignLiteral("Resultset is null");
  812. break;
  813. case JX_MYSQL50_ERROR_ILLEGAL_VALUE:
  814. aError.AssignLiteral("Illegal value (eg too small or toolarge) specified");
  815. break;
  816. case JX_MYSQL50_ERROR_INVALID_TYPE:
  817. aError.AssignLiteral("Invalid type");
  818. break;
  819. case JX_MYSQL50_ERROR_BIND_ARRAY_IS_NULL:
  820. aError.AssignLiteral("Bind array is null");
  821. break;
  822. case JX_MYSQL50_CANNOT_CONVERT_DATA:
  823. aError.AssignLiteral("Cannot convert data");
  824. break;
  825. case JX_MYSQL50_ERROR_NULL_POINTER:
  826. aError.AssignLiteral("The point is null");
  827. break;
  828. case JX_MYSQL50_ERROR_OUT_OF_MEMORY:
  829. aError.AssignLiteral("Out of memory");
  830. break;
  831. default:
  832. char unkError[0x1000];
  833. sprintf(unkError, "Unkown error 0x%0x. Last MYSQL error is %s", mErrno, mysql_error(mConnection));
  834. aError.AssignLiteral(unkError);
  835. break;
  836. }
  837. #endif
  838. return NS_OK;
  839. }
  840. /* long option (in unsigned long option); */
  841. NS_IMETHODIMP jxMySQL50::Option(PRUint32 option, PRInt32 *_retval)
  842. {
  843. PRInt32 ret = mysql_options(mConnection, (mysql_option)option, 0);
  844. *_retval = ret;
  845. if (ret)
  846. {
  847. mErrno = JX_MYSQL50_MYSQL_ERROR;
  848. return mErrno;
  849. }
  850. return NS_OK;
  851. }
  852. /* long optionString (in unsigned long option, in AString arg); */
  853. NS_IMETHODIMP jxMySQL50::OptionString(PRUint32 option, const nsAString & arg, PRInt32 *_retval)
  854. {
  855. char * str = ToNewUTF8String(arg);
  856. PRInt32 ret = mysql_options(mConnection, (mysql_option)option, str);
  857. nsMemory::Free(str);
  858. *_retval = ret;
  859. if (ret)
  860. {
  861. mErrno = JX_MYSQL50_MYSQL_ERROR;
  862. return mErrno;
  863. }
  864. return NS_OK;
  865. }
  866. /* long optionInt (in unsigned long option, in unsigned long arg); */
  867. NS_IMETHODIMP jxMySQL50::OptionInt(PRUint32 option, PRUint32 arg, PRInt32 *_retval)
  868. {
  869. PRInt32 ret = mysql_options(mConnection, (mysql_option)option, (char*) &arg);
  870. *_retval = ret;
  871. if (ret)
  872. {
  873. mErrno = JX_MYSQL50_MYSQL_ERROR;
  874. return mErrno;
  875. }
  876. return NS_OK;
  877. }
  878. /* long optionBool (in unsigned long option, in boolean arg); */
  879. NS_IMETHODIMP jxMySQL50::OptionBool(PRUint32 option, PRBool arg, PRInt32 *_retval)
  880. {
  881. PRInt32 ret = mysql_options(mConnection, (mysql_option)option, (char*) &arg);
  882. *_retval = ret;
  883. if (ret)
  884. {
  885. mErrno = JX_MYSQL50_MYSQL_ERROR;
  886. return mErrno;
  887. }
  888. return NS_OK;
  889. }
  890. /* boolean connect (in AString host, in AString user, in AString password, in AString database, in unsigned long port, in AString socket, in unsigned long options); */
  891. NS_IMETHODIMP jxMySQL50::Connect(const nsAString & argHost, const nsAString & argUser, const nsAString & argPassword,
  892. const nsAString & argDatabase, PRUint32 argPort, const nsAString & argSocket, PRUint32 argOptions, PRBool *_retval)
  893. {
  894. // process the host arg
  895. if (argHost.Length() != 0)
  896. {
  897. if (mHost != nsnull) { nsMemory::Free(mHost); }
  898. mHost = ToNewUTF8String(argHost);
  899. }
  900. // process the user arg
  901. if (argUser.Length() != 0)
  902. {
  903. if (mUser != nsnull) { nsMemory::Free(mUser); }
  904. mUser = ToNewUTF8String(argUser);
  905. }
  906. // process the password arg
  907. if (argPassword.Length() != 0)
  908. {
  909. if (mPassword != nsnull) { nsMemory::Free(mPassword); }
  910. mPassword = ToNewUTF8String(argPassword);
  911. }
  912. // process the database arg
  913. if (argDatabase.Length() != 0)
  914. {
  915. if (mDatabase != nsnull) { nsMemory::Free(mDatabase); }
  916. mDatabase = ToNewUTF8String(argDatabase);
  917. }
  918. // process the port arg
  919. if (argPort != 0)
  920. {
  921. mPort = argPort;
  922. }
  923. // process the socket arg
  924. if (argSocket.Length() != 0)
  925. {
  926. if (mSocket != nsnull) { nsMemory::Free(mSocket); }
  927. mSocket = ToNewUTF8String(argSocket);
  928. }
  929. // process the options arg
  930. if (argOptions != 0)
  931. {
  932. mOptions = argOptions;
  933. }
  934. // If the connect failed
  935. if (! mysql_real_connect(mConnection, mHost, mUser, mPassword, mDatabase, mPort, mSocket, mOptions))
  936. {
  937. // Return FALSE
  938. *_retval = PR_FALSE;
  939. mErrno = JX_MYSQL50_MYSQL_ERROR;
  940. nsCOMPtr<aptICoreLog> log(do_CreateInstance(APT_CORELOG_CONTRACTID));
  941. if (log)
  942. {
  943. nsCAutoString sError(mysql_error(mConnection));
  944. nsCAutoString sMe("jxMySQL50");
  945. log->Log(eERROR, sMe, sError);
  946. }
  947. return mErrno;
  948. }
  949. if (mysql_set_character_set(mConnection, "utf8"))
  950. {
  951. // Return FALSE
  952. *_retval = PR_FALSE;
  953. mErrno = JX_MYSQL50_MYSQL_ERROR;
  954. return mErrno;
  955. }
  956. *_retval = PR_TRUE;
  957. mConnected = PR_TRUE;
  958. return NS_OK;
  959. }
  960. /* boolean query (in AString statement); */
  961. NS_IMETHODIMP jxMySQL50::Query(const nsAString & statement, jxIMySQL50ResultSet **aReturn)
  962. {
  963. // If we didn't get a valid place to return the ResultSet object pointer,
  964. // then cause an exception to be returned to JavaScript
  965. //NS_ENSURE_ARG_POINTER(aReturn);
  966. if (! aReturn )
  967. {
  968. mErrno = JX_MYSQL50_ERROR_NULL_POINTER;
  969. return mErrno;
  970. }
  971. // If we're not connected to a db server at the moment,
  972. // then cause an exception to be returned to JavaScript
  973. if (! mConnected)
  974. {
  975. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  976. return mErrno;
  977. }
  978. // Spin up a ResultSet object, toss an exception if we can't create
  979. nsCOMPtr<jxIMySQL50ResultSet> res(do_CreateInstance(JX_MYSQL50RESULTSET_CONTRACTID));
  980. if(!res)
  981. {
  982. mErrno = JX_MYSQL50_ERROR_CANT_CREATEINSTANCE;
  983. return mErrno;
  984. }
  985. // Attach ourselves to the ResultSet object so it can make calls back to us if needed
  986. res->SetMySQL50(this);
  987. // Get the length of the query string
  988. char * stmt = ToNewUTF8String(statement);
  989. int length;
  990. length= strlen(stmt);
  991. // Execute the SQL statement
  992. int ret = mysql_real_query(mConnection, stmt, length);
  993. nsMemory::Free(stmt);
  994. if (ret)
  995. {
  996. // error
  997. *aReturn = 0;
  998. mErrno = JX_MYSQL50_MYSQL_ERROR;
  999. return mErrno;
  1000. }
  1001. // Return the ResultSet object to our caller
  1002. *aReturn = res;
  1003. NS_ADDREF(*aReturn);
  1004. // Do some work to gether up results.
  1005. // error already set if failed.
  1006. return res->StoreResult(mConnection);
  1007. #if 0
  1008. // If the ResultSet actually isn't there
  1009. PRBool hasRes = PR_FALSE;
  1010. res->HasRes(&hasRes);
  1011. if (!hasRes)
  1012. {
  1013. // Release our containing object, and return NULL
  1014. NS_RELEASE(*aReturn);
  1015. *aReturn = nsnull;
  1016. }
  1017. #endif
  1018. // return NS_OK;
  1019. }
  1020. /* jxIMySQL50ResultSet listFields (in AString table, in AString wild); */
  1021. NS_IMETHODIMP jxMySQL50::ListFields(const nsAString & table, const nsAString & wild, jxIMySQL50ResultSet **aReturn)
  1022. {
  1023. if (! aReturn )
  1024. {
  1025. mErrno = JX_MYSQL50_ERROR_NULL_POINTER;
  1026. return mErrno;
  1027. }
  1028. // If we're not connected to a db server at the moment,
  1029. // then cause an exception to be returned to JavaScript
  1030. if (! mConnected)
  1031. {
  1032. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  1033. return mErrno;
  1034. }
  1035. // Spin up a ResultSet object, toss an exception if we can't create
  1036. nsCOMPtr<jxIMySQL50ResultSet> res(do_CreateInstance(JX_MYSQL50RESULTSET_CONTRACTID));
  1037. if(!res)
  1038. {
  1039. mErrno = JX_MYSQL50_ERROR_CANT_CREATEINSTANCE;
  1040. return mErrno;
  1041. }
  1042. // Attach ourselves to the ResultSet object so it can make calls back to us if needed
  1043. res->SetMySQL50(this);
  1044. // Call listFields()
  1045. PRBool b;
  1046. nsresult rv = res->ListFields(table, wild, &b);
  1047. // If the call failed
  1048. if (NS_FAILED(rv))
  1049. {
  1050. *aReturn = nsnull;
  1051. mErrno = rv;
  1052. return mErrno;
  1053. }
  1054. // Return the ResultSet object to our caller
  1055. *aReturn = res;
  1056. NS_ADDREF(*aReturn);
  1057. return NS_OK;
  1058. }
  1059. /* jxIMySQL50Statement prepare (in AString queryStr); */
  1060. NS_IMETHODIMP jxMySQL50::Prepare(const nsAString & queryStr, jxIMySQL50Statement **aReturn)
  1061. {
  1062. if (! aReturn )
  1063. {
  1064. mErrno = JX_MYSQL50_ERROR_NULL_POINTER;
  1065. return mErrno;
  1066. }
  1067. // If we're not connected to a db server at the moment,
  1068. // then cause an exception to be returned to JavaScript
  1069. if (! mConnected)
  1070. {
  1071. mErrno = JX_MYSQL50_ERROR_NOT_CONNECTED;
  1072. return mErrno;
  1073. }
  1074. // Spin up a Statement object, toss an exception if we can't create
  1075. nsCOMPtr<jxIMySQL50Statement> stmt(do_CreateInstance(JX_MYSQL50STATEMENT_CONTRACTID));
  1076. if (!stmt)
  1077. {
  1078. mErrno = JX_MYSQL50_ERROR_CANT_CREATEINSTANCE;
  1079. return mErrno;
  1080. }
  1081. // Attach ourselves to the Statement object so it can make calls back to us if needed
  1082. stmt->SetMySQL50(this);
  1083. // Init the Statement
  1084. PRInt32 rc;
  1085. nsresult rv = stmt->Init(queryStr, &rc);
  1086. if (NS_FAILED(rv))
  1087. {
  1088. // init failed
  1089. *aReturn = nsnull;
  1090. mErrno = rv;
  1091. #if 0
  1092. char err[512];
  1093. sprintf(err, " %s", mysql_error(mConnection));
  1094. #endif
  1095. return mErrno;
  1096. }
  1097. // Return the Statement object to our caller
  1098. *aReturn = stmt;
  1099. NS_ADDREF(*aReturn);
  1100. return NS_OK;
  1101. }