SOCI Logo Get SOCI at SourceForge.net. Fast, secure and Free Open Source software downloads

test-sqlite3.cpp

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, David Courtney
00003 // Distributed under the Boost Software License, Version 1.0.
00004 // (See accompanying file LICENSE_1_0.txt or copy at
00005 // http://www.boost.org/LICENSE_1_0.txt)
00006 //
00007 
00008 //
00009 #if defined(SOCI_HEADERS_BURIED)
00010 #       include <soci/core/soci.h>
00011 #       include <soci/backends/sqlite3/soci-sqlite3.h>
00012 #       include <soci/core/test/common-tests.h>
00013 #else
00014 #       include <soci.h>
00015 #       include <soci-sqlite3.h>
00016 #       include <test/common-tests.h>
00017 #endif
00018 //
00019 #include <iostream>
00020 #include <sstream>
00021 #include <string>
00022 #include <cassert>
00023 #include <cmath>
00024 #include <ctime>
00025 #include <cstring>
00026 
00027 using namespace soci;
00028 using namespace soci::tests;
00029 
00030 std::string connectString;
00031 backend_factory const &backEnd = sqlite3;
00032 
00033 // ROWID test
00034 // In sqlite3 the row id can be called ROWID, _ROWID_ or oid
00035 void test1()
00036 {
00037     {
00038         session sql(backEnd, connectString);
00039 
00040         try { sql << "drop table test1"; }
00041         catch (soci_error const &) {} // ignore if error
00042 
00043         sql <<
00044         "create table test1 ("
00045         "    id integer,"
00046         "    name varchar(100)"
00047         ")";
00048 
00049         sql << "insert into test1(id, name) values(7, \'John\')";
00050 
00051         rowid rid(sql);
00052         sql << "select oid from test1 where id = 7", into(rid);
00053 
00054         int id;
00055         std::string name;
00056 
00057         sql << "select id, name from test1 where oid = :rid",
00058         into(id), into(name), use(rid);
00059 
00060         assert(id == 7);
00061         assert(name == "John");
00062 
00063         sql << "drop table test1";
00064     }
00065 
00066     std::cout << "test 1 passed" << std::endl;
00067 }
00068 
00069 // BLOB test
00070 struct blob_table_creator : public table_creator_base
00071 {
00072     blob_table_creator(session & sql)
00073     : table_creator_base(sql)
00074     {
00075         sql <<
00076              "create table soci_test ("
00077              "    id integer,"
00078              "    img blob"
00079              ")";
00080     }
00081 };
00082 
00083 void test2()
00084 {
00085     {
00086         session sql(backEnd, connectString);
00087 
00088         blob_table_creator tableCreator(sql);
00089 
00090         char buf[] = "abcdefghijklmnopqrstuvwxyz";
00091 
00092         sql << "insert into soci_test(id, img) values(7, '')";
00093 
00094         {
00095             blob b(sql);
00096 
00097             sql << "select img from soci_test where id = 7", into(b);
00098             assert(b.get_len() == 0);
00099 
00100             b.write(0, buf, sizeof(buf));
00101             assert(b.get_len() == sizeof(buf));
00102             sql << "update soci_test set img=? where id = 7", use(b);
00103 
00104             b.append(buf, sizeof(buf));
00105             assert(b.get_len() == 2 * sizeof(buf));
00106             sql << "insert into soci_test(id, img) values(8, ?)", use(b);
00107         }
00108         {
00109             blob b(sql);
00110             sql << "select img from soci_test where id = 8", into(b);
00111             assert(b.get_len() == 2 * sizeof(buf));
00112             char buf2[100];
00113             b.read(0, buf2, 10);
00114             assert(strncmp(buf2, "abcdefghij", 10) == 0);
00115 
00116             sql << "select img from soci_test where id = 7", into(b);
00117             assert(b.get_len() == sizeof(buf));
00118 
00119         }
00120     }
00121 
00122     std::cout << "test 2 passed" << std::endl;
00123 }
00124 
00125 // This test was put in to fix a problem that occurs when there are both
00126 //into and use elements in the same query and one of them (into) binds
00127 //to a vector object.
00128 void test3()
00129 {
00130     {
00131         session sql(backEnd, connectString);
00132 
00133         try { sql << "drop table test3"; }
00134         catch (soci_error const &) {} //ignore error if table doesn't exist
00135 
00136         sql << "Create table test3( id integer, name varchar, subname varchar);";
00137 
00138         sql << "Insert into test3(id,name,subname) values( 1,'john','smith')";
00139         sql << "Insert into test3(id,name,subname) values( 2,'george','vals')";
00140         sql << "Insert into test3(id,name,subname) values( 3,'ann','smith')";
00141         sql << "Insert into test3(id,name,subname) values( 4,'john','grey')";
00142         sql << "Insert into test3(id,name,subname) values( 5,'anthony','wall')";
00143 
00144         std::vector<int> v(10);
00145 
00146         statement s(sql.prepare << "Select id from test3 where name = :name");
00147 
00148         std::string name = "john";
00149 
00150         s.exchange(use(name, "name"));
00151         s.exchange(into(v));
00152 
00153         s.define_and_bind();
00154         s.execute(true);
00155 
00156         assert(v.size() == 2);
00157     }
00158     std::cout << "test 3 passed" << std::endl;
00159 }
00160 
00161 
00162 // Test case from Amnon David 11/1/2007
00163 // I've noticed that table schemas in SQLite3 can sometimes have typeless
00164 // columns. One (and only?) example is the sqlite_sequence that sqlite
00165 // creates for autoincrement . Attempting to traverse this table caused
00166 // SOCI to crash. I've made the following code change in statement.cpp to
00167 // create a workaround:
00168 void test4()
00169 {
00170     {
00171         // we need to have an table that uses autoincrement to test this.
00172         session sql(backEnd, connectString);
00173         sql << "create table nulltest (col INTEGER PRIMARY KEY AUTOINCREMENT, name char)";
00174         sql << "insert into nulltest(name) values('john')";
00175         sql << "insert into nulltest(name) values('james')";
00176 
00177         int key;
00178         std::string name;
00179         sql << "select * from nulltest", into(key), into(name);
00180         assert(name == "john");
00181 
00182         rowset<row> rs = (sql.prepare << "select * from sqlite_sequence");
00183         rowset<row>::const_iterator it = rs.begin();
00184         row const& r1 = (*it);
00185         assert(r1.get<std::string>(0) == "nulltest");
00186         assert(r1.get<std::string>(1) == "2");
00187     }
00188     std::cout << "test 4 passed" << std::endl;
00189 }
00190 
00191 struct longlong_table_creator : table_creator_base
00192 {
00193     longlong_table_creator(session & sql)
00194         : table_creator_base(sql)
00195     {
00196         sql << "create table soci_test(val number(20))";
00197     }
00198 };
00199 
00200 // long long test
00201 void test5()
00202 {
00203     {
00204         session sql(backEnd, connectString);
00205 
00206         longlong_table_creator tableCreator(sql);
00207 
00208         long long v1 = 1000000000000LL;
00209         assert(v1 / 1000000 == 1000000);
00210 
00211         sql << "insert into soci_test(val) values(:val)", use(v1);
00212 
00213         long long v2 = 0LL;
00214         sql << "select val from soci_test", into(v2);
00215 
00216         assert(v2 == v1);
00217     }
00218 
00219     // vector<long long>
00220     {
00221         session sql(backEnd, connectString);
00222 
00223         longlong_table_creator tableCreator(sql);
00224 
00225         std::vector<long long> v1;
00226         v1.push_back(1000000000000LL);
00227         v1.push_back(1000000000001LL);
00228         v1.push_back(1000000000002LL);
00229         v1.push_back(1000000000003LL);
00230         v1.push_back(1000000000004LL);
00231 
00232         sql << "insert into soci_test(val) values(:val)", use(v1);
00233 
00234         std::vector<long long> v2(10);
00235         sql << "select val from soci_test order by val desc", into(v2);
00236 
00237         assert(v2.size() == 5);
00238         assert(v2[0] == 1000000000004LL);
00239         assert(v2[1] == 1000000000003LL);
00240         assert(v2[2] == 1000000000002LL);
00241         assert(v2[3] == 1000000000001LL);
00242         assert(v2[4] == 1000000000000LL);
00243     }
00244 
00245     std::cout << "test 5 passed" << std::endl;
00246 }
00247 
00248 // DDL Creation objects for common tests
00249 struct table_creator_one : public table_creator_base
00250 {
00251     table_creator_one(session & sql)
00252         : table_creator_base(sql)
00253     {
00254         sql << "create table soci_test(id integer, val integer, c char, "
00255                  "str varchar(20), sh smallint, ul numeric(20), d float, "
00256                  "tm datetime, i1 integer, i2 integer, i3 integer, "
00257                  "name varchar(20))";
00258     }
00259 };
00260 
00261 struct table_creator_two : public table_creator_base
00262 {
00263     table_creator_two(session & sql)
00264         : table_creator_base(sql)
00265     {
00266         sql  << "create table soci_test(num_float float, num_int integer,"
00267                      " name varchar(20), sometime datetime, chr char)";
00268     }
00269 };
00270 
00271 struct table_creator_three : public table_creator_base
00272 {
00273     table_creator_three(session & sql)
00274         : table_creator_base(sql)
00275     {
00276         sql << "create table soci_test(name varchar(100) not null, "
00277             "phone varchar(15))";
00278     }
00279 };
00280 
00281 //
00282 // Support for SOCI Common Tests
00283 //
00284 
00285 class test_context : public test_context_base
00286 {
00287 public:
00288     test_context(backend_factory const &backEnd,
00289                 std::string const &connectString)
00290         : test_context_base(backEnd, connectString) {}
00291 
00292     table_creator_base* table_creator_1(session& s) const
00293     {
00294         return new table_creator_one(s);
00295     }
00296 
00297     table_creator_base* table_creator_2(session& s) const
00298     {
00299         return new table_creator_two(s);
00300     }
00301 
00302     table_creator_base* table_creator_3(session& s) const
00303     {
00304         return new table_creator_three(s);
00305     }
00306 
00307     std::string to_date_time(std::string const &datdt_string) const
00308     {
00309         return "datetime(\'" + datdt_string + "\')";
00310     }
00311 };
00312 
00313 int main(int argc, char** argv)
00314 {
00315 
00316 #ifdef _MSC_VER
00317     // Redirect errors, unrecoverable problems, and assert() failures to STDERR,
00318     // instead of debug message window.
00319     // This hack is required to run asser()-driven tests by Buildbot.
00320     // NOTE: Comment this 2 lines for debugging with Visual C++ debugger to catch assertions inside.
00321     _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
00322     _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
00323 #endif //_MSC_VER
00324 
00325     if (argc == 2)
00326     {
00327         connectString = argv[1];
00328     }
00329     else
00330     {
00331         // If no file name is specfied then work in-memory
00332         connectString = ":memory:";
00333     }
00334 
00335     try
00336     {
00337 
00338         test_context tc(backEnd, connectString);
00339         common_tests tests(tc);
00340         tests.run();
00341 
00342         std::cout << "\nSOCI sqlite3 Tests:\n\n";
00343 
00344         test1();
00345         test2();
00346         test3();
00347         test4();
00348         test5();
00349 
00350         std::cout << "\nOK, all tests passed.\n\n";
00351     }
00352     catch (soci::soci_error const & e)
00353     {
00354         std::cout << "SOCIERROR: " << e.what() << '\n';
00355     }
00356     catch (std::exception const & e)
00357     {
00358         std::cout << "EXCEPTION: " << e.what() << '\n';
00359     }
00360 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
SourceForge Logo

Generated on Sun Oct 3 2010 17:42:17 for EXTRAS-SOCI by Doxygen 1.7.1