1
/* -*- mode: c++ c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems, Inc.
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
#include <boost/lexical_cast.hpp>
23
#include <drizzled/field/microtime.h>
24
#include <drizzled/error.h>
25
#include <drizzled/tztime.h>
26
#include <drizzled/table.h>
27
#include <drizzled/session.h>
28
#include <drizzled/current_session.h>
34
#include <boost/date_time/posix_time/posix_time.hpp>
36
#include <drizzled/temporal.h>
44
static boost::posix_time::ptime _epoch(boost::gregorian::date(1970, 1, 1));
46
Microtime::Microtime(unsigned char *ptr_arg,
47
unsigned char *null_ptr_arg,
48
unsigned char null_bit_arg,
49
enum utype unireg_check_arg,
50
const char *field_name_arg,
51
drizzled::TableShare *share) :
61
Microtime::Microtime(bool maybe_null_arg,
62
const char *field_name_arg) :
68
int Microtime::store(const char *from,
70
const CHARSET_INFO * const )
72
MicroTimestamp temporal;
74
ASSERT_COLUMN_MARKED_FOR_WRITE;
76
if (not temporal.from_string(from, (size_t) len))
78
my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
83
temporal.to_timeval(tmp);
85
uint64_t tmp_seconds= tmp.tv_sec;
86
uint32_t tmp_micro= tmp.tv_usec;
88
pack_num(tmp_seconds);
89
pack_num(tmp_micro, ptr +8);
94
int Microtime::store_time(type::Time <ime, type::timestamp_t )
99
type::Time::epoch_t time_tmp;
100
ltime.convert(time_tmp, &my_timezone, &in_dst_time_gap, true);
101
uint64_t tmp_seconds= time_tmp;
102
uint32_t tmp_micro= ltime.second_part;
104
pack_num(tmp_seconds);
105
pack_num(tmp_micro, ptr +8);
110
int Microtime::store(double from)
112
ASSERT_COLUMN_MARKED_FOR_WRITE;
114
uint64_t from_tmp= (uint64_t)from;
115
type::Time::usec_t fractional_seconds= (type::Time::usec_t)((from - from_tmp) * type::Time::FRACTIONAL_DIGITS) % type::Time::FRACTIONAL_DIGITS;
117
MicroTimestamp temporal;
118
if (not temporal.from_int64_t(from_tmp))
120
/* Convert the integer to a string using boost::lexical_cast */
121
std::string tmp(boost::lexical_cast<std::string>(from));
123
my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
128
temporal.to_time_t(tmp);
130
uint64_t tmp_micro= tmp;
132
pack_num(fractional_seconds, ptr +8);
137
int Microtime::store(int64_t from, bool)
139
ASSERT_COLUMN_MARKED_FOR_WRITE;
141
MicroTimestamp temporal;
142
if (not temporal.from_int64_t(from))
144
/* Convert the integer to a string using boost::lexical_cast */
145
std::string tmp(boost::lexical_cast<std::string>(from));
147
my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
152
temporal.to_time_t(tmp);
154
uint64_t tmp_micro= tmp;
156
pack_num(static_cast<uint32_t>(0), ptr +8);
161
double Microtime::val_real(void) const
164
type::Time::usec_t micro_temp;
166
ASSERT_COLUMN_MARKED_FOR_READ;
169
unpack_num(micro_temp, ptr +8);
172
(void) temporal.from_time_t((time_t) temp);
174
/* We must convert into a "timestamp-formatted integer" ... */
176
temporal.to_int64_t(&result);
178
result+= micro_temp % type::Time::FRACTIONAL_DIGITS;
183
type::Decimal *Microtime::val_decimal(type::Decimal *decimal_value) const
189
return date2_class_decimal(<ime, decimal_value);
192
int64_t Microtime::val_int(void) const
196
ASSERT_COLUMN_MARKED_FOR_READ;
201
(void) temporal.from_time_t((time_t) temp);
203
/* We must convert into a "timestamp-formatted integer" ... */
205
temporal.to_int64_t(&result);
210
String *Microtime::val_str(String *val_buffer, String *) const
213
type::Time::usec_t micro_temp= 0;
216
unpack_num(micro_temp, ptr +8);
219
tmp_time.store(temp, micro_temp);
221
tmp_time.convert(*val_buffer);
227
bool Microtime::get_date(type::Time <ime, uint32_t) const
230
uint32_t micro_temp= 0;
233
unpack_num(micro_temp, ptr +8);
237
ltime.store(temp, micro_temp);
242
bool Microtime::get_time(type::Time <ime) const
244
return Microtime::get_date(ltime, 0);
247
int Microtime::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
250
uint32_t a_micro, b_micro;
252
unpack_num(a, a_ptr);
253
unpack_num(a_micro, a_ptr +8);
255
unpack_num(b, b_ptr);
256
unpack_num(b_micro, b_ptr +8);
259
return (a_micro < b_micro) ? -1 : (a_micro > b_micro) ? 1 : 0;
261
return (a < b) ? -1 : (a > b) ? 1 : 0;
265
void Microtime::sort_string(unsigned char *to,uint32_t )
267
#ifdef WORDS_BIGENDIAN
268
if ((not getTable()) or (not getTable()->getShare()->db_low_byte_first))
270
std::reverse_copy(to, to+pack_length(), ptr);
271
std::reverse_copy(to +8, to+pack_length(), ptr +8);
276
memcpy(to, ptr, pack_length());
280
void Microtime::sql_type(String &res) const
282
res.set_ascii(STRING_WITH_LEN("microsecond timestamp"));
285
void Microtime::set_time()
287
Session *session= getTable() ? getTable()->in_use : current_session;
289
type::Time::usec_t fractional_seconds= 0;
290
uint64_t epoch_seconds= session->getCurrentTimestampEpoch(fractional_seconds);
293
pack_num(epoch_seconds);
294
pack_num(fractional_seconds, ptr +8);
297
long Microtime::get_timestamp(bool *null_value) const
299
if ((*null_value= is_null()))
303
return unpack_num(tmp);
306
} /* namespace field */
307
} /* namespace drizzled */