Warning, file /sdk/codevis/thirdparty/soci/tests/odbc/test-odbc-mssql.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 // 0002 // Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, David Courtney 0003 // Distributed under the Boost Software License, Version 1.0. 0004 // (See accompanying file LICENSE_1_0.txt or copy at 0005 // http://www.boost.org/LICENSE_1_0.txt) 0006 // 0007 0008 #include "soci/soci.h" 0009 #include "soci/odbc/soci-odbc.h" 0010 #include "common-tests.h" 0011 #include <iostream> 0012 #include <string> 0013 #include <ctime> 0014 #include <cmath> 0015 0016 using namespace soci; 0017 using namespace soci::tests; 0018 0019 std::string connectString; 0020 backend_factory const &backEnd = *soci::factory_odbc(); 0021 0022 // MS SQL-specific tests 0023 TEST_CASE("MS SQL long string", "[odbc][mssql][long]") 0024 { 0025 soci::session sql(backEnd, connectString); 0026 0027 struct long_text_table_creator : public table_creator_base 0028 { 0029 explicit long_text_table_creator(soci::session& sql) 0030 : table_creator_base(sql) 0031 { 0032 // Notice that 4000 is the maximal length of an nvarchar() column, 0033 // at least when using FreeTDS ODBC driver. 0034 sql << "create table soci_test (" 0035 "long_text nvarchar(max) null, " 0036 "fixed_text nvarchar(4000) null" 0037 ")"; 0038 } 0039 } long_text_table_creator(sql); 0040 0041 // Build a string at least 8000 characters long to test that it survives 0042 // the round trip unscathed. 0043 std::ostringstream os; 0044 for ( int n = 0; n < 1000; ++n ) 0045 { 0046 os << "Line #" << n << "\n"; 0047 } 0048 0049 std::string const str_in = os.str(); 0050 CHECK_NOTHROW(( 0051 sql << "insert into soci_test(long_text) values(:str)", use(str_in) 0052 )); 0053 0054 std::string str_out; 0055 sql << "select long_text from soci_test", into(str_out); 0056 0057 // Don't just compare the strings because the error message in case they 0058 // differ is completely unreadable due to their size, so give a better 0059 // error in the common failure case. 0060 if (str_out.length() != str_in.length()) 0061 { 0062 FAIL("Read back string of length " << str_out.length() << 0063 " instead of expected " << str_in.length()); 0064 } 0065 else 0066 { 0067 CHECK(str_out == str_in); 0068 } 0069 0070 // The long string should be truncated when inserting it into a fixed size 0071 // column. 0072 CHECK_THROWS_AS( 0073 (sql << "insert into soci_test(fixed_text) values(:str)", use(str_in)), 0074 soci_error 0075 ); 0076 } 0077 0078 // DDL Creation objects for common tests 0079 struct table_creator_one : public table_creator_base 0080 { 0081 table_creator_one(soci::session & sql) 0082 : table_creator_base(sql) 0083 { 0084 sql << "create table soci_test(id integer, val integer, c char, " 0085 "str varchar(20), sh smallint, ul numeric(20), d float, " 0086 "num76 numeric(7,6), " 0087 "tm datetime, i1 integer, i2 integer, i3 integer, " 0088 "name varchar(20))"; 0089 } 0090 }; 0091 0092 struct table_creator_two : public table_creator_base 0093 { 0094 table_creator_two(soci::session & sql) 0095 : table_creator_base(sql) 0096 { 0097 sql << "create table soci_test(num_float float, num_int integer," 0098 " name varchar(20), sometime datetime, chr char)"; 0099 } 0100 }; 0101 0102 struct table_creator_three : public table_creator_base 0103 { 0104 table_creator_three(soci::session & sql) 0105 : table_creator_base(sql) 0106 { 0107 sql << "create table soci_test(name varchar(100) not null, " 0108 "phone varchar(15))"; 0109 } 0110 }; 0111 0112 struct table_creator_for_get_affected_rows : table_creator_base 0113 { 0114 table_creator_for_get_affected_rows(soci::session & sql) 0115 : table_creator_base(sql) 0116 { 0117 sql << "create table soci_test(val integer)"; 0118 } 0119 }; 0120 0121 struct table_creator_for_clob : table_creator_base 0122 { 0123 table_creator_for_clob(soci::session & sql) 0124 : table_creator_base(sql) 0125 { 0126 sql << "create table soci_test(id integer, s text)"; 0127 } 0128 }; 0129 0130 struct table_creator_for_xml : table_creator_base 0131 { 0132 table_creator_for_xml(soci::session & sql) 0133 : table_creator_base(sql) 0134 { 0135 sql << "create table soci_test(id integer, x xml)"; 0136 } 0137 }; 0138 0139 struct table_creator_for_get_last_insert_id : table_creator_base 0140 { 0141 table_creator_for_get_last_insert_id(soci::session & sql) 0142 : table_creator_base(sql) 0143 { 0144 sql << "create table soci_test (id integer identity(1, 1), val integer)"; 0145 } 0146 }; 0147 0148 // 0149 // Support for SOCI Common Tests 0150 // 0151 0152 class test_context : public test_context_base 0153 { 0154 public: 0155 test_context(backend_factory const &backend, 0156 std::string const &connstr) 0157 : test_context_base(backend, connstr) {} 0158 0159 table_creator_base* table_creator_1(soci::session& s) const override 0160 { 0161 return new table_creator_one(s); 0162 } 0163 0164 table_creator_base* table_creator_2(soci::session& s) const override 0165 { 0166 return new table_creator_two(s); 0167 } 0168 0169 table_creator_base* table_creator_3(soci::session& s) const override 0170 { 0171 return new table_creator_three(s); 0172 } 0173 0174 table_creator_base * table_creator_4(soci::session& s) const override 0175 { 0176 return new table_creator_for_get_affected_rows(s); 0177 } 0178 0179 tests::table_creator_base* table_creator_clob(soci::session& s) const override 0180 { 0181 return new table_creator_for_clob(s); 0182 } 0183 0184 tests::table_creator_base* table_creator_xml(soci::session& s) const override 0185 { 0186 return new table_creator_for_xml(s); 0187 } 0188 0189 tests::table_creator_base* table_creator_get_last_insert_id(soci::session& s) const override 0190 { 0191 return new table_creator_for_get_last_insert_id(s); 0192 } 0193 0194 bool has_real_xml_support() const override 0195 { 0196 return true; 0197 } 0198 0199 std::string to_date_time(std::string const &datdt_string) const override 0200 { 0201 return "convert(datetime, \'" + datdt_string + "\', 120)"; 0202 } 0203 0204 bool has_multiple_select_bug() const override 0205 { 0206 // MS SQL does support MARS (multiple active result sets) since 2005 0207 // version, but this support needs to be explicitly enabled and is not 0208 // implemented in FreeTDS ODBC driver used under Unix currently, so err 0209 // on the side of caution and suppose that it's not supported. 0210 return true; 0211 } 0212 0213 std::string sql_length(std::string const& s) const override 0214 { 0215 return "len(" + s + ")"; 0216 } 0217 }; 0218 0219 int main(int argc, char** argv) 0220 { 0221 #ifdef _MSC_VER 0222 // Redirect errors, unrecoverable problems, and assert() failures to STDERR, 0223 // instead of debug message window. 0224 // This hack is required to run assert()-driven tests by Buildbot. 0225 // NOTE: Comment this 2 lines for debugging with Visual C++ debugger to catch assertions inside. 0226 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); 0227 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); 0228 #endif //_MSC_VER 0229 0230 if (argc >= 2 && argv[1][0] != '-') 0231 { 0232 connectString = argv[1]; 0233 0234 // Replace the connect string with the process name to ensure that 0235 // CATCH uses the correct name in its messages. 0236 argv[1] = argv[0]; 0237 0238 argc--; 0239 argv++; 0240 } 0241 else 0242 { 0243 connectString = "FILEDSN=./test-mssql.dsn"; 0244 } 0245 0246 test_context tc(backEnd, connectString); 0247 0248 return Catch::Session().run(argc, argv); 0249 }