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/epoch.h>
00024 #include <drizzled/error.h>
00025 #include <drizzled/table.h>
00026 #include <drizzled/session.h>
00027 #include <drizzled/session/times.h>
00028 #include <drizzled/current_session.h>
00029 #include <drizzled/temporal.h>
00030 #include <cmath>
00031 #include <sstream>
00032
00033 namespace drizzled {
00034 namespace field {
00035
00079 Epoch::Epoch(unsigned char *ptr_arg,
00080 unsigned char *null_ptr_arg,
00081 unsigned char null_bit_arg,
00082 enum utype unireg_check_arg,
00083 const char *field_name_arg,
00084 drizzled::TableShare *share) :
00085 Field_str(ptr_arg,
00086 MicroTimestamp::MAX_STRING_LENGTH - 1,
00087 null_ptr_arg,
00088 null_bit_arg,
00089 field_name_arg,
00090 &my_charset_bin)
00091 {
00092 unireg_check= unireg_check_arg;
00093 if (! share->getTimestampField() && unireg_check != NONE)
00094 {
00095
00096 share->setTimestampField(this);
00097 flags|= FUNCTION_DEFAULT_FLAG;
00098 if (unireg_check != TIMESTAMP_DN_FIELD)
00099 flags|= ON_UPDATE_NOW_FLAG;
00100 }
00101 }
00102
00103 Epoch::Epoch(bool maybe_null_arg,
00104 const char *field_name_arg) :
00105 Field_str((unsigned char*) NULL,
00106 MicroTimestamp::MAX_STRING_LENGTH - 1,
00107 maybe_null_arg ? (unsigned char*) "": 0,
00108 0,
00109 field_name_arg,
00110 &my_charset_bin)
00111 {
00112 if (unireg_check != TIMESTAMP_DN_FIELD)
00113 flags|= ON_UPDATE_NOW_FLAG;
00114 }
00115
00122 timestamp_auto_set_type Epoch::get_auto_set_type() const
00123 {
00124 switch (unireg_check)
00125 {
00126 case TIMESTAMP_DN_FIELD:
00127 return TIMESTAMP_AUTO_SET_ON_INSERT;
00128 case TIMESTAMP_UN_FIELD:
00129 return TIMESTAMP_AUTO_SET_ON_UPDATE;
00130 case TIMESTAMP_OLD_FIELD:
00131
00132
00133
00134
00135
00136 assert(getTable()->timestamp_field == this);
00137
00138 case TIMESTAMP_DNUN_FIELD:
00139 return TIMESTAMP_AUTO_SET_ON_BOTH;
00140 default:
00141
00142
00143
00144
00145 assert(0);
00146 return TIMESTAMP_NO_AUTO_SET;
00147 }
00148 }
00149
00150 int Epoch::store(const char *from,
00151 uint32_t len,
00152 const charset_info_st * const )
00153 {
00154 Timestamp temporal;
00155
00156 ASSERT_COLUMN_MARKED_FOR_WRITE;
00157
00158 if (not temporal.from_string(from, (size_t) len))
00159 {
00160 my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
00161 return 1;
00162 }
00163
00164 time_t tmp;
00165 temporal.to_time_t(tmp);
00166
00167 uint64_t time_tmp= tmp;
00168 pack_num(time_tmp);
00169 return 0;
00170 }
00171
00172 int Epoch::store(double from)
00173 {
00174 ASSERT_COLUMN_MARKED_FOR_WRITE;
00175
00176 uint64_t from_tmp= (uint64_t)from;
00177
00178 Timestamp temporal;
00179 if (not temporal.from_int64_t(from_tmp))
00180 {
00181
00182 std::string tmp(boost::lexical_cast<std::string>(from));
00183
00184 my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
00185 return 2;
00186 }
00187
00188 time_t tmp;
00189 temporal.to_time_t(tmp);
00190
00191 uint64_t tmp_micro= tmp;
00192 pack_num(tmp_micro);
00193
00194 return 0;
00195 }
00196
00197 int Epoch::store_decimal(const type::Decimal *value)
00198 {
00199 double tmp;
00200 value->convert(tmp);
00201
00202 return store(tmp);
00203 }
00204
00205 int Epoch::store(int64_t from, bool)
00206 {
00207 ASSERT_COLUMN_MARKED_FOR_WRITE;
00208
00209
00210
00211
00212
00213 Timestamp temporal;
00214 if (not temporal.from_int64_t(from))
00215 {
00216
00217 std::string tmp(boost::lexical_cast<std::string>(from));
00218
00219 my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
00220 return 2;
00221 }
00222
00223 time_t tmp;
00224 temporal.to_time_t(tmp);
00225
00226 uint64_t tmp64= tmp;
00227 pack_num(tmp64);
00228
00229 return 0;
00230 }
00231
00232 double Epoch::val_real(void) const
00233 {
00234 return (double) Epoch::val_int();
00235 }
00236
00237 int64_t Epoch::val_int(void) const
00238 {
00239 uint64_t temp;
00240
00241 ASSERT_COLUMN_MARKED_FOR_READ;
00242
00243 unpack_num(temp);
00244
00245 Timestamp temporal;
00246 (void) temporal.from_time_t((time_t) temp);
00247
00248
00249 int64_t result;
00250 temporal.to_int64_t(&result);
00251 return result;
00252 }
00253
00254 String *Epoch::val_str(String *val_buffer, String *) const
00255 {
00256 uint64_t temp= 0;
00257 char *to;
00258 int to_len= field_length + 1;
00259
00260 val_buffer->alloc(to_len);
00261 to= (char *) val_buffer->ptr();
00262
00263 unpack_num(temp);
00264
00265 val_buffer->set_charset(&my_charset_bin);
00266
00267 Timestamp temporal;
00268 (void) temporal.from_time_t((time_t) temp);
00269
00270 int rlen;
00271 rlen= temporal.to_string(to, to_len);
00272 assert(rlen < to_len);
00273
00274 val_buffer->length(rlen);
00275 return val_buffer;
00276 }
00277
00278 bool Epoch::get_date(type::Time <ime, uint32_t) const
00279 {
00280 uint64_t temp;
00281 type::epoch_t time_temp;
00282
00283 unpack_num(temp);
00284 time_temp= temp;
00285
00286 ltime.reset();
00287
00288 ltime.store(time_temp);
00289
00290 return 0;
00291 }
00292
00293 bool Epoch::get_time(type::Time <ime) const
00294 {
00295 return Epoch::get_date(ltime, 0);
00296 }
00297
00298 int Epoch::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
00299 {
00300 uint64_t a,b;
00301
00302 unpack_num(a, a_ptr);
00303 unpack_num(b, b_ptr);
00304
00305 return (a < b) ? -1 : (a > b) ? 1 : 0;
00306 }
00307
00308
00309 void Epoch::sort_string(unsigned char *to,uint32_t )
00310 {
00311 #ifdef WORDS_BIGENDIAN
00312 if (!getTable() || !getTable()->getShare()->db_low_byte_first)
00313 {
00314 to[0] = ptr[0];
00315 to[1] = ptr[1];
00316 to[2] = ptr[2];
00317 to[3] = ptr[3];
00318 to[4] = ptr[4];
00319 to[5] = ptr[5];
00320 to[6] = ptr[6];
00321 to[7] = ptr[7];
00322 }
00323 else
00324 #endif
00325 {
00326 to[0] = ptr[7];
00327 to[1] = ptr[6];
00328 to[2] = ptr[5];
00329 to[3] = ptr[4];
00330 to[4] = ptr[3];
00331 to[5] = ptr[2];
00332 to[6] = ptr[1];
00333 to[7] = ptr[0];
00334 }
00335 }
00336
00337 void Epoch::set_time()
00338 {
00339 Session *session= getTable() ? getTable()->in_use : current_session;
00340 time_t tmp= session->times.getCurrentTimestampEpoch();
00341
00342 set_notnull();
00343 pack_num(static_cast<uint32_t>(tmp));
00344 }
00345
00346 void Epoch::set_default()
00347 {
00348 if (getTable()->timestamp_field == this &&
00349 unireg_check != TIMESTAMP_UN_FIELD)
00350 {
00351 set_time();
00352 }
00353 else
00354 {
00355 Field::set_default();
00356 }
00357 }
00358
00359 long Epoch::get_timestamp(bool *null_value) const
00360 {
00361 if ((*null_value= is_null()))
00362 return 0;
00363
00364 uint64_t tmp;
00365 return unpack_num(tmp);
00366 }
00367
00368 size_t Epoch::max_string_length()
00369 {
00370 return sizeof(uint64_t);
00371 }
00372
00373 }
00374 }