00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "fennel/common/CommonPreamble.h"
00025 #include "fennel/test/TestBase.h"
00026 #include "fennel/calculator/SqlDate.h"
00027 #include "fennel/common/TraceSource.h"
00028 #include "fennel/calctest/SqlStringBuffer.h"
00029 #include <boost/test/test_tools.hpp>
00030 #include <boost/scoped_array.hpp>
00031 #include <string>
00032 #include <limits>
00033 #include <iostream>
00034
00035 #ifdef HAVE_ICU
00036 #include <unicode/unistr.h>
00037 #include <unicode/uloc.h>
00038 #endif
00039
00040 using namespace fennel;
00041 using namespace std;
00042
00043
00044 static const int MAXLEN = 8;
00045 static const int MAXRANDOM = 5;
00046 static const int MAXCMPLEN = 8;
00047
00048
00049 static int64_t const ticks_per_day =
00050 boost::posix_time::ptime::time_rep_type::frac_sec_per_day();
00051 static int64_t const ticks_per_year = ticks_per_day * 365LL;
00052 static int64_t const ticks_per_month = ticks_per_day * 31LL;
00053 static int64_t const ticks_per_hour = ticks_per_day / 24;
00054 static int64_t const ticks_per_minute = ticks_per_hour / 60;
00055 static int64_t const ticks_per_sec = ticks_per_minute / 60;
00056
00057 enum SqlStrToDateConvAction {
00058 StrToDate,
00059 StrToTime,
00060 StrToTimestamp
00061 };
00062
00063 class SqlDateTest : virtual public TestBase, public TraceSource
00064 {
00065
00066 void testSqlDateToStr_Ascii();
00067 void testSqlTimeToStr_Ascii();
00068 void appendCharsToUCS2LikeString(
00069 string& str,
00070 int number,
00071 char character);
00072
00073 void testSqlStrToDate_Ascii_Helper(
00074 SqlStrToDateConvAction action,
00075 uint64_t value,
00076 char const * const src,
00077 int len,
00078 bool errorExpected);
00079 void testSqlStrToDate_Ascii();
00080
00081 void testLocalTime();
00082 void testUniversalTime();
00083
00084 #ifdef HAVE_ICU
00085 string UnicodeToPrintable(const UnicodeString &s);
00086 #endif
00087
00088
00089 public:
00090 explicit SqlDateTest()
00091 : TraceSource(shared_from_this(),"SqlDateTest")
00092 {
00093 srand(time(NULL));
00094 FENNEL_UNIT_TEST_CASE(SqlDateTest, testSqlDateToStr_Ascii);
00095 FENNEL_UNIT_TEST_CASE(SqlDateTest, testSqlTimeToStr_Ascii);
00096
00097 FENNEL_UNIT_TEST_CASE(SqlDateTest, testSqlStrToDate_Ascii);
00098
00099
00100 FENNEL_UNIT_TEST_CASE(SqlDateTest, testLocalTime);
00101 }
00102
00103 virtual ~SqlDateTest()
00104 {
00105 }
00106 };
00107
00108 #ifdef HAVE_ICU
00109
00110 string
00111 SqlDateTest::UnicodeToPrintable(const UnicodeString &s) {
00112 ostringstream o;
00113 int32_t i, length;
00114 char tmp;
00115
00116
00117 length = s.length();
00118 for (i = 0; i < length; ++i) {
00119 tmp = s.charAt(i) & 0xff;
00120 o << i << "=" << tmp << " | ";
00121 }
00122 return o.str();
00123 }
00124 #endif
00125
00126
00127
00128 void
00129 SqlDateTest::appendCharsToUCS2LikeString(
00130 string& str,
00131 int number,
00132 char character)
00133 {
00134 int i;
00135 for (i = 0; i < number; i++) {
00136 #ifdef LITTLEENDIAN
00137 str.push_back(character);
00138 str.push_back(0);
00139 #else
00140 str.push_back(0);
00141 str.push_back(character);
00142 #endif
00143 }
00144 }
00145
00146 void
00147 SqlDateTest::testSqlDateToStr_Ascii()
00148 {
00149 int storage;
00150 int leftbump = 2;
00151 int rightbump = 2;
00152
00153 SqlStringBuffer s1(
00154 10, 10,
00155 0, 0,
00156 'x', ' ',
00157 leftbump, rightbump);
00158
00159 storage = 10;
00160 SqlDateToStr<1,1,SQLDATE>(s1.mStr, storage, 0);
00161 BOOST_CHECK(s1.verify());
00162 SqlDateToStr<1,1,SQLDATE>(s1.mStr, storage, ticks_per_day);
00163 BOOST_CHECK(s1.verify());
00164 SqlDateToStr<1,1,SQLDATE>(s1.mStr, storage, ticks_per_month);
00165 BOOST_CHECK(s1.verify());
00166
00167 int size, leftpad, rightpad;
00168 for (storage = 5; storage <= 15; storage++) {
00169 for (size = 0; size <= storage; size++) {
00170 for (leftpad = 0; leftpad <= storage - size; leftpad++) {
00171 rightpad = (storage - size) - leftpad;
00172
00173 SqlStringBuffer t(
00174 storage, size,
00175 leftpad, rightpad,
00176 'x', ' ',
00177 leftbump, rightbump);
00178
00179 bool caught = false;
00180 try {
00181 SqlDateToStr<1,1,SQLDATE>(
00182 t.mStr,
00183 storage,
00184 ticks_per_year
00185 + size * ticks_per_month
00186 + storage * ticks_per_day);
00187 } catch (const char *str) {
00188 caught = true;
00189 BOOST_CHECK_EQUAL(strcmp(str,"22001"),0);
00190 BOOST_CHECK(t.verify());
00191 BOOST_CHECK(storage < 10);
00192 } catch (...) {
00193 BOOST_CHECK(false);
00194 }
00195 if (!caught) {
00196 BOOST_CHECK(t.verify());
00197
00198 }
00199 }
00200 }
00201 }
00202 }
00203
00204 void
00205 SqlDateTest::testSqlTimeToStr_Ascii()
00206 {
00207 int storage ;
00208 int leftbump = 2;
00209 int rightbump = 2;
00210
00211 SqlStringBuffer s1(
00212 10, 10,
00213 0, 0,
00214 'x', ' ',
00215 leftbump, rightbump);
00216
00217 storage = 10;
00218 SqlDateToStr<1,1,SQLTIME>(s1.mStr, storage, 0);
00219 BOOST_CHECK(s1.verify());
00220 SqlDateToStr<1,1,SQLTIME>(s1.mStr, storage, ticks_per_hour);
00221 BOOST_CHECK(s1.verify());
00222 SqlDateToStr<1,1,SQLTIME>(s1.mStr, storage, 13LL * ticks_per_hour);
00223 BOOST_CHECK(s1.verify());
00224 SqlDateToStr<1,1,SQLTIME>(s1.mStr, storage, 1000*57601000LL);
00225 BOOST_CHECK(s1.verify());
00226
00227
00228 int size, leftpad, rightpad;
00229 for (storage = 5; storage <= 15; storage++) {
00230 for (size = 0; size <= storage; size++) {
00231 for (leftpad = 0; leftpad <= storage - size; leftpad++) {
00232 rightpad = (storage - size) - leftpad;
00233
00234 SqlStringBuffer t(
00235 storage, size,
00236 leftpad, rightpad,
00237 'x', ' ',
00238 leftbump, rightbump);
00239
00240 bool caught = false;
00241 try {
00242 SqlDateToStr<1,1,SQLTIME>(
00243 t.mStr,
00244 storage,
00245 ticks_per_hour
00246 + size * ticks_per_minute
00247 + storage * ticks_per_sec);
00248 } catch (const char *str) {
00249 caught = true;
00250 BOOST_CHECK_EQUAL(strcmp(str,"22001"),0);
00251 BOOST_CHECK(t.verify());
00252 BOOST_CHECK(storage < 10);
00253 } catch (...) {
00254 BOOST_CHECK(false);
00255 }
00256 if (!caught) {
00257 BOOST_CHECK(t.verify());
00258
00259 }
00260 }
00261 }
00262 }
00263 }
00264
00265
00266
00267 void
00268 SqlDateTest::testSqlStrToDate_Ascii_Helper(
00269 SqlStrToDateConvAction action,
00270 uint64_t value,
00271 char const * const src,
00272 int len,
00273 bool errorExpected)
00274
00275 {
00276 int64_t t = 0;
00277 bool caught = false;
00278
00279 try {
00280 switch (action) {
00281 case StrToDate:
00282 t = IsoStringToDate(src, len);
00283 break;
00284 case StrToTime:
00285 t = IsoStringToTime(src, len);
00286 break;
00287 case StrToTimestamp:
00288 t = IsoStringToTimestamp(src, len);
00289 break;
00290 default:
00291 permAssert(false);
00292 }
00293 } catch (const char *str) {
00294 caught = true;
00295 BOOST_CHECK_EQUAL(strcmp(str, "22007"), 0);
00296 } catch (...) {
00297
00298 BOOST_CHECK(false);
00299 }
00300 BOOST_CHECK_EQUAL(errorExpected, caught);
00301 if (!caught) {
00302 BOOST_CHECK_EQUAL(value, t);
00303 }
00304 }
00305
00306
00307
00308 void
00309 SqlDateTest::testSqlStrToDate_Ascii()
00310 {
00311 int64_t oct2k = 972086400000LL;
00312 testSqlStrToDate_Ascii_Helper(
00313 StrToDate, oct2k, "2000-10-21", 10, false);
00314 testSqlStrToDate_Ascii_Helper(
00315 StrToDate, oct2k, " 2000-10-21 ", 14, false);
00316 testSqlStrToDate_Ascii_Helper(
00317 StrToDate, oct2k, "junk", 4, true);
00318 testSqlStrToDate_Ascii_Helper(
00319 StrToDate, oct2k, "2000-23-23", 10, true);
00320 testSqlStrToDate_Ascii_Helper(
00321 StrToDate, oct2k, "2000-2-30", 10, true);
00322
00323 int64_t fourteen21 =
00324 (ticks_per_hour * 14 +
00325 ticks_per_minute * 21 +
00326 ticks_per_sec * 1) / 1000;
00327 testSqlStrToDate_Ascii_Helper(
00328 StrToTime, fourteen21, "14:21:01", 8, false);
00329 testSqlStrToDate_Ascii_Helper(
00330 StrToTime, fourteen21, "14:21:1", 7, false);
00331 testSqlStrToDate_Ascii_Helper(
00332 StrToTime, fourteen21, " 14:21:01 ", 12, false);
00333
00334
00335
00336 testSqlStrToDate_Ascii_Helper(
00337 StrToTime, fourteen21, "12:61:01", 8, true);
00338 testSqlStrToDate_Ascii_Helper(
00339 StrToTime, fourteen21, "junk", 4, true);
00340 testSqlStrToDate_Ascii_Helper(
00341 StrToTime, fourteen21, "12:34", 5, true);
00342
00343 int64_t ts = oct2k + fourteen21;
00344 testSqlStrToDate_Ascii_Helper(
00345 StrToTimestamp, ts, "2000-10-21 14:21:01", 19, false);
00346 testSqlStrToDate_Ascii_Helper(
00347 StrToTimestamp, ts, "2000-10-21 14:21:1", 18, false);
00348
00349
00350
00351 testSqlStrToDate_Ascii_Helper(
00352 StrToTimestamp, ts, " 2000-10-21 14:21:01 ", 23, false);
00353 testSqlStrToDate_Ascii_Helper(
00354 StrToTimestamp, ts, "2000-10-21 27:21:01", 19, true);
00355 testSqlStrToDate_Ascii_Helper(
00356 StrToTimestamp, ts, "2000-10-32 01:21:01", 19, true);
00357 testSqlStrToDate_Ascii_Helper(
00358 StrToTimestamp, ts, "junk", 4, true);
00359 testSqlStrToDate_Ascii_Helper(
00360 StrToTimestamp, ts, "2323-6-25", 9, true);
00361 }
00362
00363
00364 void
00365 SqlDateTest::testUniversalTime()
00366 {
00367 int64_t t = UniversalTime();
00368 int64_t ts = UniversalTimestamp();
00369
00370 cout << "UniversalTime = " << t << endl;
00371 cout << "UniversalTimestamp = " << ts << endl;
00372 }
00373
00374 void
00375 SqlDateTest::testLocalTime()
00376 {
00377 boost::local_time::time_zone_ptr tzPST(
00378 new boost::local_time::posix_time_zone(
00379 std::string("PST-8PDT,M3.2.0,M11.1.0")));
00380 boost::local_time::time_zone_ptr tzUTC(
00381 new boost::local_time::posix_time_zone(
00382 std::string("UTC0")));
00383 boost::local_time::time_zone_ptr tzJST(
00384 new boost::local_time::posix_time_zone(
00385 std::string("JST9")));
00386
00387 int64_t tPST = LocalTime(tzPST);
00388 int64_t tJST = LocalTime(tzJST);
00389 int64_t tUTC = LocalTime(tzUTC);
00390 int64_t tsPST = LocalTimestamp(tzPST);
00391 int64_t tsJST = LocalTimestamp(tzJST);
00392 int64_t tsUTC = LocalTimestamp(tzUTC);
00393
00394 cout << "LocalTime(PST) = " << tPST << endl;
00395 cout << "LocalTime(JST) = " << tJST << endl;
00396 cout << "LocalTime(UTC) = " << tUTC << endl;
00397 cout << "LocalTimestamp(PST) = " << tsPST << endl;
00398 cout << "LocalTimestamp(JST) = " << tsJST << endl;
00399 cout << "LocalTimestamp(UTC) = " << tsUTC << endl;
00400 }
00401
00402 FENNEL_UNIT_TEST_SUITE(SqlDateTest);
00403
00404
00405