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