您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

906 行
34 KiB

  1. #include <memory>
  2. #include <type_traits>
  3. #include <gtest/gtest.h>
  4. #include <cppmariadb.h>
  5. #include "mock.h"
  6. using namespace ::testing;
  7. using namespace ::cppmariadb;
  8. /**********************************************************************************************************/
  9. TEST(MariaDbTests, MariaDB_connect)
  10. {
  11. StrictMock<MariaDbMock> mock;
  12. InSequence seq;
  13. EXPECT_CALL(mock, mysql_init(nullptr))
  14. .WillOnce(Return(reinterpret_cast<MYSQL*>(0x123)));
  15. EXPECT_CALL(mock, mysql_real_connect(reinterpret_cast<MYSQL*>(0x123), StrEq("testhost"), StrEq("testuser"), StrEq("password"), StrEq("database"), 3306, nullptr, 0))
  16. .WillOnce(Invoke([](MYSQL *mysql, const char*, const char*, const char*, const char*, unsigned int, const char*, unsigned long){
  17. return mysql;
  18. }));
  19. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x123)))
  20. .Times(1);
  21. connection con;
  22. con.connect("testhost", 3306, "testuser", "password", "database", client_flags::empty());
  23. EXPECT_EQ(reinterpret_cast<MYSQL*>(0x123), con.get_handle());
  24. }
  25. TEST(MariaDbTests, MariaDB_errorCode)
  26. {
  27. StrictMock<MariaDbMock> mock;
  28. EXPECT_CALL(mock, mysql_errno(reinterpret_cast<MYSQL*>(0x123)))
  29. .WillOnce(Return(1000));
  30. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x123)));
  31. connection con(reinterpret_cast<MYSQL*>(0x123));
  32. auto ret = con.error_code();
  33. EXPECT_EQ(error_code::ErrorFirst, ret);
  34. }
  35. TEST(MariaDbTests, MariaDB_errorMessage)
  36. {
  37. {
  38. StrictMock<MariaDbMock> mock;
  39. std::string msg("test");
  40. EXPECT_CALL(mock, mysql_error(reinterpret_cast<MYSQL*>(0x123)))
  41. .WillOnce(Return(msg.data()));
  42. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x123)));
  43. connection con(reinterpret_cast<MYSQL*>(0x123));
  44. auto ret = con.error_msg();
  45. EXPECT_EQ(msg, ret);
  46. }
  47. {
  48. StrictMock<MariaDbMock> mock;
  49. EXPECT_CALL(mock, mysql_error(reinterpret_cast<MYSQL*>(0x123)))
  50. .WillOnce(Return(nullptr));
  51. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x123)));
  52. connection con(reinterpret_cast<MYSQL*>(0x123));
  53. auto ret = con.error_msg();
  54. EXPECT_EQ(std::string(), ret);
  55. }
  56. }
  57. /**********************************************************************************************************/
  58. TEST(MariaDbTests, Connection_fieldcount)
  59. {
  60. StrictMock<MariaDbMock> mock;
  61. InSequence seq;
  62. EXPECT_CALL(mock, mysql_field_count(reinterpret_cast<MYSQL*>(0x5514)))
  63. .WillOnce(Return(5));
  64. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x5514)))
  65. .Times(1);
  66. connection con(reinterpret_cast<MYSQL*>(0x5514));
  67. auto ret = con.fieldcount();
  68. EXPECT_EQ(5, ret);
  69. }
  70. TEST(MariaDbTests, Connection_escape)
  71. {
  72. StrictMock<MariaDbMock> mock;
  73. InSequence seq;
  74. EXPECT_CALL(mock, mysql_real_escape_string(reinterpret_cast<MYSQL*>(0x5514), _, StrEq("'teststring'"), 12))
  75. .WillOnce(DoAll(
  76. WithArgs<1>(Invoke([](char* str){
  77. memcpy(str, "\\'teststring\\'", 14);
  78. })),
  79. Return(14)));
  80. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x5514)))
  81. .Times(1);
  82. connection con(reinterpret_cast<MYSQL*>(0x5514));
  83. auto ret = con.escape("'teststring'");
  84. EXPECT_EQ(std::string("\\'teststring\\'"), ret);
  85. }
  86. /**********************************************************************************************************/
  87. TEST(MariaDbTests, Connection_execute_queryFailed)
  88. {
  89. StrictMock<MariaDbMock> mock;
  90. EXPECT_CALL(mock, mysql_errno(_)).Times(AnyNumber());
  91. EXPECT_CALL(mock, mysql_error(_)).Times(AnyNumber());
  92. InSequence seq;
  93. EXPECT_CALL(mock, mysql_real_query(reinterpret_cast<MYSQL*>(0x6818), StrEq("SELECT * FROM blubb"), 19))
  94. .WillOnce(Return(1));
  95. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x6818)))
  96. .Times(1);
  97. connection con(reinterpret_cast<MYSQL*>(0x6818));
  98. EXPECT_THROW(con.execute("SELECT * FROM blubb"), ::cppmariadb::exception);
  99. }
  100. TEST(MariaDbTests, Connection_execute_storeResultFailed_fieldCountGreaterZero)
  101. {
  102. StrictMock<MariaDbMock> mock;
  103. EXPECT_CALL(mock, mysql_errno(_)).Times(AnyNumber());
  104. EXPECT_CALL(mock, mysql_error(_)).Times(AnyNumber());
  105. InSequence seq;
  106. EXPECT_CALL(mock, mysql_real_query(reinterpret_cast<MYSQL*>(0x6818), StrEq("SELECT * FROM blubb"), 19))
  107. .WillOnce(Return(0));
  108. EXPECT_CALL(mock, mysql_store_result(reinterpret_cast<MYSQL*>(0x6818)))
  109. .WillOnce(Return(nullptr));
  110. EXPECT_CALL(mock, mysql_field_count(reinterpret_cast<MYSQL*>(0x6818)))
  111. .WillOnce(Return(5));
  112. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x6818)))
  113. .Times(1);
  114. connection con(reinterpret_cast<MYSQL*>(0x6818));
  115. EXPECT_THROW(con.execute("SELECT * FROM blubb"), ::cppmariadb::exception);
  116. }
  117. TEST(MariaDbTests, Connection_execute_storeResultFailed_fieldCountIsZero)
  118. {
  119. StrictMock<MariaDbMock> mock;
  120. EXPECT_CALL(mock, mysql_errno(_)).Times(AnyNumber());
  121. EXPECT_CALL(mock, mysql_error(_)).Times(AnyNumber());
  122. InSequence seq;
  123. EXPECT_CALL(mock, mysql_real_query(reinterpret_cast<MYSQL*>(0x6818), StrEq("SELECT * FROM blubb"), 19))
  124. .WillOnce(Return(0));
  125. EXPECT_CALL(mock, mysql_store_result(reinterpret_cast<MYSQL*>(0x6818)))
  126. .WillOnce(Return(nullptr));
  127. EXPECT_CALL(mock, mysql_field_count(reinterpret_cast<MYSQL*>(0x6818)))
  128. .WillOnce(Return(0));
  129. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x6818)))
  130. .Times(1);
  131. connection con(reinterpret_cast<MYSQL*>(0x6818));
  132. con.execute("SELECT * FROM blubb");
  133. ASSERT_FALSE(static_cast<bool>(con.result()));
  134. }
  135. TEST(MariaDbTests, Connection_execute_success)
  136. {
  137. StrictMock<MariaDbMock> mock;
  138. EXPECT_CALL(mock, mysql_errno(_)).Times(AnyNumber());
  139. EXPECT_CALL(mock, mysql_error(_)).Times(AnyNumber());
  140. InSequence seq;
  141. EXPECT_CALL(mock, mysql_real_query(reinterpret_cast<MYSQL*>(0x6818), StrEq("SELECT * FROM blubb"), 19))
  142. .WillOnce(Return(0));
  143. EXPECT_CALL(mock, mysql_store_result(reinterpret_cast<MYSQL*>(0x6818)))
  144. .WillOnce(Return(reinterpret_cast<MYSQL_RES*>(0x8888)));
  145. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x8888)))
  146. .Times(1);
  147. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x6818)))
  148. .Times(1);
  149. connection con(reinterpret_cast<MYSQL*>(0x6818));
  150. con.execute("SELECT * FROM blubb");
  151. ASSERT_TRUE(static_cast<bool>(con.result()));
  152. EXPECT_EQ (reinterpret_cast<MYSQL_RES*>(0x8888), con.result()->get_handle());
  153. }
  154. /**********************************************************************************************************/
  155. TEST(MariaDbTests, Connection_executeStored_queryFailed)
  156. {
  157. StrictMock<MariaDbMock> mock;
  158. EXPECT_CALL(mock, mysql_errno(_)).Times(AnyNumber());
  159. EXPECT_CALL(mock, mysql_error(_)).Times(AnyNumber());
  160. InSequence seq;
  161. EXPECT_CALL(mock, mysql_real_query(reinterpret_cast<MYSQL*>(0x6818), StrEq("SELECT * FROM blubb"), 19))
  162. .WillOnce(Return(1));
  163. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x6818)))
  164. .Times(1);
  165. connection con(reinterpret_cast<MYSQL*>(0x6818));
  166. EXPECT_THROW(con.execute_stored("SELECT * FROM blubb"), ::cppmariadb::exception);
  167. }
  168. TEST(MariaDbTests, Connection_executeStored_storeResultFailed_fieldCountGreaterZero)
  169. {
  170. StrictMock<MariaDbMock> mock;
  171. EXPECT_CALL(mock, mysql_errno(_)).Times(AnyNumber());
  172. EXPECT_CALL(mock, mysql_error(_)).Times(AnyNumber());
  173. InSequence seq;
  174. EXPECT_CALL(mock, mysql_real_query(reinterpret_cast<MYSQL*>(0x6818), StrEq("SELECT * FROM blubb"), 19))
  175. .WillOnce(Return(0));
  176. EXPECT_CALL(mock, mysql_store_result(reinterpret_cast<MYSQL*>(0x6818)))
  177. .WillOnce(Return(nullptr));
  178. EXPECT_CALL(mock, mysql_field_count(reinterpret_cast<MYSQL*>(0x6818)))
  179. .WillOnce(Return(5));
  180. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x6818)))
  181. .Times(1);
  182. connection con(reinterpret_cast<MYSQL*>(0x6818));
  183. EXPECT_THROW(con.execute_stored("SELECT * FROM blubb"), ::cppmariadb::exception);
  184. }
  185. TEST(MariaDbTests, Connection_executeStored_storeResultFailed_fieldCountIsZero)
  186. {
  187. StrictMock<MariaDbMock> mock;
  188. EXPECT_CALL(mock, mysql_errno(_)).Times(AnyNumber());
  189. EXPECT_CALL(mock, mysql_error(_)).Times(AnyNumber());
  190. InSequence seq;
  191. EXPECT_CALL(mock, mysql_real_query(reinterpret_cast<MYSQL*>(0x6818), StrEq("SELECT * FROM blubb"), 19))
  192. .WillOnce(Return(0));
  193. EXPECT_CALL(mock, mysql_store_result(reinterpret_cast<MYSQL*>(0x6818)))
  194. .WillOnce(Return(nullptr));
  195. EXPECT_CALL(mock, mysql_field_count(reinterpret_cast<MYSQL*>(0x6818)))
  196. .WillOnce(Return(0));
  197. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x6818)))
  198. .Times(1);
  199. connection con(reinterpret_cast<MYSQL*>(0x6818));
  200. con.execute_stored("SELECT * FROM blubb");
  201. ASSERT_FALSE(static_cast<bool>(con.result()));
  202. }
  203. TEST(MariaDbTests, Connection_executeStored_success)
  204. {
  205. StrictMock<MariaDbMock> mock;
  206. EXPECT_CALL(mock, mysql_errno(_)).Times(AnyNumber());
  207. EXPECT_CALL(mock, mysql_error(_)).Times(AnyNumber());
  208. InSequence seq;
  209. EXPECT_CALL(mock, mysql_real_query(reinterpret_cast<MYSQL*>(0x6818), StrEq("SELECT * FROM blubb"), 19))
  210. .WillOnce(Return(0));
  211. EXPECT_CALL(mock, mysql_store_result(reinterpret_cast<MYSQL*>(0x6818)))
  212. .WillOnce(Return(reinterpret_cast<MYSQL_RES*>(0x8888)));
  213. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x8888)))
  214. .Times(1);
  215. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x6818)))
  216. .Times(1);
  217. connection con(reinterpret_cast<MYSQL*>(0x6818));
  218. auto ret = con.execute_stored("SELECT * FROM blubb");
  219. EXPECT_EQ (ret, con.result());
  220. ASSERT_TRUE(static_cast<bool>(ret));
  221. EXPECT_EQ (reinterpret_cast<MYSQL_RES*>(0x8888), ret->get_handle());
  222. }
  223. /**********************************************************************************************************/
  224. TEST(MariaDbTests, Connection_executeUsed_queryFailed)
  225. {
  226. StrictMock<MariaDbMock> mock;
  227. EXPECT_CALL(mock, mysql_errno(_)).Times(AnyNumber());
  228. EXPECT_CALL(mock, mysql_error(_)).Times(AnyNumber());
  229. InSequence seq;
  230. EXPECT_CALL(mock, mysql_real_query(reinterpret_cast<MYSQL*>(0x6818), StrEq("SELECT * FROM blubb"), 19))
  231. .WillOnce(Return(1));
  232. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x6818)))
  233. .Times(1);
  234. connection con(reinterpret_cast<MYSQL*>(0x6818));
  235. EXPECT_THROW(con.execute_used("SELECT * FROM blubb"), ::cppmariadb::exception);
  236. }
  237. TEST(MariaDbTests, Connection_executeused_useResultFailed_fieldCountGreaterZero)
  238. {
  239. StrictMock<MariaDbMock> mock;
  240. EXPECT_CALL(mock, mysql_errno(_)).Times(AnyNumber());
  241. EXPECT_CALL(mock, mysql_error(_)).Times(AnyNumber());
  242. InSequence seq;
  243. EXPECT_CALL(mock, mysql_real_query(reinterpret_cast<MYSQL*>(0x6818), StrEq("SELECT * FROM blubb"), 19))
  244. .WillOnce(Return(0));
  245. EXPECT_CALL(mock, mysql_use_result(reinterpret_cast<MYSQL*>(0x6818)))
  246. .WillOnce(Return(nullptr));
  247. EXPECT_CALL(mock, mysql_field_count(reinterpret_cast<MYSQL*>(0x6818)))
  248. .WillOnce(Return(5));
  249. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x6818)))
  250. .Times(1);
  251. connection con(reinterpret_cast<MYSQL*>(0x6818));
  252. EXPECT_THROW(con.execute_used("SELECT * FROM blubb"), ::cppmariadb::exception);
  253. }
  254. TEST(MariaDbTests, Connection_executeUsed_useResultFailed_fieldCountIsZero)
  255. {
  256. StrictMock<MariaDbMock> mock;
  257. EXPECT_CALL(mock, mysql_errno(_)).Times(AnyNumber());
  258. EXPECT_CALL(mock, mysql_error(_)).Times(AnyNumber());
  259. InSequence seq;
  260. EXPECT_CALL(mock, mysql_real_query(reinterpret_cast<MYSQL*>(0x6818), StrEq("SELECT * FROM blubb"), 19))
  261. .WillOnce(Return(0));
  262. EXPECT_CALL(mock, mysql_use_result(reinterpret_cast<MYSQL*>(0x6818)))
  263. .WillOnce(Return(nullptr));
  264. EXPECT_CALL(mock, mysql_field_count(reinterpret_cast<MYSQL*>(0x6818)))
  265. .WillOnce(Return(0));
  266. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x6818)))
  267. .Times(1);
  268. connection con(reinterpret_cast<MYSQL*>(0x6818));
  269. con.execute_used("SELECT * FROM blubb");
  270. ASSERT_FALSE(static_cast<bool>(con.result()));
  271. }
  272. TEST(MariaDbTests, Connection_executeUsed_success)
  273. {
  274. StrictMock<MariaDbMock> mock;
  275. EXPECT_CALL(mock, mysql_errno(_)).Times(AnyNumber());
  276. EXPECT_CALL(mock, mysql_error(_)).Times(AnyNumber());
  277. InSequence seq;
  278. EXPECT_CALL(mock, mysql_real_query(reinterpret_cast<MYSQL*>(0x6818), StrEq("SELECT * FROM blubb"), 19))
  279. .WillOnce(Return(0));
  280. EXPECT_CALL(mock, mysql_use_result(reinterpret_cast<MYSQL*>(0x6818)))
  281. .WillOnce(Return(reinterpret_cast<MYSQL_RES*>(0x8888)));
  282. EXPECT_CALL(mock, mysql_fetch_row(reinterpret_cast<MYSQL_RES*>(0x8888)))
  283. .WillOnce(Return(nullptr));
  284. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x8888)))
  285. .Times(1);
  286. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x6818)))
  287. .Times(1);
  288. connection con(reinterpret_cast<MYSQL*>(0x6818));
  289. auto ret = con.execute_used("SELECT * FROM blubb");
  290. EXPECT_EQ (ret, con.result());
  291. ASSERT_TRUE(static_cast<bool>(ret));
  292. EXPECT_EQ (reinterpret_cast<MYSQL_RES*>(0x8888), ret->get_handle());
  293. }
  294. /**********************************************************************************************************/
  295. TEST(MariaDbTests, Statement_set_validIndex)
  296. {
  297. StrictMock<MariaDbMock> mock;
  298. statement s("SELECT * FROM ?table?");
  299. EXPECT_NO_THROW(s.set(0, "test"));
  300. }
  301. TEST(MariaDbTests, Statement_set_invalidIndex)
  302. {
  303. StrictMock<MariaDbMock> mock;
  304. statement s("SELECT * FROM ?table?");
  305. EXPECT_THROW(s.set(4, "test"), ::cppmariadb::exception);
  306. }
  307. TEST(MariaDbTests, Statement_set_validName)
  308. {
  309. StrictMock<MariaDbMock> mock;
  310. statement s("SELECT * FROM ?table?");
  311. EXPECT_NO_THROW(s.set("table", "test"));
  312. }
  313. TEST(MariaDbTests, Statement_set_invalidName)
  314. {
  315. StrictMock<MariaDbMock> mock;
  316. statement s("SELECT * FROM ?table?");
  317. EXPECT_THROW(s.set("foo", "test"), ::cppmariadb::exception);
  318. }
  319. TEST(MariaDbTests, Statement_query)
  320. {
  321. StrictMock<MariaDbMock> mock;
  322. EXPECT_CALL(mock, mysql_real_escape_string(reinterpret_cast<MYSQL*>(0x123), _, StrEq("test"), 4))
  323. .WillOnce(DoAll(
  324. WithArgs<1>(Invoke([](char* str){
  325. memcpy(str, "test", 4);
  326. })),
  327. Return(4)));
  328. EXPECT_CALL(mock, mysql_close(reinterpret_cast<MYSQL*>(0x123)))
  329. .Times(1);
  330. connection c(reinterpret_cast<MYSQL*>(0x123));
  331. statement s("SELECT * FROM ?table?");
  332. s.set("table", "test");
  333. auto ret = s.query(c);
  334. EXPECT_EQ(std::string("SELECT * FROM 'test'"), ret);
  335. }
  336. /**********************************************************************************************************/
  337. TEST(MariaDbTests, Result_rowindex_next_current)
  338. {
  339. StrictMock<MariaDbMock> mock;
  340. InSequence seq;
  341. EXPECT_CALL(mock, mysql_fetch_row(reinterpret_cast<MYSQL_RES*>(0x51651)))
  342. .WillOnce(Return(reinterpret_cast<MYSQL_ROW>(0x15160)))
  343. .WillOnce(Return(reinterpret_cast<MYSQL_ROW>(0x15161)));
  344. EXPECT_CALL(mock, mysql_data_seek(reinterpret_cast<MYSQL_RES*>(0x51651), 0))
  345. .Times(1);
  346. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x51651)))
  347. .Times(1);
  348. result_stored result(reinterpret_cast<MYSQL_RES*>(0x51651));
  349. EXPECT_EQ(-1, result.rowindex());
  350. auto row = result.next();
  351. ASSERT_TRUE(static_cast<bool>(row));
  352. EXPECT_EQ (reinterpret_cast<MYSQL_ROW>(0x15160), row->get_handle());
  353. EXPECT_EQ (0, result.rowindex());
  354. row = result.next();
  355. ASSERT_TRUE(static_cast<bool>(row));
  356. EXPECT_EQ (reinterpret_cast<MYSQL_ROW>(0x15161), row->get_handle());
  357. EXPECT_EQ (1, result.rowindex());
  358. auto current = result.current();
  359. EXPECT_EQ(row, current);
  360. result.rowindex(0);
  361. EXPECT_EQ(0, result.rowindex());
  362. }
  363. TEST(MariaDbTests, Result_columncount)
  364. {
  365. StrictMock<MariaDbMock> mock;
  366. InSequence seq;
  367. EXPECT_CALL(mock, mysql_num_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  368. .WillOnce(Return(10));
  369. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x51651)))
  370. .Times(1);
  371. result_stored result(reinterpret_cast<MYSQL_RES*>(0x51651));
  372. auto ret = result.columncount();
  373. EXPECT_EQ(10, ret);
  374. }
  375. TEST(MariaDbTests, Result_columns)
  376. {
  377. static const std::string name0 ("index");
  378. static const std::string name1 ("username");
  379. static const std::string name2 ("password");
  380. static const std::string table ("user");
  381. static const std::string database ("database");
  382. MYSQL_FIELD fields[3];
  383. fields[0].name = const_cast<char*>(name0.c_str());
  384. fields[0].org_name = const_cast<char*>(name0.c_str());
  385. fields[0].table = const_cast<char*>(table.c_str());
  386. fields[0].org_table = const_cast<char*>(table.c_str());
  387. fields[0].db = const_cast<char*>(database.c_str());
  388. fields[0].catalog = nullptr;
  389. fields[0].def = nullptr;
  390. fields[0].length = 32;
  391. fields[0].max_length = 2;
  392. fields[0].name_length = static_cast<unsigned int>(name0.size());
  393. fields[0].org_name_length = static_cast<unsigned int>(name0.size());
  394. fields[0].table_length = static_cast<unsigned int>(table.size());
  395. fields[0].org_table_length = static_cast<unsigned int>(table.size());
  396. fields[0].db_length = static_cast<unsigned int>(database.size());
  397. fields[0].catalog_length = 0;
  398. fields[0].def_length = 0;
  399. fields[0].flags = 0;
  400. fields[0].decimals = 0;
  401. fields[0].charsetnr = 0;
  402. fields[0].type = MYSQL_TYPE_LONG;
  403. fields[0].extension = nullptr;
  404. fields[1].name = const_cast<char*>(name1.c_str());
  405. fields[1].org_name = const_cast<char*>(name1.c_str());
  406. fields[1].table = const_cast<char*>(table.c_str());
  407. fields[1].org_table = const_cast<char*>(table.c_str());
  408. fields[1].db = const_cast<char*>(database.c_str());
  409. fields[1].catalog = nullptr;
  410. fields[1].def = nullptr;
  411. fields[1].length = 128;
  412. fields[1].max_length = 48;
  413. fields[1].name_length = static_cast<unsigned int>(name1.size());
  414. fields[1].org_name_length = static_cast<unsigned int>(name1.size());
  415. fields[1].table_length = static_cast<unsigned int>(table.size());
  416. fields[1].org_table_length = static_cast<unsigned int>(table.size());
  417. fields[1].db_length = static_cast<unsigned int>(database.size());
  418. fields[1].catalog_length = 0;
  419. fields[1].def_length = 0;
  420. fields[1].flags = 0;
  421. fields[1].decimals = 0;
  422. fields[1].charsetnr = 0;
  423. fields[1].type = MYSQL_TYPE_STRING;
  424. fields[1].extension = nullptr;
  425. fields[2].name = const_cast<char*>(name2.c_str());
  426. fields[2].org_name = const_cast<char*>(name2.c_str());
  427. fields[2].table = const_cast<char*>(table.c_str());
  428. fields[2].org_table = const_cast<char*>(table.c_str());
  429. fields[2].db = const_cast<char*>(database.c_str());
  430. fields[2].catalog = nullptr;
  431. fields[2].def = nullptr;
  432. fields[2].length = 128;
  433. fields[2].max_length = 42;
  434. fields[2].name_length = static_cast<unsigned int>(name2.size());
  435. fields[2].org_name_length = static_cast<unsigned int>(name2.size());
  436. fields[2].table_length = static_cast<unsigned int>(table.size());
  437. fields[2].org_table_length = static_cast<unsigned int>(table.size());
  438. fields[2].db_length = static_cast<unsigned int>(database.size());
  439. fields[2].catalog_length = 0;
  440. fields[2].def_length = 0;
  441. fields[2].flags = 0;
  442. fields[2].decimals = 0;
  443. fields[2].charsetnr = 0;
  444. fields[2].type = MYSQL_TYPE_STRING;
  445. fields[2].extension = nullptr;
  446. StrictMock<MariaDbMock> mock;
  447. InSequence seq;
  448. EXPECT_CALL(mock, mysql_fetch_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  449. .WillOnce(Return(fields));
  450. EXPECT_CALL(mock, mysql_num_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  451. .WillOnce(Return(3));
  452. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x51651)))
  453. .Times(1);
  454. result_stored result(reinterpret_cast<MYSQL_RES*>(0x51651));
  455. auto ret = result.columns();
  456. ASSERT_EQ(3, ret.size());
  457. EXPECT_EQ(name0, ret.at(0).name);
  458. EXPECT_EQ(name0, ret.at(0).original_name);
  459. EXPECT_EQ(table, ret.at(0).table);
  460. EXPECT_EQ(table, ret.at(0).original_table);
  461. EXPECT_EQ(database, ret.at(0).database);
  462. EXPECT_EQ(32, ret.at(0).length);
  463. EXPECT_EQ(2, ret.at(0).max_length);
  464. EXPECT_EQ(column_flags::empty(), ret.at(0).flags);
  465. EXPECT_EQ(0, ret.at(0).decimals);
  466. EXPECT_EQ(0, ret.at(0).charset_number);
  467. EXPECT_EQ(column_type::Long, ret.at(0).type);
  468. EXPECT_EQ(name1, ret.at(1).name);
  469. EXPECT_EQ(name1, ret.at(1).original_name);
  470. EXPECT_EQ(table, ret.at(1).table);
  471. EXPECT_EQ(table, ret.at(1).original_table);
  472. EXPECT_EQ(database, ret.at(1).database);
  473. EXPECT_EQ(128, ret.at(1).length);
  474. EXPECT_EQ(48, ret.at(1).max_length);
  475. EXPECT_EQ(column_flags::empty(), ret.at(1).flags);
  476. EXPECT_EQ(0, ret.at(1).decimals);
  477. EXPECT_EQ(0, ret.at(1).charset_number);
  478. EXPECT_EQ(column_type::String, ret.at(1).type);
  479. EXPECT_EQ(name2, ret.at(2).name);
  480. EXPECT_EQ(name2, ret.at(2).original_name);
  481. EXPECT_EQ(table, ret.at(2).table);
  482. EXPECT_EQ(table, ret.at(2).original_table);
  483. EXPECT_EQ(database, ret.at(2).database);
  484. EXPECT_EQ(128, ret.at(2).length);
  485. EXPECT_EQ(42, ret.at(2).max_length);
  486. EXPECT_EQ(column_flags::empty(), ret.at(2).flags);
  487. EXPECT_EQ(0, ret.at(2).decimals);
  488. EXPECT_EQ(0, ret.at(2).charset_number);
  489. EXPECT_EQ(column_type::String, ret.at(2).type);
  490. }
  491. /**********************************************************************************************************/
  492. TEST(MariaDbTests, StoredResult_rowcount)
  493. {
  494. StrictMock<MariaDbMock> mock;
  495. InSequence seq;
  496. EXPECT_CALL(mock, mysql_num_rows(reinterpret_cast<MYSQL_RES*>(0x51651)))
  497. .WillOnce(Return(100));
  498. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x51651)))
  499. .Times(1);
  500. result_stored result(reinterpret_cast<MYSQL_RES*>(0x51651));
  501. auto ret = result.rowcount();
  502. EXPECT_EQ(100, ret);
  503. }
  504. /**********************************************************************************************************/
  505. TEST(MariaDbTests, UsedResult_dtor)
  506. {
  507. StrictMock<MariaDbMock> mock;
  508. InSequence seq;
  509. EXPECT_CALL(mock, mysql_fetch_row(reinterpret_cast<MYSQL_RES*>(0x51651)))
  510. .WillOnce(Return(reinterpret_cast<MYSQL_ROW>(0x0001)))
  511. .WillOnce(Return(reinterpret_cast<MYSQL_ROW>(0x0002)))
  512. .WillOnce(Return(reinterpret_cast<MYSQL_ROW>(0x0003)))
  513. .WillOnce(Return(reinterpret_cast<MYSQL_ROW>(0x0004)))
  514. .WillOnce(Return(nullptr));
  515. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x51651)))
  516. .Times(1);
  517. result_used result(reinterpret_cast<MYSQL_RES*>(0x51651));
  518. }
  519. /**********************************************************************************************************/
  520. static const char* RowData[3] =
  521. {
  522. "2",
  523. "bergmann89",
  524. "secret"
  525. };
  526. static unsigned long RowLengths[3] =
  527. {
  528. 1,
  529. 10,
  530. 6
  531. };
  532. TEST(MariaDbTests, Row_columns)
  533. {
  534. StrictMock<MariaDbMock> mock;
  535. InSequence seq;
  536. EXPECT_CALL(mock, mysql_fetch_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  537. .WillOnce(Return(nullptr));
  538. EXPECT_CALL(mock, mysql_num_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  539. .WillOnce(Return(0));
  540. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x51651)))
  541. .Times(1);
  542. result_stored result(reinterpret_cast<MYSQL_RES*>(0x51651));
  543. row row(result, const_cast<MYSQL_ROW>(&RowData[0]));
  544. row.columns();
  545. }
  546. TEST(MariaDbTests, Row_size)
  547. {
  548. StrictMock<MariaDbMock> mock;
  549. InSequence seq;
  550. EXPECT_CALL(mock, mysql_num_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  551. .WillOnce(Return(3));
  552. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x51651)))
  553. .Times(1);
  554. result_stored result(reinterpret_cast<MYSQL_RES*>(0x51651));
  555. row row(result, const_cast<MYSQL_ROW>(&RowData[0]));
  556. auto ret = row.size();
  557. EXPECT_EQ(3u, ret);
  558. }
  559. TEST(MariaDbTests, Row_at_invalidIndex)
  560. {
  561. StrictMock<MariaDbMock> mock;
  562. InSequence seq;
  563. EXPECT_CALL(mock, mysql_num_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  564. .WillOnce(Return(3));
  565. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x51651)))
  566. .Times(1);
  567. result_stored result(reinterpret_cast<MYSQL_RES*>(0x51651));
  568. row row(result, const_cast<MYSQL_ROW>(&RowData[0]));
  569. EXPECT_THROW(row.at(3), ::cppmariadb::exception);
  570. }
  571. TEST(MariaDbTests, Row_at_validIndex)
  572. {
  573. StrictMock<MariaDbMock> mock;
  574. InSequence seq;
  575. EXPECT_CALL(mock, mysql_num_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  576. .WillOnce(Return(3));
  577. EXPECT_CALL(mock, mysql_fetch_lengths(reinterpret_cast<MYSQL_RES*>(0x51651)))
  578. .WillOnce(Return(&RowLengths[0]));
  579. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x51651)))
  580. .Times(1);
  581. result_stored result(reinterpret_cast<MYSQL_RES*>(0x51651));
  582. row row(result, const_cast<MYSQL_ROW>(&RowData[0]));
  583. EXPECT_NO_THROW(row.at(1));
  584. }
  585. static const std::string RowDataName0("index");
  586. static const std::string RowDataName1("username");
  587. static const std::string RowDataName2("password");
  588. TEST(MariaDbTests, Row_at_invalidName)
  589. {
  590. MYSQL_FIELD fields[3];
  591. memset(&fields[0], 0, sizeof(fields));
  592. fields[0].name = const_cast<char*>(RowDataName0.c_str());
  593. fields[0].name_length = static_cast<unsigned int>(RowDataName0.size());
  594. fields[1].name = const_cast<char*>(RowDataName1.c_str());
  595. fields[1].name_length = static_cast<unsigned int>(RowDataName1.size());
  596. fields[2].name = const_cast<char*>(RowDataName2.c_str());
  597. fields[2].name_length = static_cast<unsigned int>(RowDataName2.size());
  598. StrictMock<MariaDbMock> mock;
  599. InSequence seq;
  600. EXPECT_CALL(mock, mysql_fetch_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  601. .WillOnce(Return(fields));
  602. EXPECT_CALL(mock, mysql_num_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  603. .WillOnce(Return(3));
  604. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x51651)))
  605. .Times(1);
  606. result_stored result(reinterpret_cast<MYSQL_RES*>(0x51651));
  607. row row(result, const_cast<MYSQL_ROW>(&RowData[0]));
  608. EXPECT_THROW(row.at("blubb"), ::cppmariadb::exception);
  609. }
  610. TEST(MariaDbTests, Row_at_validName)
  611. {
  612. MYSQL_FIELD fields[3];
  613. memset(&fields[0], 0, sizeof(fields));
  614. fields[0].name = const_cast<char*>(RowDataName0.c_str());
  615. fields[0].name_length = static_cast<unsigned int>(RowDataName0.size());
  616. fields[1].name = const_cast<char*>(RowDataName1.c_str());
  617. fields[1].name_length = static_cast<unsigned int>(RowDataName1.size());
  618. fields[2].name = const_cast<char*>(RowDataName2.c_str());
  619. fields[2].name_length = static_cast<unsigned int>(RowDataName2.size());
  620. StrictMock<MariaDbMock> mock;
  621. InSequence seq;
  622. EXPECT_CALL(mock, mysql_fetch_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  623. .WillOnce(Return(fields));
  624. EXPECT_CALL(mock, mysql_num_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  625. .WillRepeatedly(Return(3));
  626. EXPECT_CALL(mock, mysql_fetch_lengths(reinterpret_cast<MYSQL_RES*>(0x51651)))
  627. .WillOnce(Return(&RowLengths[0]));
  628. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x51651)))
  629. .Times(1);
  630. result_stored result(reinterpret_cast<MYSQL_RES*>(0x51651));
  631. row row(result, const_cast<MYSQL_ROW>(&RowData[0]));
  632. EXPECT_NO_THROW(row.at("username"));
  633. }
  634. TEST(MariaDbTests, Row_iterator)
  635. {
  636. StrictMock<MariaDbMock> mock;
  637. InSequence seq;
  638. EXPECT_CALL(mock, mysql_num_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  639. .WillRepeatedly(Return(3));
  640. EXPECT_CALL(mock, mysql_fetch_lengths(reinterpret_cast<MYSQL_RES*>(0x51651)))
  641. .WillRepeatedly(Return(&RowLengths[0]));
  642. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x51651)))
  643. .Times(1);
  644. result_stored result(reinterpret_cast<MYSQL_RES*>(0x51651));
  645. row row(result, const_cast<MYSQL_ROW>(&RowData[0]));
  646. auto it = row.begin();
  647. ASSERT_TRUE(it != row.end());
  648. ++it;
  649. ASSERT_TRUE(it != row.end());
  650. ++it;
  651. ASSERT_TRUE(it != row.end());
  652. ++it;
  653. ASSERT_TRUE(it == row.end());
  654. }
  655. TEST(MariaDbTests, Row_const_iterator)
  656. {
  657. StrictMock<MariaDbMock> mock;
  658. InSequence seq;
  659. EXPECT_CALL(mock, mysql_num_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  660. .WillRepeatedly(Return(3));
  661. EXPECT_CALL(mock, mysql_fetch_lengths(reinterpret_cast<MYSQL_RES*>(0x51651)))
  662. .WillRepeatedly(Return(&RowLengths[0]));
  663. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x51651)))
  664. .Times(1);
  665. result_stored result(reinterpret_cast<MYSQL_RES*>(0x51651));
  666. row row(result, const_cast<MYSQL_ROW>(&RowData[0]));
  667. auto it = row.cbegin();
  668. ASSERT_TRUE(it != row.cend());
  669. ++it;
  670. ASSERT_TRUE(it != row.cend());
  671. ++it;
  672. ASSERT_TRUE(it != row.cend());
  673. ++it;
  674. ASSERT_TRUE(it == row.cend());
  675. }
  676. TEST(MariaDbTests, Row_reverse_iterator)
  677. {
  678. StrictMock<MariaDbMock> mock;
  679. InSequence seq;
  680. EXPECT_CALL(mock, mysql_num_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  681. .WillRepeatedly(Return(3));
  682. EXPECT_CALL(mock, mysql_fetch_lengths(reinterpret_cast<MYSQL_RES*>(0x51651)))
  683. .WillRepeatedly(Return(&RowLengths[0]));
  684. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x51651)))
  685. .Times(1);
  686. result_stored result(reinterpret_cast<MYSQL_RES*>(0x51651));
  687. row row(result, const_cast<MYSQL_ROW>(&RowData[0]));
  688. auto it = row.rbegin();
  689. ASSERT_TRUE(it != row.rend());
  690. ++it;
  691. ASSERT_TRUE(it != row.rend());
  692. ++it;
  693. ASSERT_TRUE(it != row.rend());
  694. ++it;
  695. ASSERT_TRUE(it == row.rend());
  696. }
  697. TEST(MariaDbTests, Row_const_reverse_iterator)
  698. {
  699. StrictMock<MariaDbMock> mock;
  700. InSequence seq;
  701. EXPECT_CALL(mock, mysql_num_fields(reinterpret_cast<MYSQL_RES*>(0x51651)))
  702. .WillRepeatedly(Return(3));
  703. EXPECT_CALL(mock, mysql_fetch_lengths(reinterpret_cast<MYSQL_RES*>(0x51651)))
  704. .WillRepeatedly(Return(&RowLengths[0]));
  705. EXPECT_CALL(mock, mysql_free_result(reinterpret_cast<MYSQL_RES*>(0x51651)))
  706. .Times(1);
  707. result_stored result(reinterpret_cast<MYSQL_RES*>(0x51651));
  708. row row(result, const_cast<MYSQL_ROW>(&RowData[0]));
  709. auto it = row.crbegin();
  710. ASSERT_TRUE(it != row.crend());
  711. ++it;
  712. ASSERT_TRUE(it != row.crend());
  713. ++it;
  714. ASSERT_TRUE(it != row.crend());
  715. ++it;
  716. ASSERT_TRUE(it == row.crend());
  717. }
  718. /**********************************************************************************************************/
  719. TEST(MariaDbTests, Field_index)
  720. {
  721. cppmariadb::result_stored result (reinterpret_cast<MYSQL_RES*>(0x51651));
  722. cppmariadb::row row (result, const_cast<MYSQL_ROW>(&RowData[0]));
  723. cppmariadb::field field (row, 1, RowData[1], RowLengths[1]);
  724. EXPECT_EQ(1, field.index());
  725. }
  726. TEST(MariaDbTests, Field_isNull)
  727. {
  728. cppmariadb::result_stored result (reinterpret_cast<MYSQL_RES*>(0x51651));
  729. cppmariadb::row row (result, const_cast<MYSQL_ROW>(&RowData[0]));
  730. cppmariadb::field field0 (row, 1, nullptr, 0);
  731. cppmariadb::field field1 (row, 1, "", 0);
  732. cppmariadb::field field2 (row, 1, "asd", 3);
  733. EXPECT_TRUE (field0.is_null());
  734. EXPECT_FALSE(field1.is_null());
  735. EXPECT_FALSE(field2.is_null());
  736. }
  737. TEST(MariaDbTests, Field_isEmpty)
  738. {
  739. cppmariadb::result_stored result (reinterpret_cast<MYSQL_RES*>(0x51651));
  740. cppmariadb::row row (result, const_cast<MYSQL_ROW>(&RowData[0]));
  741. cppmariadb::field field0 (row, 1, nullptr, 0);
  742. cppmariadb::field field1 (row, 1, "", 0);
  743. cppmariadb::field field2 (row, 1, "asd", 3);
  744. EXPECT_TRUE (field0.is_empty());
  745. EXPECT_TRUE (field1.is_empty());
  746. EXPECT_FALSE(field2.is_empty());
  747. }
  748. TEST(MariaDbTests, Field_data)
  749. {
  750. static const char* data = "test";
  751. cppmariadb::result_stored result (reinterpret_cast<MYSQL_RES*>(0x51651));
  752. cppmariadb::row row (result, const_cast<MYSQL_ROW>(&RowData[0]));
  753. cppmariadb::field field (row, 1, data, 4);
  754. EXPECT_EQ(data, field.data());
  755. }
  756. TEST(MariaDbTests, Field_size)
  757. {
  758. static const char* data = "test";
  759. cppmariadb::result_stored result (reinterpret_cast<MYSQL_RES*>(0x51651));
  760. cppmariadb::row row (result, const_cast<MYSQL_ROW>(&RowData[0]));
  761. cppmariadb::field field (row, 1, data, 4);
  762. EXPECT_EQ(4, field.size());
  763. }
  764. TEST(MariaDbTests, Field_implicit_bool_cast)
  765. {
  766. cppmariadb::result_stored result (reinterpret_cast<MYSQL_RES*>(0x51651));
  767. cppmariadb::row row (result, const_cast<MYSQL_ROW>(&RowData[0]));
  768. cppmariadb::field field0 (row, 1, nullptr, 0);
  769. cppmariadb::field field1 (row, 1, "", 0);
  770. cppmariadb::field field2 (row, 1, "asd", 3);
  771. EXPECT_FALSE(static_cast<bool>(field0));
  772. EXPECT_FALSE(static_cast<bool>(field1));
  773. EXPECT_TRUE (static_cast<bool>(field2));
  774. }
  775. TEST(MariaDbTests, Field_get)
  776. {
  777. cppmariadb::result_stored result (reinterpret_cast<MYSQL_RES*>(0x51651));
  778. cppmariadb::row row (result, const_cast<MYSQL_ROW>(&RowData[0]));
  779. cppmariadb::field field0 (row, 1, "123", 3);
  780. cppmariadb::field field1 (row, 1, "asd", 3);
  781. EXPECT_EQ(123, field0.get<int>());
  782. EXPECT_EQ(std::string("asd"), field1.get<std::string>());
  783. }