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/table.h>
00026 #include <drizzled/session.h>
00027 #include <drizzled/temporal.h>
00028 
00029 #include <arpa/inet.h>
00030 #include <cmath>
00031 #include <sstream>
00032 
00033 namespace drizzled {
00034 namespace field {
00035 
00043   Time::Time(unsigned char *ptr_arg,
00044              uint32_t,
00045              unsigned char *null_ptr_arg,
00046              unsigned char null_bit_arg,
00047              const char *field_name_arg) :
00048     Field_str(ptr_arg,
00049               DateTime::MAX_STRING_LENGTH - 1 /* no \0 */,
00050               null_ptr_arg,
00051               null_bit_arg,
00052               field_name_arg,
00053               &my_charset_bin)
00054 {
00055 }
00056 
00057 Time::Time(bool maybe_null_arg,
00058            const char *field_name_arg) :
00059   Field_str((unsigned char*) NULL,
00060             DateTime::MAX_STRING_LENGTH - 1 /* no \0 */,
00061             maybe_null_arg ? (unsigned char*) "": 0,
00062             0,
00063             field_name_arg,
00064             &my_charset_bin)
00065 {
00066 }
00067 
00068 int Time::store(const char *from,
00069                 uint32_t len,
00070                 const charset_info_st * const )
00071 {
00072   drizzled::Time temporal;
00073 
00074   ASSERT_COLUMN_MARKED_FOR_WRITE;
00075 
00076   if (not temporal.from_string(from, (size_t) len))
00077   {
00078     std::string tmp(boost::lexical_cast<std::string>(from));
00079     my_error(ER_INVALID_TIME_VALUE, MYF(0), tmp.c_str());
00080     return 1;
00081   }
00082 
00083   pack_time(temporal);
00084 
00085   return 0;
00086 }
00087 
00088 int Time::store(double from)
00089 { 
00090   ASSERT_COLUMN_MARKED_FOR_WRITE;
00091 
00092   do
00093   {
00094     int64_t tmp;
00095 
00096     if (from > (double)TIME_MAX_VALUE)
00097     { 
00098       tmp= TIME_MAX_VALUE;
00099       break;
00100     }
00101     else if (from < (double) - TIME_MAX_VALUE)
00102     { 
00103       tmp= -TIME_MAX_VALUE;
00104       break;
00105     }
00106     else
00107     { 
00108       tmp=(long) floor(fabs(from));                 // Remove fractions
00109 
00110       if (from < 0)
00111         tmp= -tmp;
00112 
00113       if (tmp % 100 > 59 || tmp/100 % 100 > 59)
00114       { 
00115         break;
00116       }
00117     }
00118 
00119     return store(tmp, false);
00120 
00121   } while (0);
00122 
00123   std::string tmp(boost::lexical_cast<std::string>(from));
00124   my_error(ER_INVALID_TIME_VALUE, MYF(0), tmp.c_str());
00125 
00126   return 1;
00127 }
00128 
00129 int Time::store(int64_t from, bool)
00130 {
00131   ASSERT_COLUMN_MARKED_FOR_WRITE;
00132 
00133   /* 
00134    * Try to create a DateTime from the supplied integer.  Throw an error
00135    * if unable to create a valid DateTime.  
00136    */
00137   drizzled::Time temporal;
00138   if (not temporal.from_time_t(from))
00139   {
00140     /* Convert the integer to a string using boost::lexical_cast */
00141     std::string tmp(boost::lexical_cast<std::string>(from));
00142     my_error(ER_INVALID_TIME_VALUE, MYF(0), tmp.c_str());
00143     return 2;
00144   }
00145 
00146   pack_time(temporal);
00147 
00148   return 0;
00149 }
00150 
00151 void Time::pack_time(drizzled::Time &temporal)
00152 {
00153   int32_t tmp;
00154   temporal.to_int32_t(&tmp);
00155   tmp= htonl(tmp);
00156   memcpy(ptr, &tmp, sizeof(int32_t));
00157 }
00158 
00159 void Time::unpack_time(drizzled::Time &temporal) const
00160 {
00161   int32_t tmp;
00162 
00163   memcpy(&tmp, ptr, sizeof(int32_t));
00164   tmp= htonl(tmp);
00165 
00166   temporal.from_int32_t(tmp);
00167 }
00168 
00169 void Time::unpack_time(int32_t &destination, const unsigned char *source) const
00170 {
00171   memcpy(&destination, source, sizeof(int32_t));
00172   destination= htonl(destination);
00173 }
00174 
00175 double Time::val_real(void) const
00176 {
00177   return (double) Time::val_int();
00178 }
00179 
00180 int64_t Time::val_int(void) const
00181 {
00182   ASSERT_COLUMN_MARKED_FOR_READ;
00183 
00184   drizzled::Time temporal;
00185   unpack_time(temporal);
00186 
00187   /* We must convert into a "timestamp-formatted integer" ... */
00188   uint64_t result;
00189   temporal.to_uint64_t(result);
00190   return result;
00191 }
00192 
00193 String *Time::val_str(String *val_buffer, String *) const
00194 {
00195   char *to;
00196   int to_len= field_length + 1;
00197 
00198   val_buffer->alloc(to_len);
00199   to= (char *) val_buffer->ptr();
00200 
00201   val_buffer->set_charset(&my_charset_bin); /* Safety */
00202 
00203   drizzled::Time temporal;
00204   unpack_time(temporal);
00205 
00206   int rlen;
00207   rlen= temporal.to_string(to, to_len);
00208   assert(rlen < to_len);
00209 
00210   val_buffer->length(rlen);
00211   return val_buffer;
00212 }
00213 
00214 bool Time::get_date(type::Time &ltime, uint32_t) const
00215 {
00216   ltime.reset();
00217 
00218   drizzled::Time temporal;
00219   unpack_time(temporal);
00220 
00221   ltime.time_type= type::DRIZZLE_TIMESTAMP_DATETIME;
00222   ltime.year= temporal.years();
00223   ltime.month= temporal.months();
00224   ltime.day= temporal.days();
00225   ltime.hour= temporal.hours();
00226   ltime.minute= temporal.minutes();
00227   ltime.second= temporal.seconds();
00228 
00229   return 0;
00230 }
00231 
00232 bool Time::get_time(type::Time &ltime) const
00233 {
00234   return Time::get_date(ltime, 0);
00235 }
00236 
00237 int Time::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
00238 {
00239   int32_t a,b;
00240 
00241   unpack_time(a, a_ptr);
00242   unpack_time(b, b_ptr);
00243 
00244   return (a < b) ? -1 : (a > b) ? 1 : 0;
00245 }
00246 
00247 
00248 void Time::sort_string(unsigned char *to,uint32_t )
00249 {
00250 #ifdef WORDS_BIGENDIAN
00251   if (!getTable() || !getTable()->getShare()->db_low_byte_first)
00252   {
00253     to[0] = ptr[0];
00254     to[1] = ptr[1];
00255     to[2] = ptr[2];
00256     to[3] = ptr[3];
00257   }
00258   else
00259 #endif
00260   {
00261     to[0] = ptr[3];
00262     to[1] = ptr[2];
00263     to[2] = ptr[1];
00264     to[3] = ptr[0];
00265   }
00266 }
00267 
00268 long Time::get_timestamp(bool *null_value) const
00269 {
00270   if ((*null_value= is_null()))
00271     return 0;
00272 
00273   uint64_t tmp;
00274   return unpack_num(tmp);
00275 }
00276 
00277 size_t Time::max_string_length()
00278 {
00279   return sizeof(int64_t);
00280 }
00281 
00282 } /* namespace field */
00283 } /* namespace drizzled */