C++DB is the database layer that was designed to work with C++CMS. This customized version is used within Ye Ol' Pi Shack.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

751 lines
20 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2010-2011 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
  4. //
  5. // Distributed under:
  6. //
  7. // the Boost Software License, Version 1.0.
  8. // (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // or (at your opinion) under:
  12. //
  13. // The MIT License
  14. // (See accompanying file MIT.txt or a copy at
  15. // http://www.opensource.org/licenses/mit-license.php)
  16. //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #include <cppdb/backend.h>
  19. #include <cppdb/driver_manager.h>
  20. #include <sstream>
  21. #include <iostream>
  22. #include <stdexcept>
  23. #include <memory>
  24. #include <stdlib.h>
  25. #include "test.h"
  26. bool test_64bit_integer = true;
  27. bool test_blob = true;
  28. bool wide_api = false;
  29. bool pq_oid = false;
  30. int sizes[]={ 0, // General 0 length string
  31. 61,62,63,64,65,66,67, // mysql buffer size
  32. 510,511,512,513,514, // ODBC buffer size in wchars
  33. 1020,1021,1022,1023,1024,1025,1026,1027, // ODBC buffer size
  34. 4094,4095,4096,4097,4098// postgresql driver buffer size for LO
  35. };
  36. /*
  37. void test_template(cppdb::ref_ptr<cppdb::backend::connection> sql)
  38. {
  39. cppdb::ref_ptr<cppdb::backend::statement> stmt;
  40. cppdb::ref_ptr<cppdb::backend::result> res;
  41. }
  42. */
  43. void test1(cppdb::ref_ptr<cppdb::backend::connection> sql)
  44. {
  45. cppdb::ref_ptr<cppdb::backend::statement> stmt;
  46. cppdb::ref_ptr<cppdb::backend::result> res;
  47. try {
  48. stmt = sql->prepare("drop table test");
  49. stmt->exec();
  50. }catch(...) {}
  51. if(sql->engine()=="mssql" && wide_api) {
  52. stmt = sql->prepare("create table test ( x integer not null, y nvarchar(1000) )");
  53. }
  54. else
  55. stmt = sql->prepare("create table test ( x integer not null, y varchar(1000) )");
  56. std::cout << "Basic select " << std::endl;
  57. stmt->exec();
  58. stmt = sql->prepare("select * from test");
  59. res = stmt->query();
  60. TEST(!res->next());
  61. stmt = sql->prepare("insert into test(x,y) values(10,'foo?')");
  62. stmt->exec();
  63. stmt = sql->prepare("select x,y from test");
  64. res = stmt->query();
  65. TEST(res->next());
  66. TEST(res->cols()==2);
  67. int iv;
  68. std::string sv;
  69. TEST(res->fetch(0,iv));
  70. TEST(iv==10);
  71. TEST(res->fetch(1,sv));
  72. TEST(sv=="foo?");
  73. TEST(!res->next());
  74. res.reset();
  75. stmt = sql->prepare("insert into test(x,y) values(20,NULL)");
  76. stmt->exec();
  77. stmt = sql->prepare("select y from test where x=?");
  78. stmt->bind(1,20);
  79. res = stmt->query();
  80. TEST(res->next());
  81. TEST(res->is_null(0));
  82. sv="xxx";
  83. TEST(!res->fetch(0,sv));
  84. TEST(sv=="xxx");
  85. TEST(!res->next());
  86. res.reset();
  87. stmt->reset();
  88. stmt->bind(1,10);
  89. res = stmt->query();
  90. TEST(res->next());
  91. sv="";
  92. TEST(!res->is_null(0));
  93. TEST(res->fetch(0,sv));
  94. TEST(sv=="foo?");
  95. stmt = sql->prepare("DELETE FROM test");
  96. stmt->exec();
  97. std::cout << "Unicode Test" << std::endl;
  98. if(sql->engine()!="mssql" || wide_api) {
  99. std::string test_string = "Pease שלום Мир ﺱﻼﻣ";
  100. stmt = sql->prepare("insert into test(x,y) values(?,?)");
  101. stmt->bind(1,15);
  102. stmt->bind(2,test_string);
  103. stmt->exec();
  104. stmt = sql->prepare("select x,y from test");
  105. res = stmt->query();
  106. TEST(res->next());
  107. sv="";
  108. res->fetch(1,sv);
  109. TEST(sv==test_string);
  110. }
  111. else {
  112. std::cout << "This does not support unicode, skipping" << std::endl;
  113. }
  114. }
  115. void test2(cppdb::ref_ptr<cppdb::backend::connection> sql)
  116. {
  117. cppdb::ref_ptr<cppdb::backend::statement> stmt;
  118. cppdb::ref_ptr<cppdb::backend::result> res;
  119. try {
  120. stmt = sql->prepare("drop table test");
  121. stmt->exec();
  122. stmt.reset();
  123. }catch(...) {}
  124. stmt = 0;
  125. std::cout << "Testing sequences types" << std::endl;
  126. if(sql->engine() == "sqlite3") {
  127. stmt = sql->prepare("create table test ( id integer primary key autoincrement not null, n integer)");
  128. }
  129. else if(sql->engine() == "mysql") {
  130. stmt = sql->prepare("create table test ( id integer primary key auto_increment not null, n integer)");
  131. }
  132. else if(sql->engine() == "postgresql" ) {
  133. stmt = sql->prepare("create table test ( id serial primary key not null, n integer)");
  134. }
  135. else if(sql->engine() == "mssql" ) {
  136. stmt = sql->prepare("create table test ( id integer identity(1,1) primary key not null,n integer)");
  137. }
  138. if(stmt) {
  139. stmt->exec();
  140. stmt = sql->prepare("insert into test(n) values(?)");
  141. stmt->bind(1,10);
  142. stmt->exec();
  143. TEST(stmt->sequence_last("test_id_seq") == 1);
  144. stmt->reset();
  145. stmt->bind(1,20);
  146. stmt->exec();
  147. TEST(stmt->sequence_last("test_id_seq") == 2);
  148. stmt = sql->prepare("drop table test");
  149. stmt->exec();
  150. stmt.reset();
  151. }
  152. else {
  153. std::cout << "This engine " << sql->engine() << " does not support sequences, skipping" << std::endl;
  154. }
  155. }
  156. void test3(cppdb::ref_ptr<cppdb::backend::connection> sql)
  157. {
  158. cppdb::ref_ptr<cppdb::backend::statement> stmt;
  159. cppdb::ref_ptr<cppdb::backend::result> res;
  160. std::cout << "Testing data types" << std::endl;
  161. try {
  162. stmt = sql->prepare("drop table test");
  163. stmt->exec();
  164. stmt.reset();
  165. }catch(...) {}
  166. if(sql->engine() == "mssql")
  167. stmt = sql->prepare("create table test ( i bigint, r real, t datetime, s varchar(5000), bl varbinary(max))");
  168. else if(sql->engine() == "mysql")
  169. stmt = sql->prepare("create table test ( i bigint, r real, t datetime default null, s varchar(5000), bl blob) Engine = innodb");
  170. else if(sql->engine() == "postgresql") {
  171. if(pq_oid) {
  172. stmt = sql->prepare("create table test ( i bigint, r real, t timestamp, s varchar(5000), bl oid)");
  173. stmt->exec();
  174. stmt = sql->prepare( "CREATE TRIGGER t_test BEFORE UPDATE OR DELETE ON test "
  175. "FOR EACH ROW EXECUTE PROCEDURE lo_manage(bl)");
  176. }
  177. else {
  178. stmt = sql->prepare("create table test ( i bigint, r real, t timestamp, s varchar(5000), bl bytea)");
  179. }
  180. }
  181. else if(sql->engine() == "sqlite3") {
  182. stmt = sql->prepare("create table test ( i integer, r real, t timestamp, s varchar(5000), bl blob)");
  183. }
  184. else {
  185. test_64bit_integer = false;
  186. test_blob= false;
  187. stmt = sql->prepare("create table test ( i integer, r real, t timestamp, s varchar(5000))");
  188. }
  189. stmt->exec();
  190. if(sql->engine()=="mssql")
  191. stmt = sql->prepare("insert into test values(?,?,?,?,cast(? as varbinary(max)))");
  192. else if(test_blob)
  193. stmt = sql->prepare("insert into test values(?,?,?,?,?)");
  194. else
  195. stmt = sql->prepare("insert into test values(?,?,?,?)");
  196. stmt->bind_null(1);
  197. stmt->bind_null(2);
  198. stmt->bind_null(3);
  199. stmt->bind_null(4);
  200. if(test_blob)
  201. stmt->bind_null(5);
  202. stmt->exec();
  203. TEST(stmt->affected()==1);
  204. if(pq_oid) {
  205. sql->begin();
  206. }
  207. stmt->reset();
  208. stmt->bind(1,10);
  209. stmt->bind(2,3.14);
  210. std::time_t now=time(0);
  211. std::tm t=*std::localtime(&now);
  212. stmt->bind(3,t);
  213. stmt->bind(4,"'to be' \\'or not' to be");
  214. std::istringstream iss;
  215. iss.str(std::string("\xFF\0\xFE\1\2",5));
  216. if(test_blob)
  217. stmt->bind(5,iss);
  218. stmt->exec();
  219. if(pq_oid) {
  220. sql->commit();
  221. sql->begin();
  222. }
  223. if(test_blob)
  224. stmt = sql->prepare("select i,r,t,s,bl from test");
  225. else
  226. stmt = sql->prepare("select i,r,t,s from test");
  227. res = stmt->query();
  228. {
  229. TEST(res->cols()==test_blob ? 5 : 4);
  230. TEST(res->column_to_name(0)=="i");
  231. TEST(res->column_to_name(1)=="r");
  232. TEST(res->column_to_name(2)=="t");
  233. TEST(res->column_to_name(3)=="s");
  234. if(test_blob)
  235. TEST(res->column_to_name(4)=="bl");
  236. TEST(res->name_to_column("i")==0);
  237. TEST(res->name_to_column("r")==1);
  238. TEST(res->name_to_column("t")==2);
  239. TEST(res->name_to_column("s")==3);
  240. if(test_blob)
  241. TEST(res->name_to_column("bl")==4);
  242. TEST(res->name_to_column("x")==-1);
  243. TEST(res->next());
  244. std::ostringstream oss;
  245. int i=-1; double r=-1; std::tm t=std::tm(); std::string s="def";
  246. TEST(res->is_null(0));
  247. TEST(res->is_null(1));
  248. TEST(res->is_null(2));
  249. TEST(res->is_null(3));
  250. if(test_blob)
  251. TEST(res->is_null(4));
  252. TEST(!res->fetch(0,i));
  253. TEST(!res->fetch(1,r));
  254. TEST(!res->fetch(2,t));
  255. TEST(!res->fetch(3,s));
  256. if(test_blob)
  257. TEST(!res->fetch(4,oss));
  258. TEST(i==-1);
  259. TEST(r==-1);
  260. TEST(t.tm_year == 0);
  261. TEST(s=="def");
  262. TEST(oss.str()=="");
  263. TEST(res->has_next() == cppdb::backend::result::next_row_unknown || res->has_next() == cppdb::backend::result::next_row_exists);
  264. TEST(res->next());
  265. TEST(res->fetch(0,i));
  266. TEST(res->fetch(1,r));
  267. TEST(res->fetch(2,t));
  268. TEST(res->fetch(3,s));
  269. if(test_blob)
  270. TEST(res->fetch(4,oss));
  271. TEST(!res->is_null(0));
  272. TEST(!res->is_null(1));
  273. TEST(!res->is_null(2));
  274. TEST(!res->is_null(3));
  275. if(test_blob)
  276. TEST(!res->is_null(4));
  277. TEST(i==10);
  278. TEST(3.1399 <= r && r <= 3.1401);
  279. TEST(mktime(&t)==now);
  280. TEST(s=="'to be' \\'or not' to be");
  281. if(test_blob)
  282. TEST(oss.str() == std::string("\xFF\0\xFE\1\2",5));
  283. TEST(res->has_next() == cppdb::backend::result::next_row_unknown || res->has_next() == cppdb::backend::result::last_row_reached);
  284. TEST(!res->next());
  285. }
  286. if(pq_oid) {
  287. sql->commit();
  288. }
  289. stmt = sql->prepare("DELETE FROM test where 1<>0");
  290. stmt->exec();
  291. TEST(stmt->affected()==2);
  292. }
  293. void test4(cppdb::ref_ptr<cppdb::backend::connection> sql)
  294. {
  295. cppdb::ref_ptr<cppdb::backend::statement> stmt;
  296. cppdb::ref_ptr<cppdb::backend::result> res;
  297. std::cout << "Tesing transactions" << std::endl;
  298. stmt = sql->prepare("DELETE FROM test where 1<>0");
  299. stmt->exec();
  300. sql->begin();
  301. stmt = sql->prepare("insert into test(i) values(10)");
  302. stmt->exec();
  303. stmt = sql->prepare("insert into test(i) values(20)");
  304. stmt->exec();
  305. sql->commit();
  306. stmt = sql->prepare("select count(*) from test");
  307. res = stmt->query();
  308. TEST(res->next());
  309. int iv;
  310. TEST(res->fetch(0,iv) && iv==2);
  311. res.reset();
  312. stmt.reset();
  313. iv=-1;
  314. stmt = sql->prepare("DELETE FROM test where 1<>0");
  315. stmt->exec();
  316. sql->begin();
  317. stmt = sql->prepare("insert into test(i) values(10)");
  318. stmt->exec();
  319. stmt = sql->prepare("insert into test(i) values(20)");
  320. stmt->exec();
  321. sql->rollback();
  322. stmt = sql->prepare("select count(*) from test");
  323. res = stmt->query();
  324. TEST(res->next());
  325. iv=-1;
  326. TEST(res->fetch(0,iv));
  327. TEST(iv==0);
  328. stmt = sql->prepare("DELETE FROM test where 1<>0");
  329. stmt->exec();
  330. }
  331. void test5(cppdb::ref_ptr<cppdb::backend::connection> sql)
  332. {
  333. cppdb::ref_ptr<cppdb::backend::statement> stmt;
  334. cppdb::ref_ptr<cppdb::backend::result> res;
  335. std::cout << "Tesing variable length data handing: text" << std::endl;
  336. sql->begin();
  337. stmt = sql->prepare("insert into test(i,s) values(?,?)");
  338. for(unsigned i=0;i<sizeof(sizes)/sizeof(int);i++) {
  339. int size = sizes[i];
  340. std::string value;
  341. value.reserve(size);
  342. srand(i);
  343. for(int j=0;j<size;j++) {
  344. value+=char(rand() % 26 + 'a');
  345. }
  346. stmt->bind(1,size);
  347. stmt->bind(2,value);
  348. stmt->exec();
  349. stmt->reset();
  350. }
  351. sql->commit();
  352. stmt = sql->prepare("select s from test where i=?");
  353. for(unsigned i=0;i<sizeof(sizes)/sizeof(int);i++) {
  354. int size = sizes[i];
  355. std::string value;
  356. value.reserve(size);
  357. srand(i);
  358. for(int j=0;j<size;j++) {
  359. value+=char(rand() % 26 + 'a');
  360. }
  361. stmt->bind(1,size);
  362. res = stmt->query();
  363. TEST(res->next());
  364. std::string v;
  365. TEST(res->fetch(0,v));
  366. TEST(v==value);
  367. res.reset();
  368. stmt->reset();
  369. }
  370. stmt = sql->prepare("DELETE FROM test where 1<>0");
  371. stmt->exec();
  372. }
  373. void test6(cppdb::ref_ptr<cppdb::backend::connection> sql)
  374. {
  375. cppdb::ref_ptr<cppdb::backend::statement> stmt;
  376. cppdb::ref_ptr<cppdb::backend::result> res;
  377. if(test_blob) {
  378. std::cout << "Tesing variable length data handing: blob" << std::endl;
  379. sql->begin();
  380. if(sql->engine()=="mssql")
  381. stmt = sql->prepare("insert into test(i,bl) values(?,cast(? as varbinary(max)))");
  382. else
  383. stmt = sql->prepare("insert into test(i,bl) values(?,?)");
  384. for(unsigned i=0;i<sizeof(sizes)/sizeof(int);i++) {
  385. int size = sizes[i];
  386. std::stringstream value;
  387. srand(i);
  388. for(int j=0;j<size;j++) {
  389. value << char(rand() % 26 + 'a');
  390. }
  391. stmt->bind(1,size);
  392. stmt->bind(2,value);
  393. stmt->exec();
  394. stmt->reset();
  395. }
  396. sql->commit();
  397. stmt = sql->prepare("select bl from test where i=?");
  398. for(unsigned i=0;i<sizeof(sizes)/sizeof(int);i++) {
  399. int size = sizes[i];
  400. std::string value;
  401. value.reserve(size);
  402. srand(i);
  403. for(int j=0;j<size;j++) {
  404. value+=char(rand() % 26 + 'a');
  405. }
  406. if(pq_oid)
  407. sql->begin();
  408. stmt->bind(1,size);
  409. res = stmt->query();
  410. TEST(res->next());
  411. std::ostringstream v;
  412. TEST(res->fetch(0,v));
  413. TEST(v.str()==value);
  414. res.reset();
  415. stmt->reset();
  416. if(pq_oid)
  417. sql->commit();
  418. }
  419. }
  420. stmt = sql->prepare("DELETE FROM test where 1<>0");
  421. stmt->exec();
  422. }
  423. void test7(cppdb::ref_ptr<cppdb::backend::connection> sql)
  424. {
  425. cppdb::ref_ptr<cppdb::backend::statement> stmt;
  426. cppdb::ref_ptr<cppdb::backend::result> res;
  427. std::cout << "Testing integer ranges" << std::endl;
  428. {
  429. stmt=sql->prepare("delete from test");
  430. stmt->exec();
  431. std::cout << "- short" << std::endl;
  432. stmt=sql->prepare("insert into test(i) values(32768)");
  433. stmt->exec();
  434. stmt=sql->prepare("select i from test");
  435. res = stmt->query();
  436. res->next();
  437. short s=0;
  438. THROWS(res->fetch(0,s),cppdb::bad_value_cast);
  439. unsigned short us=0;
  440. TEST(res->fetch(0,us));
  441. TEST(us==32768);
  442. }
  443. if(test_64bit_integer) {
  444. stmt=sql->prepare("delete from test");
  445. stmt->exec();
  446. std::cout << "- int" << std::endl;
  447. stmt=sql->prepare("insert into test(i) values(2147483648)");
  448. stmt->exec();
  449. stmt=sql->prepare("select i from test");
  450. res = stmt->query();
  451. res->next();
  452. int i=0;
  453. THROWS(res->fetch(0,i),cppdb::bad_value_cast);
  454. unsigned ui=0;
  455. TEST(res->fetch(0,ui));
  456. TEST(ui==2147483648U);
  457. if(sizeof(long)==8) {
  458. long l=0;
  459. TEST(res->fetch(0,l));
  460. TEST(l==2147483648L);
  461. }
  462. long long ll=0;
  463. TEST(res->fetch(0,ll));
  464. TEST(ll==2147483648LL);
  465. }
  466. if(test_64bit_integer && sizeof(long)==4) {
  467. stmt=sql->prepare("delete from test");
  468. stmt->exec();
  469. std::cout << "- long" << std::endl;
  470. stmt=sql->prepare("insert into test(i) values(2147483648)");
  471. stmt->exec();
  472. stmt=sql->prepare("select i from test");
  473. res = stmt->query();
  474. res->next();
  475. long i=0;
  476. THROWS(res->fetch(0,i),cppdb::bad_value_cast);
  477. unsigned long ul=0;
  478. TEST(res->fetch(0,ul));
  479. TEST(ul==2147483648UL);
  480. long long ll=0;
  481. TEST(res->fetch(0,ll));
  482. TEST(ll==2147483648LL);
  483. }
  484. {
  485. stmt=sql->prepare("delete from test");
  486. stmt->exec();
  487. std::cout << "- unsigned short,int,long,long long" << std::endl;
  488. stmt=sql->prepare("insert into test(i) values(-1)");
  489. stmt->exec();
  490. stmt=sql->prepare("select i from test");
  491. res = stmt->query();
  492. res->next();
  493. unsigned short us=0;
  494. short s=0;
  495. unsigned ui=0;
  496. int i=0;
  497. unsigned long ul=0;
  498. long l=0;
  499. unsigned long long ull=0;
  500. long long ll=0;
  501. THROWS(res->fetch(0,us),cppdb::bad_value_cast);
  502. THROWS(res->fetch(0,ui),cppdb::bad_value_cast);
  503. THROWS(res->fetch(0,ul),cppdb::bad_value_cast);
  504. THROWS(res->fetch(0,ull),cppdb::bad_value_cast);
  505. TEST(res->fetch(0,s) && s==-1);
  506. TEST(res->fetch(0,i) && i==-1);
  507. TEST(res->fetch(0,l) && l==-1);
  508. TEST(res->fetch(0,ll) && ll==-1);
  509. }
  510. std::cout <<"Testing floating -> integer conversions" << std::endl;
  511. {
  512. stmt=sql->prepare("delete from test");
  513. stmt->exec();
  514. stmt=sql->prepare("insert into test(r) values(33000.11)");
  515. stmt->exec();
  516. stmt=sql->prepare("select r from test");
  517. res = stmt->query();
  518. res->next();
  519. int i=0;
  520. short s=0;
  521. TEST(res->fetch(0,i) && (i==33000 || i==33001));
  522. THROWS(res->fetch(0,s),cppdb::bad_value_cast);
  523. res.reset();
  524. stmt=sql->prepare("delete from test");
  525. stmt->exec();
  526. stmt=sql->prepare("insert into test(r) values(-1e12)");
  527. stmt->exec();
  528. long long ll = 0;
  529. unsigned long long ull;
  530. stmt=sql->prepare("select r from test");
  531. res = stmt->query();
  532. res->next();
  533. THROWS(res->fetch(0,i),cppdb::bad_value_cast);
  534. TEST(res->fetch(0,ll) && ll==-1000000000000LL);
  535. THROWS(res->fetch(0,ull),cppdb::bad_value_cast);
  536. }
  537. stmt=sql->prepare("delete from test");
  538. stmt->exec();
  539. }
  540. void test8(cppdb::ref_ptr<cppdb::backend::connection> sql)
  541. {
  542. cppdb::ref_ptr<cppdb::backend::statement> stmt;
  543. cppdb::ref_ptr<cppdb::backend::result> res;
  544. std::cout << "Testing conversions on fetch" << std::endl;
  545. {
  546. stmt=sql->prepare("delete from test");
  547. stmt->exec();
  548. std::cout << "- string to integer" << std::endl;
  549. stmt=sql->prepare("insert into test(s) values('10')");
  550. stmt->exec();
  551. stmt=sql->prepare("select s from test");
  552. res = stmt->query();
  553. res->next();
  554. int i=0;
  555. TEST(res->fetch(0,i));
  556. TEST(i==10);
  557. }
  558. {
  559. stmt=sql->prepare("delete from test");
  560. stmt->exec();
  561. std::cout << "- string to date-time" << std::endl;
  562. stmt=sql->prepare("insert into test(s) values('2008-02-03 11:22:33')");
  563. stmt->exec();
  564. stmt=sql->prepare("select s from test");
  565. res = stmt->query();
  566. res->next();
  567. std::tm t=std::tm();;
  568. TEST(res->fetch(0,t));
  569. TEST(t.tm_year == 2008 - 1900);
  570. TEST(t.tm_mon == 2 - 1);
  571. TEST(t.tm_mday == 3);
  572. TEST(t.tm_hour == 11);
  573. TEST(t.tm_min == 22);
  574. TEST(t.tm_sec == 33);
  575. }
  576. {
  577. stmt=sql->prepare("delete from test");
  578. stmt->exec();
  579. std::cout << "- integer to string" << std::endl;
  580. stmt=sql->prepare("insert into test(i) values(10)");
  581. stmt->exec();
  582. stmt=sql->prepare("select i from test");
  583. res = stmt->query();
  584. res->next();
  585. int i=0;
  586. TEST(res->fetch(0,i));
  587. TEST(i==10);
  588. }
  589. }
  590. void test9(cppdb::ref_ptr<cppdb::backend::connection> sql)
  591. {
  592. cppdb::ref_ptr<cppdb::backend::statement> stmt;
  593. cppdb::ref_ptr<cppdb::backend::result> res;
  594. std::cout << "Testing conversions on bind" << std::endl;
  595. {
  596. stmt=sql->prepare("delete from test");
  597. stmt->exec();
  598. std::cout << "- integer to string" << std::endl;
  599. stmt=sql->prepare("insert into test(s) values(?)");
  600. stmt->bind(1,10);
  601. stmt->exec();
  602. stmt=sql->prepare("select s from test");
  603. res = stmt->query();
  604. res->next();
  605. std::string s;
  606. TEST(res->fetch(0,s));
  607. TEST(s=="10");
  608. }
  609. if(sql->engine()!="mssql") {
  610. stmt=sql->prepare("delete from test");
  611. stmt->exec();
  612. std::tm t=std::tm();;
  613. t.tm_year = 2008 - 1900;
  614. t.tm_mon = 2 - 1;
  615. t.tm_mday = 3;
  616. t.tm_hour = 11;
  617. t.tm_min = 22;
  618. t.tm_sec = 33;
  619. mktime(&t);
  620. std::cout << "- date-time to string" << std::endl;
  621. stmt=sql->prepare("insert into test(s) values(?)");
  622. stmt->bind(1,t);
  623. stmt->exec();
  624. stmt=sql->prepare("select s from test");
  625. res = stmt->query();
  626. res->next();
  627. std::string s;
  628. TEST(res->fetch(0,s));
  629. TEST(s=="2008-02-03 11:22:33");
  630. }
  631. if(sql->engine()!="mssql"){
  632. stmt=sql->prepare("delete from test");
  633. stmt->exec();
  634. std::cout << "- string to date-time" << std::endl;
  635. stmt=sql->prepare("insert into test(t) values(?)");
  636. stmt->bind(1,"2008-02-03 11:22:33");
  637. stmt->exec();
  638. stmt=sql->prepare("select t from test");
  639. res = stmt->query();
  640. res->next();
  641. std::tm t=std::tm();;
  642. TEST(res->fetch(0,t));
  643. TEST(t.tm_year == 2008 - 1900);
  644. TEST(t.tm_mon == 2 - 1);
  645. TEST(t.tm_mday == 3);
  646. TEST(t.tm_hour == 11);
  647. TEST(t.tm_min == 22);
  648. TEST(t.tm_sec == 33);
  649. }
  650. }
  651. void run_test(void (*func)(cppdb::ref_ptr<cppdb::backend::connection>),cppdb::ref_ptr<cppdb::backend::connection> sql)
  652. {
  653. try {
  654. func(sql);
  655. }
  656. catch(cppdb::cppdb_error const &e) {
  657. std::cerr << "Catched exception " << e.what() << std::endl;
  658. std::cerr << "Last tested line " << last_line << std::endl;
  659. failed++;
  660. return;
  661. }
  662. passed++;
  663. }
  664. void test(std::string conn_str)
  665. {
  666. cppdb::ref_ptr<cppdb::backend::connection> sql(cppdb::driver_manager::instance().connect(conn_str));
  667. cppdb::ref_ptr<cppdb::backend::statement> stmt;
  668. cppdb::ref_ptr<cppdb::backend::result> res;
  669. wide_api = (sql->driver()=="odbc" && conn_str.find("utf=wide")!=std::string::npos);
  670. std::cout << "Basic setup" << std::endl;
  671. if(sql->engine() == "postgresql") {
  672. if(sql->driver() == "odbc")
  673. pq_oid = true;
  674. else if(sql->driver()=="postgresql" && conn_str.find("@blob=bytea") == std::string::npos)
  675. pq_oid = true;
  676. }
  677. run_test(test1,sql);
  678. run_test(test2,sql);
  679. run_test(test3,sql);
  680. run_test(test4,sql);
  681. run_test(test5,sql);
  682. run_test(test6,sql);
  683. run_test(test7,sql);
  684. run_test(test8,sql);
  685. run_test(test9,sql);
  686. }
  687. int main(int argc,char **argv)
  688. {
  689. if(argc!=2) {
  690. std::cerr << "Usage: test_backend connection_string" << std::endl;
  691. return 1;
  692. }
  693. std::string cs = argv[1];
  694. try {
  695. test(cs);
  696. }
  697. CATCH_BLOCK();
  698. SUMMARY();
  699. }