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.
 
 
 
 
 

196 lines
5.9 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/frontend.h>
  19. #include <cppdb/connection_specific.h>
  20. #include <iostream>
  21. #include <sstream>
  22. #define TEST(x) do { if(x) break; std::ostringstream ss; ss<<"Failed in " << __LINE__ <<' '<< #x; throw std::runtime_error(ss.str()); } while(0)
  23. class my_specific_a : public cppdb::connection_specific_data {
  24. public:
  25. int val;
  26. my_specific_a(int v=0) : val(v) {}
  27. };
  28. class my_specific_b : public cppdb::connection_specific_data {
  29. public:
  30. int val;
  31. my_specific_b(int v=0) : val(v) {}
  32. };
  33. int call_counter = 0;
  34. void caller(cppdb::session &)
  35. {
  36. call_counter++;
  37. }
  38. struct functor_caller {
  39. void operator()(cppdb::session &) const
  40. {
  41. call_counter++;
  42. }
  43. };
  44. int main(int argc,char **argv)
  45. {
  46. std::cout << "Testing CppDB version `" << cppdb::version_string()
  47. << "' " << cppdb::version_number() << std::endl;
  48. std::string cs = "sqlite3:db=db.db";
  49. if(argc >= 2) {
  50. cs = argv[1];
  51. }
  52. try {
  53. cppdb::session sql(cs);
  54. try {
  55. sql << "DROP TABLE test" << cppdb::exec;
  56. }
  57. catch(cppdb::cppdb_error const &e){}
  58. if(sql.engine() == "sqlite3") {
  59. sql<< "create table test ( id integer primary key autoincrement not null, "
  60. "n integer, f real , t timestamp ,name text )" << cppdb::exec;
  61. }
  62. else if(sql.engine() == "mysql") {
  63. sql<< "create table test ( id integer primary key auto_increment not null, "
  64. "n integer, f real , t timestamp ,name text )" << cppdb::exec;
  65. }
  66. else if(sql.engine() == "postgresql" ) {
  67. sql<< "create table test ( id serial primary key not null "
  68. ",n integer, f double precision , t timestamp ,name text )" << cppdb::exec;
  69. }
  70. else if(sql.engine() == "mssql" ) {
  71. sql<< "create table test ( id integer identity(1,1) primary key not null "
  72. ",n integer, f double precision , t datetime ,name text )" << cppdb::exec;
  73. }
  74. else {
  75. std::cerr << "Unknown engine: " << sql.engine() << std::endl;
  76. return 1;
  77. }
  78. std::tm t;
  79. std::time_t tt;
  80. tt=std::time(NULL);
  81. t = *std::localtime(&tt);
  82. std::cout<<asctime(&t);
  83. std::string torig=asctime(&t);
  84. int n;
  85. long long rowid;
  86. {
  87. cppdb::statement stat = sql<<"insert into test(n,f,t,name) values(?,?,?,?)"
  88. <<10<<3.1415926565<<t
  89. <<"Hello \'World\'";
  90. stat.exec();
  91. rowid = stat.sequence_last("test_id_seq");
  92. TEST(rowid==1);
  93. TEST(stat.affected()==1);
  94. std::cout<<"ID: "<<rowid<<", Affected rows "<<stat.affected()<<std::endl;
  95. }
  96. {
  97. cppdb::statement stat = sql<<"insert into test(n,f,t,name) values(?,?,?,?)"
  98. << cppdb::use(10,cppdb::not_null_value)
  99. << cppdb::use(3.1415926565,cppdb::null_value)
  100. << cppdb::use(t,cppdb::not_null_value)
  101. << cppdb::use("Hello \'World\'",cppdb::not_null_value)
  102. << cppdb::exec;
  103. rowid = stat.sequence_last("test_id_seq");
  104. std::cout<<"ID: "<<rowid<<", Affected rows "<<stat.affected()<<std::endl;
  105. TEST(rowid==2);
  106. TEST(stat.affected()==1);
  107. }
  108. cppdb::result res;
  109. if(sql.engine()=="mssql")
  110. res = sql<<"select top 10 id,n,f,t,name from test";
  111. else
  112. res = sql<<"select id,n,f,t,name from test limit 10";
  113. n=0;
  114. while(res.next()){
  115. double f=-1;
  116. int id=-1,k=-1;
  117. std::tm atime=std::tm();
  118. std::string name="nonset";
  119. cppdb::null_tag_type tag;
  120. res >> id >> k >> cppdb::into(f,tag) >> atime >> name;
  121. std::cout <<id << ' '<<k <<' '<<f<<' '<<name<<' '<<asctime(&atime)<<std::endl;
  122. TEST(id==n+1);
  123. TEST(k==10);
  124. TEST(n==0 ? f==3.1415926565: f==-1);
  125. TEST(n==0 ? tag==cppdb::not_null_value : tag==cppdb::null_value);
  126. TEST(asctime(&atime) == torig);
  127. TEST(name=="Hello 'World'");
  128. n++;
  129. }
  130. TEST(n==2);
  131. res = sql << "SELECT n FROM test WHERE id=?" << 1 << cppdb::row;
  132. TEST(!res.empty());
  133. int val;
  134. res >> val;
  135. TEST(val == 10);
  136. res.clear();
  137. cppdb::statement stat = sql<<"delete from test where 1<>0" << cppdb::exec;
  138. std::cout<<"Deleted "<<stat.affected()<<" rows\n";
  139. TEST(stat.affected()==2);
  140. TEST(!stat.empty());
  141. stat.clear();
  142. TEST(stat.empty());
  143. TEST(cppdb::statement().empty());
  144. sql.reset_specific(new my_specific_a(10));
  145. TEST(sql.get_specific<my_specific_b>()==0);
  146. TEST(sql.get_specific<my_specific_a>()!=0);
  147. TEST(sql.get_specific<my_specific_a>()->val==10);
  148. sql.reset_specific(new my_specific_b(20));
  149. TEST(sql.get_specific<my_specific_b>()!=0);
  150. TEST(sql.get_specific<my_specific_a>()!=0);
  151. TEST(sql.get_specific<my_specific_a>()->val==10);
  152. TEST(sql.get_specific<my_specific_b>()->val==20);
  153. sql.reset_specific<my_specific_b>();
  154. TEST(sql.get_specific<my_specific_b>()==0);
  155. TEST(sql.get_specific<my_specific_a>()!=0);
  156. my_specific_a *p = sql.release_specific<my_specific_a>();
  157. TEST(p!=0);
  158. delete p;
  159. TEST(sql.get_specific<my_specific_a>()==0);
  160. TEST(sql.release_specific<my_specific_a>() == 0);
  161. TEST(call_counter == 0);
  162. TEST(sql.once_called()==false);
  163. sql.once(&caller);
  164. TEST(sql.once_called()==true);
  165. TEST(call_counter == 1);
  166. sql.once(&caller);
  167. TEST(call_counter == 1);
  168. sql.close();
  169. bool have_pool = cs.find("@pool_size")!=std::string::npos;
  170. sql.open(cs);
  171. TEST(sql.once_called()==have_pool);
  172. sql.once(functor_caller());
  173. TEST(have_pool ? call_counter == 1 : call_counter == 2);
  174. }
  175. catch(std::exception const &e) {
  176. std::cerr << "ERROR: " << e.what() << std::endl;
  177. return 1;
  178. }
  179. std::cout << "Ok" << std::endl;
  180. return 0;
  181. }