00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 ,
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 ,
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));
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
00135
00136
00137 drizzled::Time temporal;
00138 if (not temporal.from_time_t(from))
00139 {
00140
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
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);
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 <ime, 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 <ime) 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 }
00283 }