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/microtime.h>
00024 #include <drizzled/error.h>
00025 #include <drizzled/tztime.h>
00026 #include <drizzled/table.h>
00027 #include <drizzled/session.h>
00028 #include <drizzled/current_session.h>
00029
00030 #include <math.h>
00031
00032 #include <sstream>
00033
00034 #include <boost/date_time/posix_time/posix_time.hpp>
00035
00036 #include <drizzled/temporal.h>
00037
00038 namespace drizzled
00039 {
00040
00041 namespace field
00042 {
00043
00044 static boost::posix_time::ptime _epoch(boost::gregorian::date(1970, 1, 1));
00045
00046 Microtime::Microtime(unsigned char *ptr_arg,
00047 unsigned char *null_ptr_arg,
00048 unsigned char null_bit_arg,
00049 enum utype unireg_check_arg,
00050 const char *field_name_arg,
00051 drizzled::TableShare *share) :
00052 Epoch(ptr_arg,
00053 null_ptr_arg,
00054 null_bit_arg,
00055 unireg_check_arg,
00056 field_name_arg,
00057 share)
00058 {
00059 }
00060
00061 Microtime::Microtime(bool maybe_null_arg,
00062 const char *field_name_arg) :
00063 Epoch(maybe_null_arg,
00064 field_name_arg)
00065 {
00066 }
00067
00068 int Microtime::store(const char *from,
00069 uint32_t len,
00070 const CHARSET_INFO * const )
00071 {
00072 MicroTimestamp temporal;
00073
00074 ASSERT_COLUMN_MARKED_FOR_WRITE;
00075
00076 if (not temporal.from_string(from, (size_t) len))
00077 {
00078 my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
00079 return 1;
00080 }
00081
00082 struct timeval tmp;
00083 temporal.to_timeval(tmp);
00084
00085 uint64_t tmp_seconds= tmp.tv_sec;
00086 uint32_t tmp_micro= tmp.tv_usec;
00087
00088 pack_num(tmp_seconds);
00089 pack_num(tmp_micro, ptr +8);
00090
00091 return 0;
00092 }
00093
00094 int Microtime::store_time(type::Time <ime, type::timestamp_t )
00095 {
00096 long my_timezone;
00097 bool in_dst_time_gap;
00098
00099 type::Time::epoch_t time_tmp;
00100 ltime.convert(time_tmp, &my_timezone, &in_dst_time_gap, true);
00101 uint64_t tmp_seconds= time_tmp;
00102 uint32_t tmp_micro= ltime.second_part;
00103
00104 pack_num(tmp_seconds);
00105 pack_num(tmp_micro, ptr +8);
00106
00107 return 0;
00108 }
00109
00110 int Microtime::store(double from)
00111 {
00112 ASSERT_COLUMN_MARKED_FOR_WRITE;
00113
00114 uint64_t from_tmp= (uint64_t)from;
00115 type::Time::usec_t fractional_seconds= (type::Time::usec_t)((from - from_tmp) * type::Time::FRACTIONAL_DIGITS) % type::Time::FRACTIONAL_DIGITS;
00116
00117 MicroTimestamp temporal;
00118 if (not temporal.from_int64_t(from_tmp))
00119 {
00120
00121 std::string tmp(boost::lexical_cast<std::string>(from));
00122
00123 my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
00124 return 2;
00125 }
00126
00127 time_t tmp;
00128 temporal.to_time_t(tmp);
00129
00130 uint64_t tmp_micro= tmp;
00131 pack_num(tmp_micro);
00132 pack_num(fractional_seconds, ptr +8);
00133
00134 return 0;
00135 }
00136
00137 int Microtime::store(int64_t from, bool)
00138 {
00139 ASSERT_COLUMN_MARKED_FOR_WRITE;
00140
00141 MicroTimestamp temporal;
00142 if (not temporal.from_int64_t(from))
00143 {
00144
00145 std::string tmp(boost::lexical_cast<std::string>(from));
00146
00147 my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
00148 return 2;
00149 }
00150
00151 time_t tmp;
00152 temporal.to_time_t(tmp);
00153
00154 uint64_t tmp_micro= tmp;
00155 pack_num(tmp_micro);
00156 pack_num(static_cast<uint32_t>(0), ptr +8);
00157
00158 return 0;
00159 }
00160
00161 double Microtime::val_real(void) const
00162 {
00163 uint64_t temp;
00164 type::Time::usec_t micro_temp;
00165
00166 ASSERT_COLUMN_MARKED_FOR_READ;
00167
00168 unpack_num(temp);
00169 unpack_num(micro_temp, ptr +8);
00170
00171 Timestamp temporal;
00172 (void) temporal.from_time_t((time_t) temp);
00173
00174
00175 int64_t result;
00176 temporal.to_int64_t(&result);
00177
00178 result+= micro_temp % type::Time::FRACTIONAL_DIGITS;
00179
00180 return result;
00181 }
00182
00183 type::Decimal *Microtime::val_decimal(type::Decimal *decimal_value) const
00184 {
00185 type::Time ltime;
00186
00187 get_date(ltime, 0);
00188
00189 return date2_class_decimal(<ime, decimal_value);
00190 }
00191
00192 int64_t Microtime::val_int(void) const
00193 {
00194 uint64_t temp;
00195
00196 ASSERT_COLUMN_MARKED_FOR_READ;
00197
00198 unpack_num(temp);
00199
00200 Timestamp temporal;
00201 (void) temporal.from_time_t((time_t) temp);
00202
00203
00204 int64_t result;
00205 temporal.to_int64_t(&result);
00206
00207 return result;
00208 }
00209
00210 String *Microtime::val_str(String *val_buffer, String *) const
00211 {
00212 uint64_t temp= 0;
00213 type::Time::usec_t micro_temp= 0;
00214
00215 unpack_num(temp);
00216 unpack_num(micro_temp, ptr +8);
00217
00218 type::Time tmp_time;
00219 tmp_time.store(temp, micro_temp);
00220
00221 tmp_time.convert(*val_buffer);
00222
00223
00224 return val_buffer;
00225 }
00226
00227 bool Microtime::get_date(type::Time <ime, uint32_t) const
00228 {
00229 uint64_t temp;
00230 uint32_t micro_temp= 0;
00231
00232 unpack_num(temp);
00233 unpack_num(micro_temp, ptr +8);
00234
00235 ltime.reset();
00236
00237 ltime.store(temp, micro_temp);
00238
00239 return false;
00240 }
00241
00242 bool Microtime::get_time(type::Time <ime) const
00243 {
00244 return Microtime::get_date(ltime, 0);
00245 }
00246
00247 int Microtime::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
00248 {
00249 uint64_t a,b;
00250 uint32_t a_micro, b_micro;
00251
00252 unpack_num(a, a_ptr);
00253 unpack_num(a_micro, a_ptr +8);
00254
00255 unpack_num(b, b_ptr);
00256 unpack_num(b_micro, b_ptr +8);
00257
00258 if (a == b)
00259 return (a_micro < b_micro) ? -1 : (a_micro > b_micro) ? 1 : 0;
00260
00261 return (a < b) ? -1 : (a > b) ? 1 : 0;
00262 }
00263
00264
00265 void Microtime::sort_string(unsigned char *to,uint32_t )
00266 {
00267 #ifdef WORDS_BIGENDIAN
00268 if ((not getTable()) or (not getTable()->getShare()->db_low_byte_first))
00269 {
00270 std::reverse_copy(to, to+pack_length(), ptr);
00271 std::reverse_copy(to +8, to+pack_length(), ptr +8);
00272 }
00273 else
00274 #endif
00275 {
00276 memcpy(to, ptr, pack_length());
00277 }
00278 }
00279
00280 void Microtime::sql_type(String &res) const
00281 {
00282 res.set_ascii(STRING_WITH_LEN("microsecond timestamp"));
00283 }
00284
00285 void Microtime::set_time()
00286 {
00287 Session *session= getTable() ? getTable()->in_use : current_session;
00288
00289 type::Time::usec_t fractional_seconds= 0;
00290 uint64_t epoch_seconds= session->getCurrentTimestampEpoch(fractional_seconds);
00291
00292 set_notnull();
00293 pack_num(epoch_seconds);
00294 pack_num(fractional_seconds, ptr +8);
00295 }
00296
00297 long Microtime::get_timestamp(bool *null_value) const
00298 {
00299 if ((*null_value= is_null()))
00300 return 0;
00301
00302 uint64_t tmp;
00303 return unpack_num(tmp);
00304 }
00305
00306 }
00307 }