Drizzled Public API Documentation

time.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
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/time.h>
24 #include <drizzled/error.h>
25 #include <drizzled/table.h>
26 #include <drizzled/session.h>
27 #include <drizzled/temporal.h>
28 
29 #include <arpa/inet.h>
30 #include <cmath>
31 #include <sstream>
32 
33 namespace drizzled {
34 namespace field {
35 
43  Time::Time(unsigned char *ptr_arg,
44  uint32_t,
45  unsigned char *null_ptr_arg,
46  unsigned char null_bit_arg,
47  const char *field_name_arg) :
48  Field_str(ptr_arg,
49  DateTime::MAX_STRING_LENGTH - 1 /* no \0 */,
50  null_ptr_arg,
51  null_bit_arg,
52  field_name_arg,
53  &my_charset_bin)
54 {
55 }
56 
57 Time::Time(bool maybe_null_arg,
58  const char *field_name_arg) :
59  Field_str((unsigned char*) NULL,
60  DateTime::MAX_STRING_LENGTH - 1 /* no \0 */,
61  maybe_null_arg ? (unsigned char*) "": 0,
62  0,
63  field_name_arg,
64  &my_charset_bin)
65 {
66 }
67 
68 int Time::store(const char *from,
69  uint32_t len,
70  const charset_info_st * const )
71 {
72  drizzled::Time temporal;
73 
74  ASSERT_COLUMN_MARKED_FOR_WRITE;
75 
76  if (not temporal.from_string(from, (size_t) len))
77  {
78  std::string tmp(boost::lexical_cast<std::string>(from));
79  my_error(ER_INVALID_TIME_VALUE, MYF(0), tmp.c_str());
80  return 1;
81  }
82 
83  pack_time(temporal);
84 
85  return 0;
86 }
87 
88 int Time::store(double from)
89 {
90  ASSERT_COLUMN_MARKED_FOR_WRITE;
91 
92  do
93  {
94  int64_t tmp;
95 
96  if (from > (double)TIME_MAX_VALUE)
97  {
98  tmp= TIME_MAX_VALUE;
99  break;
100  }
101  else if (from < (double) - TIME_MAX_VALUE)
102  {
103  tmp= -TIME_MAX_VALUE;
104  break;
105  }
106  else
107  {
108  tmp=(long) floor(fabs(from)); // Remove fractions
109 
110  if (from < 0)
111  tmp= -tmp;
112 
113  if (tmp % 100 > 59 || tmp/100 % 100 > 59)
114  {
115  break;
116  }
117  }
118 
119  return store(tmp, false);
120 
121  } while (0);
122 
123  std::string tmp(boost::lexical_cast<std::string>(from));
124  my_error(ER_INVALID_TIME_VALUE, MYF(0), tmp.c_str());
125 
126  return 1;
127 }
128 
129 int Time::store(int64_t from, bool)
130 {
131  ASSERT_COLUMN_MARKED_FOR_WRITE;
132 
133  /*
134  * Try to create a DateTime from the supplied integer. Throw an error
135  * if unable to create a valid DateTime.
136  */
137  drizzled::Time temporal;
138  if (not temporal.from_time_t(from))
139  {
140  /* Convert the integer to a string using boost::lexical_cast */
141  std::string tmp(boost::lexical_cast<std::string>(from));
142  my_error(ER_INVALID_TIME_VALUE, MYF(0), tmp.c_str());
143  return 2;
144  }
145 
146  pack_time(temporal);
147 
148  return 0;
149 }
150 
151 void Time::pack_time(drizzled::Time &temporal)
152 {
153  int32_t tmp;
154  temporal.to_int32_t(&tmp);
155  tmp= htonl(tmp);
156  memcpy(ptr, &tmp, sizeof(int32_t));
157 }
158 
159 void Time::unpack_time(drizzled::Time &temporal) const
160 {
161  int32_t tmp;
162 
163  memcpy(&tmp, ptr, sizeof(int32_t));
164  tmp= htonl(tmp);
165 
166  temporal.from_int32_t(tmp);
167 }
168 
169 void Time::unpack_time(int32_t &destination, const unsigned char *source) const
170 {
171  memcpy(&destination, source, sizeof(int32_t));
172  destination= htonl(destination);
173 }
174 
175 double Time::val_real(void) const
176 {
177  return (double) Time::val_int();
178 }
179 
180 int64_t Time::val_int(void) const
181 {
182  ASSERT_COLUMN_MARKED_FOR_READ;
183 
184  drizzled::Time temporal;
185  unpack_time(temporal);
186 
187  /* We must convert into a "timestamp-formatted integer" ... */
188  uint64_t result;
189  temporal.to_uint64_t(result);
190  return result;
191 }
192 
193 String *Time::val_str(String *val_buffer, String *) const
194 {
195  char *to;
196  int to_len= field_length + 1;
197 
198  val_buffer->alloc(to_len);
199  to= (char *) val_buffer->ptr();
200 
201  val_buffer->set_charset(&my_charset_bin); /* Safety */
202 
203  drizzled::Time temporal;
204  unpack_time(temporal);
205 
206  int rlen;
207  rlen= temporal.to_string(to, to_len);
208  assert(rlen < to_len);
209 
210  val_buffer->length(rlen);
211  return val_buffer;
212 }
213 
214 bool Time::get_date(type::Time &ltime, uint32_t) const
215 {
216  ltime.reset();
217 
218  drizzled::Time temporal;
219  unpack_time(temporal);
220 
221  ltime.time_type= type::DRIZZLE_TIMESTAMP_DATETIME;
222  ltime.year= temporal.years();
223  ltime.month= temporal.months();
224  ltime.day= temporal.days();
225  ltime.hour= temporal.hours();
226  ltime.minute= temporal.minutes();
227  ltime.second= temporal.seconds();
228 
229  return 0;
230 }
231 
232 bool Time::get_time(type::Time &ltime) const
233 {
234  return Time::get_date(ltime, 0);
235 }
236 
237 int Time::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
238 {
239  int32_t a,b;
240 
241  unpack_time(a, a_ptr);
242  unpack_time(b, b_ptr);
243 
244  return (a < b) ? -1 : (a > b) ? 1 : 0;
245 }
246 
247 
248 void Time::sort_string(unsigned char *to,uint32_t )
249 {
250 #ifdef WORDS_BIGENDIAN
251  if (!getTable() || !getTable()->getShare()->db_low_byte_first)
252  {
253  to[0] = ptr[0];
254  to[1] = ptr[1];
255  to[2] = ptr[2];
256  to[3] = ptr[3];
257  }
258  else
259 #endif
260  {
261  to[0] = ptr[3];
262  to[1] = ptr[2];
263  to[2] = ptr[1];
264  to[3] = ptr[0];
265  }
266 }
267 
268 long Time::get_timestamp(bool *null_value) const
269 {
270  if ((*null_value= is_null()))
271  return 0;
272 
273  uint64_t tmp;
274  return unpack_num(tmp);
275 }
276 
277 size_t Time::max_string_length()
278 {
279  return sizeof(int64_t);
280 }
281 
282 } /* namespace field */
283 } /* namespace drizzled */
bool from_string(const char *from, size_t from_len)
Definition: temporal.cc:978
uint32_t field_length
Definition: field.h:129
void to_uint64_t(uint64_t &to) const
Definition: temporal.cc:1068
uint32_t hours() const
Definition: temporal.h:138
int to_string(char *to, size_t to_len) const
Definition: temporal.cc:989
uint32_t months() const
Definition: temporal.h:146
uint32_t minutes() const
Definition: temporal.h:134
uint32_t days() const
Definition: temporal.h:142
void to_int32_t(int32_t *to) const
Definition: temporal.cc:1062
Time(unsigned char *ptr_arg, uint32_t len_arg, unsigned char *null_ptr_arg, unsigned char null_bit_arg, const char *field_name_arg)
Definition: time.cc:43
uint32_t years() const
Definition: temporal.h:150
bool from_time_t(const time_t from)
Definition: temporal.cc:1224
uint32_t seconds() const
Definition: temporal.h:130
unsigned char * ptr
Definition: field.h:71
bool from_int32_t(const int32_t from)
Definition: temporal.cc:1130