Drizzled Public API Documentation

time.cc
00001 /* -*- mode: c++ c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 #include <config.h>
00022 #include <boost/lexical_cast.hpp>
00023 #include <drizzled/field/time.h>
00024 #include <drizzled/error.h>
00025 #include <drizzled/tztime.h>
00026 #include <drizzled/table.h>
00027 #include <drizzled/session.h>
00028 
00029 #include <math.h>
00030 
00031 #include <sstream>
00032 
00033 #include <drizzled/temporal.h>
00034 
00035 namespace drizzled
00036 {
00037 
00038 namespace field
00039 {
00040 
00048   Time::Time(unsigned char *ptr_arg,
00049              uint32_t,
00050              unsigned char *null_ptr_arg,
00051              unsigned char null_bit_arg,
00052              const char *field_name_arg) :
00053     Field_str(ptr_arg,
00054               DateTime::MAX_STRING_LENGTH - 1 /* no \0 */,
00055               null_ptr_arg,
00056               null_bit_arg,
00057               field_name_arg,
00058               &my_charset_bin)
00059 {
00060 }
00061 
00062 Time::Time(bool maybe_null_arg,
00063            const char *field_name_arg) :
00064   Field_str((unsigned char*) NULL,
00065             DateTime::MAX_STRING_LENGTH - 1 /* no \0 */,
00066             maybe_null_arg ? (unsigned char*) "": 0,
00067             0,
00068             field_name_arg,
00069             &my_charset_bin)
00070 {
00071 }
00072 
00073 int Time::store(const char *from,
00074                 uint32_t len,
00075                 const CHARSET_INFO * const )
00076 {
00077   drizzled::Time temporal;
00078 
00079   ASSERT_COLUMN_MARKED_FOR_WRITE;
00080 
00081   if (not temporal.from_string(from, (size_t) len))
00082   {
00083     std::string tmp(boost::lexical_cast<std::string>(from));
00084     my_error(ER_INVALID_TIME_VALUE, MYF(0), tmp.c_str());
00085     return 1;
00086   }
00087 
00088   pack_time(temporal);
00089 
00090   return 0;
00091 }
00092 
00093 int Time::store(double from)
00094 { 
00095   ASSERT_COLUMN_MARKED_FOR_WRITE;
00096 
00097   do
00098   {
00099     int64_t tmp;
00100 
00101     if (from > (double)TIME_MAX_VALUE)
00102     { 
00103       tmp= TIME_MAX_VALUE;
00104       break;
00105     }
00106     else if (from < (double) - TIME_MAX_VALUE)
00107     { 
00108       tmp= -TIME_MAX_VALUE;
00109       break;
00110     }
00111     else
00112     { 
00113       tmp=(long) floor(fabs(from));                 // Remove fractions
00114 
00115       if (from < 0)
00116         tmp= -tmp;
00117 
00118       if (tmp % 100 > 59 || tmp/100 % 100 > 59)
00119       { 
00120         break;
00121       }
00122     }
00123 
00124     return store(tmp, false);
00125 
00126   } while (0);
00127 
00128   std::string tmp(boost::lexical_cast<std::string>(from));
00129   my_error(ER_INVALID_TIME_VALUE, MYF(0), tmp.c_str());
00130 
00131   return 1;
00132 }
00133 
00134 int Time::store(int64_t from, bool)
00135 {
00136   ASSERT_COLUMN_MARKED_FOR_WRITE;
00137 
00138   /* 
00139    * Try to create a DateTime from the supplied integer.  Throw an error
00140    * if unable to create a valid DateTime.  
00141    */
00142   drizzled::Time temporal;
00143   if (not temporal.from_time_t(from))
00144   {
00145     /* Convert the integer to a string using boost::lexical_cast */
00146     std::string tmp(boost::lexical_cast<std::string>(from));
00147     my_error(ER_INVALID_TIME_VALUE, MYF(0), tmp.c_str());
00148     return 2;
00149   }
00150 
00151   pack_time(temporal);
00152 
00153   return 0;
00154 }
00155 
00156 void Time::pack_time(drizzled::Time &temporal)
00157 {
00158   int32_t tmp;
00159   temporal.to_int32_t(&tmp);
00160   tmp= htonl(tmp);
00161   memcpy(ptr, &tmp, sizeof(int32_t));
00162 }
00163 
00164 void Time::unpack_time(drizzled::Time &temporal) const
00165 {
00166   int32_t tmp;
00167 
00168   memcpy(&tmp, ptr, sizeof(int32_t));
00169   tmp= htonl(tmp);
00170 
00171   temporal.from_int32_t(tmp);
00172 }
00173 
00174 void Time::unpack_time(int32_t &destination, const unsigned char *source) const
00175 {
00176   memcpy(&destination, source, sizeof(int32_t));
00177   destination= htonl(destination);
00178 }
00179 
00180 double Time::val_real(void) const
00181 {
00182   return (double) Time::val_int();
00183 }
00184 
00185 int64_t Time::val_int(void) const
00186 {
00187   ASSERT_COLUMN_MARKED_FOR_READ;
00188 
00189   drizzled::Time temporal;
00190   unpack_time(temporal);
00191 
00192   /* We must convert into a "timestamp-formatted integer" ... */
00193   uint64_t result;
00194   temporal.to_uint64_t(result);
00195   return result;
00196 }
00197 
00198 String *Time::val_str(String *val_buffer, String *) const
00199 {
00200   char *to;
00201   int to_len= field_length + 1;
00202 
00203   val_buffer->alloc(to_len);
00204   to= (char *) val_buffer->ptr();
00205 
00206   val_buffer->set_charset(&my_charset_bin); /* Safety */
00207 
00208   drizzled::Time temporal;
00209   unpack_time(temporal);
00210 
00211   int rlen;
00212   rlen= temporal.to_string(to, to_len);
00213   assert(rlen < to_len);
00214 
00215   val_buffer->length(rlen);
00216   return val_buffer;
00217 }
00218 
00219 bool Time::get_date(type::Time &ltime, uint32_t) const
00220 {
00221   ltime.reset();
00222 
00223   drizzled::Time temporal;
00224   unpack_time(temporal);
00225 
00226   ltime.time_type= type::DRIZZLE_TIMESTAMP_DATETIME;
00227   ltime.year= temporal.years();
00228   ltime.month= temporal.months();
00229   ltime.day= temporal.days();
00230   ltime.hour= temporal.hours();
00231   ltime.minute= temporal.minutes();
00232   ltime.second= temporal.seconds();
00233 
00234   return 0;
00235 }
00236 
00237 bool Time::get_time(type::Time &ltime) const
00238 {
00239   return Time::get_date(ltime, 0);
00240 }
00241 
00242 int Time::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
00243 {
00244   int32_t a,b;
00245 
00246   unpack_time(a, a_ptr);
00247   unpack_time(b, b_ptr);
00248 
00249   return (a < b) ? -1 : (a > b) ? 1 : 0;
00250 }
00251 
00252 
00253 void Time::sort_string(unsigned char *to,uint32_t )
00254 {
00255 #ifdef WORDS_BIGENDIAN
00256   if (!getTable() || !getTable()->getShare()->db_low_byte_first)
00257   {
00258     to[0] = ptr[0];
00259     to[1] = ptr[1];
00260     to[2] = ptr[2];
00261     to[3] = ptr[3];
00262   }
00263   else
00264 #endif
00265   {
00266     to[0] = ptr[3];
00267     to[1] = ptr[2];
00268     to[2] = ptr[1];
00269     to[3] = ptr[0];
00270   }
00271 }
00272 
00273 void Time::sql_type(String &res) const
00274 {
00275   res.set_ascii(STRING_WITH_LEN("timestamp"));
00276 }
00277 
00278 long Time::get_timestamp(bool *null_value) const
00279 {
00280   if ((*null_value= is_null()))
00281     return 0;
00282 
00283   uint64_t tmp;
00284   return unpack_num(tmp);
00285 }
00286 
00287 size_t Time::max_string_length()
00288 {
00289   return sizeof(int64_t);
00290 }
00291 
00292 } /* namespace field */
00293 } /* namespace drizzled */