Drizzled Public API Documentation

microtime.cc
1 /* -*- mode: c++ c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2008 Sun Microsystems, Inc.
5  *
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.
10  *
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.
15  *
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
19  */
20 
21 #include <config.h>
22 #include <boost/lexical_cast.hpp>
23 #include <drizzled/field/microtime.h>
24 #include <drizzled/error.h>
25 #include <drizzled/table.h>
26 #include <drizzled/session.h>
27 #include <drizzled/session/times.h>
28 #include <drizzled/current_session.h>
29 #include <drizzled/temporal.h>
30 #include <cmath>
31 #include <sstream>
32 #include <boost/date_time/posix_time/posix_time.hpp>
33 
34 
35 namespace drizzled {
36 namespace field {
37 
38 static boost::posix_time::ptime _epoch(boost::gregorian::date(1970, 1, 1));
39 
40 Microtime::Microtime(unsigned char *ptr_arg,
41  unsigned char *null_ptr_arg,
42  unsigned char null_bit_arg,
43  enum utype unireg_check_arg,
44  const char *field_name_arg,
45  drizzled::TableShare *share) :
46  Epoch(ptr_arg,
47  null_ptr_arg,
48  null_bit_arg,
49  unireg_check_arg,
50  field_name_arg,
51  share)
52 {
53 }
54 
55 Microtime::Microtime(bool maybe_null_arg,
56  const char *field_name_arg) :
57  Epoch(maybe_null_arg,
58  field_name_arg)
59 {
60 }
61 
62 int Microtime::store(const char *from,
63  uint32_t len,
64  const charset_info_st * const )
65 {
66  MicroTimestamp temporal;
67 
68  ASSERT_COLUMN_MARKED_FOR_WRITE;
69 
70  if (not temporal.from_string(from, (size_t) len))
71  {
72  my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
73  return 1;
74  }
75 
76  struct timeval tmp;
77  temporal.to_timeval(tmp);
78 
79  uint64_t tmp_seconds= tmp.tv_sec;
80  uint32_t tmp_micro= tmp.tv_usec;
81 
82  pack_num(tmp_seconds);
83  pack_num(tmp_micro, ptr +8);
84 
85  return 0;
86 }
87 
88 int Microtime::store_time(type::Time &ltime, type::timestamp_t)
89 {
90  long my_timezone;
91 
92  type::epoch_t time_tmp;
93  ltime.convert(time_tmp, &my_timezone);
94  uint64_t tmp_seconds= time_tmp;
95  uint32_t tmp_micro= ltime.second_part;
96 
97  pack_num(tmp_seconds);
98  pack_num(tmp_micro, ptr +8);
99 
100  return 0;
101 }
102 
103 int Microtime::store(double from)
104 {
105  ASSERT_COLUMN_MARKED_FOR_WRITE;
106 
107  uint64_t from_tmp= (uint64_t)from;
108  type::usec_t fractional_seconds= (type::usec_t)((from - from_tmp) * type::Time::FRACTIONAL_DIGITS) % type::Time::FRACTIONAL_DIGITS;
109 
110  MicroTimestamp temporal;
111  if (not temporal.from_int64_t(from_tmp))
112  {
113  /* Convert the integer to a string using boost::lexical_cast */
114  std::string tmp(boost::lexical_cast<std::string>(from));
115 
116  my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
117  return 2;
118  }
119 
120  time_t tmp;
121  temporal.to_time_t(tmp);
122 
123  uint64_t tmp_micro= tmp;
124  pack_num(tmp_micro);
125  pack_num(fractional_seconds, ptr +8);
126 
127  return 0;
128 }
129 
130 int Microtime::store(int64_t from, bool)
131 {
132  ASSERT_COLUMN_MARKED_FOR_WRITE;
133 
134  MicroTimestamp temporal;
135  if (not temporal.from_int64_t(from))
136  {
137  /* Convert the integer to a string using boost::lexical_cast */
138  std::string tmp(boost::lexical_cast<std::string>(from));
139 
140  my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
141  return 2;
142  }
143 
144  time_t tmp;
145  temporal.to_time_t(tmp);
146 
147  uint64_t tmp_micro= tmp;
148  pack_num(tmp_micro);
149  pack_num(static_cast<uint32_t>(0), ptr +8);
150 
151  return 0;
152 }
153 
154 double Microtime::val_real(void) const
155 {
156  uint64_t temp;
157  type::usec_t micro_temp;
158 
159  ASSERT_COLUMN_MARKED_FOR_READ;
160 
161  unpack_num(temp);
162  unpack_num(micro_temp, ptr +8);
163 
164  Timestamp temporal;
165  (void) temporal.from_time_t((time_t) temp);
166 
167  /* We must convert into a "timestamp-formatted integer" ... */
168  int64_t result;
169  temporal.to_int64_t(&result);
170 
171  result+= micro_temp % type::Time::FRACTIONAL_DIGITS;
172 
173  return result;
174 }
175 
176 type::Decimal *Microtime::val_decimal(type::Decimal *decimal_value) const
177 {
178  type::Time ltime;
179 
180  get_date(ltime, 0);
181 
182  return date2_class_decimal(&ltime, decimal_value);
183 }
184 
185 int64_t Microtime::val_int(void) const
186 {
187  uint64_t temp;
188 
189  ASSERT_COLUMN_MARKED_FOR_READ;
190 
191  unpack_num(temp);
192 
193  Timestamp temporal;
194  (void) temporal.from_time_t((time_t) temp);
195 
196  /* We must convert into a "timestamp-formatted integer" ... */
197  int64_t result;
198  temporal.to_int64_t(&result);
199 
200  return result;
201 }
202 
203 String *Microtime::val_str(String *val_buffer, String *) const
204 {
205  uint64_t temp= 0;
206  type::usec_t micro_temp= 0;
207 
208  unpack_num(temp);
209  unpack_num(micro_temp, ptr +8);
210 
211  type::Time tmp_time;
212  tmp_time.store(temp, micro_temp);
213 
214  tmp_time.convert(*val_buffer);
215 
216 
217  return val_buffer;
218 }
219 
220 bool Microtime::get_date(type::Time &ltime, uint32_t) const
221 {
222  uint64_t temp;
223  uint32_t micro_temp= 0;
224 
225  unpack_num(temp);
226  unpack_num(micro_temp, ptr +8);
227 
228  ltime.reset();
229 
230  ltime.store(temp, micro_temp);
231 
232  return false;
233 }
234 
235 bool Microtime::get_time(type::Time &ltime) const
236 {
237  return Microtime::get_date(ltime, 0);
238 }
239 
240 int Microtime::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
241 {
242  uint64_t a,b;
243  uint32_t a_micro, b_micro;
244 
245  unpack_num(a, a_ptr);
246  unpack_num(a_micro, a_ptr +8);
247 
248  unpack_num(b, b_ptr);
249  unpack_num(b_micro, b_ptr +8);
250 
251  if (a == b)
252  return (a_micro < b_micro) ? -1 : (a_micro > b_micro) ? 1 : 0;
253 
254  return (a < b) ? -1 : (a > b) ? 1 : 0;
255 }
256 
257 
258 void Microtime::sort_string(unsigned char *to,uint32_t )
259 {
260 #ifdef WORDS_BIGENDIAN
261  if ((not getTable()) or (not getTable()->getShare()->db_low_byte_first))
262  {
263  std::reverse_copy(to, to+pack_length(), ptr);
264  std::reverse_copy(to +8, to+pack_length(), ptr +8);
265  }
266  else
267 #endif
268  {
269  memcpy(to, ptr, pack_length());
270  }
271 }
272 
273 void Microtime::set_time()
274 {
275  Session *session= getTable() ? getTable()->in_use : current_session;
276 
277  type::usec_t fractional_seconds= 0;
278  uint64_t epoch_seconds= session->times.getCurrentTimestampEpoch(fractional_seconds);
279 
280  set_notnull();
281  pack_num(epoch_seconds);
282  pack_num(fractional_seconds, ptr +8);
283 }
284 
285 long Microtime::get_timestamp(bool *null_value) const
286 {
287  if ((*null_value= is_null()))
288  return 0;
289 
290  uint64_t tmp;
291  return unpack_num(tmp);
292 }
293 
294 } /* namespace field */
295 } /* namespace drizzled */
TODO: Rename this file - func.h is stupid.
bool from_int64_t(const int64_t from, bool convert)
Definition: temporal.cc:1144
void to_time_t(time_t &to) const
Definition: temporal.cc:1336