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>
33
#include <boost/date_time/posix_time/posix_time.hpp>
35
#include "drizzled/temporal.h"
43
static boost::posix_time::ptime _epoch(boost::gregorian::date(1970, 1, 1));
45
Microtime::Microtime(unsigned char *ptr_arg,
46
unsigned char *null_ptr_arg,
47
unsigned char null_bit_arg,
48
enum utype unireg_check_arg,
49
const char *field_name_arg,
50
drizzled::TableShare *share) :
60
Microtime::Microtime(bool maybe_null_arg,
61
const char *field_name_arg) :
67
int Microtime::store(const char *from,
69
const CHARSET_INFO * const )
71
MicroTimestamp temporal;
73
ASSERT_COLUMN_MARKED_FOR_WRITE;
75
if (not temporal.from_string(from, (size_t) len))
77
my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
82
temporal.to_timeval(tmp);
84
uint64_t tmp_seconds= tmp.tv_sec;
85
uint32_t tmp_micro= tmp.tv_usec;
87
pack_num(tmp_seconds);
88
pack_num(tmp_micro, ptr +8);
93
int Microtime::store(double from)
95
ASSERT_COLUMN_MARKED_FOR_WRITE;
97
if (from < 0 || from > 99991231235959.0)
99
/* Convert the double to a string using stringstream */
100
std::stringstream ss;
102
ss.precision(18); /* 18 places should be fine for error display of double input. */
106
my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
109
return Microtime::store((int64_t) rint(from), false);
112
int Microtime::store(int64_t from, bool)
114
ASSERT_COLUMN_MARKED_FOR_WRITE;
116
MicroTimestamp temporal;
117
if (not temporal.from_int64_t(from))
119
/* Convert the integer to a string using boost::lexical_cast */
120
std::string tmp(boost::lexical_cast<std::string>(from));
122
my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
127
temporal.to_time_t(tmp);
129
uint64_t tmp_micro= tmp;
131
pack_num(static_cast<uint32_t>(0), ptr +8);
136
double Microtime::val_real(void)
138
return (double) Microtime::val_int();
141
int64_t Microtime::val_int(void)
145
ASSERT_COLUMN_MARKED_FOR_READ;
150
(void) temporal.from_time_t((time_t) temp);
152
/* We must convert into a "timestamp-formatted integer" ... */
154
temporal.to_int64_t(&result);
159
String *Microtime::val_str(String *val_buffer, String *)
162
uint32_t micro_temp= 0;
164
int to_len= field_length + 1 + 8;
166
val_buffer->alloc(to_len);
167
to= (char *) val_buffer->ptr();
170
unpack_num(micro_temp, ptr +8);
172
val_buffer->set_charset(&my_charset_bin); /* Safety */
174
struct timeval buffer;
176
buffer.tv_usec= micro_temp;
178
MicroTimestamp temporal;
179
(void) temporal.from_timeval(buffer);
181
int rlen= temporal.to_string(to, to_len);
182
assert(rlen <= to_len);
184
val_buffer->length(rlen);
189
bool Microtime::get_date(type::Time *ltime, uint32_t)
192
uint32_t micro_temp= 0;
195
unpack_num(micro_temp, ptr +8);
197
memset(ltime, 0, sizeof(*ltime));
200
(void) temporal.from_time_t((time_t) temp);
202
/* @TODO Goodbye the below code when type::Time is finally gone.. */
204
ltime->time_type= DRIZZLE_TIMESTAMP_DATETIME;
205
ltime->year= temporal.years();
206
ltime->month= temporal.months();
207
ltime->day= temporal.days();
208
ltime->hour= temporal.hours();
209
ltime->minute= temporal.minutes();
210
ltime->second= temporal.seconds();
211
ltime->second_part= temporal.useconds();
216
bool Microtime::get_time(type::Time *ltime)
218
return Microtime::get_date(ltime,0);
221
int Microtime::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
224
uint32_t a_micro, b_micro;
226
unpack_num(a, a_ptr);
227
unpack_num(a_micro, a_ptr +8);
229
unpack_num(b, b_ptr);
230
unpack_num(b_micro, b_ptr +8);
233
return (a_micro < b_micro) ? -1 : (a_micro > b_micro) ? 1 : 0;
235
return (a < b) ? -1 : (a > b) ? 1 : 0;
239
void Microtime::sort_string(unsigned char *to,uint32_t )
241
#ifdef WORDS_BIGENDIAN
242
if ((not getTable()) or (not getTable()->getShare()->db_low_byte_first))
244
std::reverse_copy(to, to+pack_length(), ptr);
245
std::reverse_copy(to +8, to+pack_length(), ptr +8);
250
memcpy(to, ptr, pack_length());
254
void Microtime::sql_type(String &res) const
256
res.set_ascii(STRING_WITH_LEN("microsecond timestamp"));
259
void Microtime::set_time()
261
Session *session= getTable() ? getTable()->in_use : current_session;
263
uint32_t fractional_seconds= 0;
264
uint64_t epoch_seconds= session->getCurrentTimestampEpoch(fractional_seconds);
267
pack_num(epoch_seconds);
268
pack_num(fractional_seconds, ptr +8);
271
long Microtime::get_timestamp(bool *null_value)
273
if ((*null_value= is_null()))
277
return unpack_num(tmp);
280
} /* namespace field */
281
} /* namespace drizzled */