File indexing completed on 2025-02-23 05:15:24
0001 // 0002 // Copyright (C) 2011-2013 Denis Chapligin 0003 // Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton 0004 // Distributed under the Boost Software License, Version 1.0. 0005 // (See accompanying file LICENSE_1_0.txt or copy at 0006 // http://www.boost.org/LICENSE_1_0.txt) 0007 // 0008 0009 #include "soci/soci.h" 0010 #include "soci/db2/soci-db2.h" 0011 #include "common-tests.h" 0012 #include <iostream> 0013 #include <string> 0014 #include <cstdlib> 0015 #include <ctime> 0016 0017 using namespace soci; 0018 using namespace soci::tests; 0019 0020 std::string connectString; 0021 backend_factory const &backEnd = *soci::factory_db2(); 0022 0023 // 0024 // Support for soci Common Tests 0025 // 0026 0027 struct table_creator_one : public table_creator_base 0028 { 0029 table_creator_one(soci::session & sql) 0030 : table_creator_base(sql) 0031 { 0032 sql << "CREATE TABLE SOCI_TEST(ID INTEGER, VAL SMALLINT, C CHAR, STR VARCHAR(20), SH SMALLINT, UL NUMERIC(20), D DOUBLE, " 0033 "NUM76 NUMERIC(7,6), " 0034 "TM TIMESTAMP, I1 INTEGER, I2 INTEGER, I3 INTEGER, NAME VARCHAR(20))"; 0035 } 0036 }; 0037 0038 struct table_creator_two : public table_creator_base 0039 { 0040 table_creator_two(soci::session & sql) 0041 : table_creator_base(sql) 0042 { 0043 sql << "CREATE TABLE SOCI_TEST(NUM_FLOAT DOUBLE, NUM_INT INTEGER, NAME VARCHAR(20), SOMETIME TIMESTAMP, CHR CHAR)"; 0044 } 0045 }; 0046 0047 struct table_creator_three : public table_creator_base 0048 { 0049 table_creator_three(soci::session & sql) 0050 : table_creator_base(sql) 0051 { 0052 sql << "CREATE TABLE SOCI_TEST(NAME VARCHAR(100) NOT NULL, PHONE VARCHAR(15))"; 0053 } 0054 }; 0055 0056 struct table_creator_for_get_affected_rows : table_creator_base 0057 { 0058 table_creator_for_get_affected_rows(soci::session & sql) 0059 : table_creator_base(sql) 0060 { 0061 sql << "CREATE TABLE SOCI_TEST(VAL INTEGER)"; 0062 } 0063 }; 0064 0065 class test_context :public test_context_base 0066 { 0067 public: 0068 test_context(backend_factory const & pi_back_end, std::string const & pi_connect_string) 0069 : test_context_base(pi_back_end, pi_connect_string) {} 0070 0071 table_creator_base* table_creator_1(soci::session & pr_s) const override 0072 { 0073 pr_s << "SET CURRENT SCHEMA = 'DB2INST1'"; 0074 return new table_creator_one(pr_s); 0075 } 0076 0077 table_creator_base* table_creator_2(soci::session & pr_s) const override 0078 { 0079 pr_s << "SET CURRENT SCHEMA = 'DB2INST1'"; 0080 return new table_creator_two(pr_s); 0081 } 0082 0083 table_creator_base* table_creator_3(soci::session & pr_s) const override 0084 { 0085 pr_s << "SET CURRENT SCHEMA = 'DB2INST1'"; 0086 return new table_creator_three(pr_s); 0087 } 0088 0089 table_creator_base* table_creator_4(soci::session& s) const override 0090 { 0091 return new table_creator_for_get_affected_rows(s); 0092 } 0093 0094 std::string to_date_time(std::string const & pi_datdt_string) const override 0095 { 0096 return "to_date('" + pi_datdt_string + "', 'YYYY-MM-DD HH24:MI:SS')"; 0097 } 0098 0099 std::string sql_length(std::string const& s) const override 0100 { 0101 return "length(" + s + ")"; 0102 } 0103 }; 0104 0105 0106 // 0107 // Additional tests to exercise the DB2 backend 0108 // 0109 0110 TEST_CASE("DB2 test 1", "[db2]") 0111 { 0112 soci::session sql(backEnd, connectString); 0113 0114 sql << "SELECT CURRENT TIMESTAMP FROM SYSIBM.SYSDUMMY1"; 0115 sql << "SELECT " << 123 << " FROM SYSIBM.SYSDUMMY1"; 0116 0117 std::string query = "CREATE TABLE DB2INST1.SOCI_TEST (ID BIGINT,DATA VARCHAR(8))"; 0118 sql << query; 0119 0120 { 0121 const int i = 7; 0122 sql << "insert into db2inst1.SOCI_TEST (id) values (:id)", use(i,"id"); 0123 int j = 0; 0124 sql << "select id from db2inst1.SOCI_TEST where id=7", into(j); 0125 CHECK(j == i); 0126 } 0127 0128 { 0129 const long int li = 9; 0130 sql << "insert into db2inst1.SOCI_TEST (id) values (:id)", use(li,"id"); 0131 long int lj = 0;; 0132 sql << "select id from db2inst1.SOCI_TEST where id=9", into(lj); 0133 CHECK(lj == li); 0134 } 0135 0136 { 0137 const long long ll = 11; 0138 sql << "insert into db2inst1.SOCI_TEST (id) values (:id)", use(ll,"id"); 0139 long long lj = 0; 0140 sql << "select id from db2inst1.SOCI_TEST where id=11", into(lj); 0141 CHECK(lj == ll); 0142 } 0143 0144 { 0145 const int i = 13; 0146 indicator i_ind = i_ok; 0147 sql << "insert into db2inst1.SOCI_TEST (id) values (:id)", use(i,i_ind,"id"); 0148 int j = 0; 0149 indicator j_ind = i_null; 0150 sql << "select id from db2inst1.SOCI_TEST where id=13", into(j,j_ind); 0151 CHECK(j == i); 0152 CHECK(j_ind == i_ok); 0153 } 0154 0155 { 0156 std::vector<int> numbers(100); 0157 for (int i = 0 ; i < 100 ; i++) 0158 { 0159 numbers[i] = i + 1000; 0160 } 0161 sql << "insert into db2inst1.SOCI_TEST (id) values (:id)", use(numbers,"id"); 0162 sql << "select id from db2inst1.SOCI_TEST where id >= 1000 and id < 2000 order by id", into(numbers); 0163 for (int i = 0 ; i < 100 ; i++) 0164 { 0165 CHECK(numbers[i] == i + 1000); 0166 } 0167 } 0168 0169 { 0170 std::vector<int> numbers(100); 0171 std::vector<indicator> inds(100); 0172 for (int i = 0 ; i < 100 ; i++) 0173 { 0174 numbers[i] = i + 2000; 0175 inds[i] = i_ok; 0176 } 0177 sql << "insert into db2inst1.SOCI_TEST (id) values (:id)", use(numbers,inds,"id"); 0178 for (int i = 0 ; i < 100 ; i++) 0179 { 0180 numbers[i] = 0; 0181 inds[i] = i_null; 0182 } 0183 sql << "select id from db2inst1.SOCI_TEST where id >= 2000 and id < 3000 order by id", into(numbers,inds); 0184 for (int i = 0 ; i < 100 ; i++) 0185 { 0186 CHECK(numbers[i] == i + 2000); 0187 CHECK(inds[i] == i_ok); 0188 } 0189 } 0190 0191 { 0192 int i = 0; 0193 statement st = (sql.prepare << "select id from db2inst1.SOCI_TEST where id < 1000", into(i)); 0194 st.execute(); 0195 st.fetch(); 0196 CHECK (i == 7); 0197 st.fetch(); 0198 CHECK (i == 9); 0199 st.fetch(); 0200 CHECK (i == 11); 0201 st.fetch(); 0202 CHECK (i == 13); 0203 } 0204 0205 { 0206 int i = 0; 0207 indicator i_ind = i_null; 0208 std::string d; 0209 indicator d_ind = i_ok; 0210 statement st = (sql.prepare << "select id, data from db2inst1.SOCI_TEST where id = 13", into(i, i_ind), into(d, d_ind)); 0211 st.execute(); 0212 st.fetch(); 0213 CHECK (i == 13); 0214 CHECK (i_ind == i_ok); 0215 CHECK (d_ind == i_null); 0216 } 0217 0218 { 0219 std::vector<int> numbers(100); 0220 for (int i = 0 ; i < 100 ; i++) 0221 { 0222 numbers[i] = 0; 0223 } 0224 statement st = (sql.prepare << "select id from db2inst1.SOCI_TEST where id >= 1000 order by id", into(numbers)); 0225 st.execute(); 0226 st.fetch(); 0227 for (int i = 0 ; i < 100 ; i++) 0228 { 0229 CHECK(numbers[i] == i + 1000); 0230 } 0231 st.fetch(); 0232 for (int i = 0 ; i < 100 ; i++) 0233 { 0234 CHECK(numbers[i] == i + 2000); 0235 } 0236 } 0237 0238 { 0239 std::vector<int> numbers(100); 0240 std::vector<indicator> inds(100); 0241 for (int i = 0 ; i < 100 ; i++) 0242 { 0243 numbers[i] = 0; 0244 inds[i] = i_null; 0245 } 0246 statement st = (sql.prepare << "select id from db2inst1.SOCI_TEST where id >= 1000 order by id", into(numbers, inds)); 0247 st.execute(); 0248 st.fetch(); 0249 for (int i = 0 ; i < 100 ; i++) 0250 { 0251 CHECK(numbers[i] == i + 1000); 0252 CHECK(inds[i] == i_ok); 0253 } 0254 st.fetch(); 0255 for (int i = 0 ; i < 100 ; i++) 0256 { 0257 CHECK(numbers[i] == i + 2000); 0258 CHECK(inds[i] == i_ok); 0259 } 0260 } 0261 0262 { 0263 // XXX: what is the purpose of this test?? what is the expected value? 0264 int i = 0; 0265 statement st = (sql.prepare << "select id from db2inst1.SOCI_TEST", use(i)); 0266 } 0267 0268 { 0269 // XXX: what is the purpose of this test?? what is the expected value? 0270 int i = 0; 0271 indicator ind = i_ok; 0272 statement st = (sql.prepare << "select id from db2inst1.SOCI_TEST", use(i, ind)); 0273 } 0274 0275 { 0276 // XXX: what is the purpose of this test?? what is the expected value? 0277 std::vector<int> numbers(100); 0278 statement st = (sql.prepare << "select id from db2inst1.SOCI_TEST", use(numbers)); 0279 } 0280 0281 { 0282 // XXX: what is the purpose of this test?? what is the expected value? 0283 std::vector<int> numbers(100); 0284 std::vector<indicator> inds(100); 0285 statement st = (sql.prepare << "select id from db2inst1.SOCI_TEST", use(numbers, inds)); 0286 } 0287 0288 sql<<"DROP TABLE DB2INST1.SOCI_TEST"; 0289 sql.commit(); 0290 } 0291 0292 TEST_CASE("DB2 test 2", "[db2]") 0293 { 0294 soci::session sql(backEnd, connectString); 0295 0296 std::string query = "CREATE TABLE DB2INST1.SOCI_TEST (ID BIGINT,DATA VARCHAR(8),DT TIMESTAMP)"; 0297 sql << query; 0298 0299 { 0300 int i = 7; 0301 std::string n("test"); 0302 sql << "insert into db2inst1.SOCI_TEST (id,data) values (:id,:name)", use(i,"id"),use(n,"name"); 0303 int j; 0304 std::string m; 0305 sql << "select id,data from db2inst1.SOCI_TEST where id=7", into(j),into(m); 0306 CHECK (j == i); 0307 CHECK (m == n); 0308 } 0309 0310 { 0311 int i = 8; 0312 sql << "insert into db2inst1.SOCI_TEST (id) values (:id)", use(i,"id"); 0313 int j; 0314 std::string m; 0315 indicator ind = i_ok; 0316 sql << "select id,data from db2inst1.SOCI_TEST where id=8", into(j),into(m,ind); 0317 CHECK(j == i); 0318 CHECK(ind==i_null); 0319 } 0320 0321 { 0322 std::tm dt; 0323 sql << "select current timestamp from sysibm.sysdummy1",into(dt); 0324 sql << "insert into db2inst1.SOCI_TEST (dt) values (:dt)",use(dt,"dt"); 0325 std::tm dt2; 0326 sql << "select dt from db2inst1.SOCI_TEST where dt is not null", into(dt2); 0327 CHECK(dt2.tm_year == dt.tm_year); 0328 CHECK(dt2.tm_mon == dt.tm_mon); 0329 CHECK(dt2.tm_mday == dt.tm_mday); 0330 CHECK(dt2.tm_hour == dt.tm_hour); 0331 CHECK(dt2.tm_min == dt.tm_min); 0332 CHECK(dt2.tm_sec == dt.tm_sec); 0333 } 0334 0335 sql<<"DROP TABLE DB2INST1.SOCI_TEST"; 0336 sql.commit(); 0337 } 0338 0339 TEST_CASE("DB2 test 3", "[db2]") 0340 { 0341 soci::session sql(backEnd, connectString); 0342 int i; 0343 0344 std::string query = "CREATE TABLE DB2INST1.SOCI_TEST (ID BIGINT,DATA VARCHAR(8),DT TIMESTAMP)"; 0345 sql << query; 0346 0347 std::vector<long long> ids(100); 0348 std::vector<std::string> data(100); 0349 std::vector<std::tm> dts(100); 0350 for (int i = 0; i < 100; i++) 0351 { 0352 ids[i] = 1000000000LL + i; 0353 data[i] = "test"; 0354 dts[i].tm_year = 112; 0355 dts[i].tm_mon = 7; 0356 dts[i].tm_mday = 17; 0357 dts[i].tm_hour = 0; 0358 dts[i].tm_min = 0; 0359 dts[i].tm_sec = i % 60; 0360 } 0361 0362 sql << "insert into db2inst1.SOCI_TEST (id, data, dt) values (:id, :data, :dt)", 0363 use(ids, "id"), use(data,"data"), use(dts, "dt"); 0364 0365 i = 0; 0366 rowset<row> rs = (sql.prepare<<"SELECT ID, DATA, DT FROM DB2INST1.SOCI_TEST"); 0367 for (rowset<row>::const_iterator it = rs.begin(); it != rs.end(); it++) 0368 { 0369 const row & r = *it; 0370 const long long id = r.get<long long>(0); 0371 const std::string data = r.get<std::string>(1); 0372 const std::tm dt = r.get<std::tm>(2); 0373 0374 CHECK(id == 1000000000LL + i); 0375 CHECK(data == "test"); 0376 CHECK(dt.tm_year == 112); 0377 CHECK(dt.tm_mon == 7); 0378 CHECK(dt.tm_mday == 17); 0379 CHECK(dt.tm_hour == 0); 0380 CHECK(dt.tm_min == 0); 0381 CHECK(dt.tm_sec == i % 60); 0382 0383 i += 1; 0384 } 0385 0386 sql<<"DROP TABLE DB2INST1.SOCI_TEST"; 0387 sql.commit(); 0388 } 0389 0390 0391 int main(int argc, char** argv) 0392 { 0393 0394 #ifdef _MSC_VER 0395 // Redirect errors, unrecoverable problems, and assert() failures to STDERR, 0396 // instead of debug message window. 0397 // This hack is required to run assert()-driven tests by Buildbot. 0398 // NOTE: Comment this 2 lines for debugging with Visual C++ debugger to catch assertions inside. 0399 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); 0400 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); 0401 #endif //_MSC_VER 0402 0403 if (argc >= 2) 0404 { 0405 connectString = argv[1]; 0406 0407 argv[1] = argv[0]; 0408 0409 argc--; 0410 argv++; 0411 } 0412 else 0413 { 0414 std::cout << "usage: " << argv[0] 0415 << " connectstring [test-arguments...]\n" 0416 << "example: " << argv[0] 0417 << " \'DSN=SAMPLE;Uid=db2inst1;Pwd=db2inst1;autocommit=off\'\n"; 0418 std::exit(1); 0419 } 0420 0421 test_context tc(backEnd, connectString); 0422 0423 return Catch::Session().run(argc, argv); 0424 }