Drizzled Public API Documentation

datetime.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 MySQL
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/datetime.h>
24 #include <drizzled/error.h>
25 #include <drizzled/table.h>
26 #include <drizzled/temporal.h>
27 #include <drizzled/session.h>
28 
29 #include <math.h>
30 
31 #include <sstream>
32 #include <string>
33 
34 
35 namespace drizzled
36 {
37 
38 /****************************************************************************
39 ** datetime type
40 ** In string context: YYYY-MM-DD HH:MM:DD
41 ** In number context: YYYYMMDDHHMMDD
42 ****************************************************************************/
43 
44 int Field_datetime::store(const char *from,
45  uint32_t len,
46  const charset_info_st * const )
47 {
48  ASSERT_COLUMN_MARKED_FOR_WRITE;
49  /*
50  * Try to create a DateTime from the supplied string. Throw an error
51  * if unable to create a valid DateTime.
52  */
53  DateTime temporal;
54  if (! temporal.from_string(from, (size_t) len))
55  {
56  my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), from);
57  return 2;
58  }
59  /* Create the stored integer format. @TODO This should go away. Should be up to engine... */
60  int64_t int_value;
61  temporal.to_int64_t(&int_value);
62 
63 #ifdef WORDS_BIGENDIAN
64  if (getTable() && getTable()->isDatabaseLowByteFirst())
65  {
66  int8store(ptr, int_value);
67  }
68  else
69 #endif
70  int64_tstore(ptr, int_value);
71  return 0;
72 }
73 
74 int Field_datetime::store(double from)
75 {
76  ASSERT_COLUMN_MARKED_FOR_WRITE;
77  if (from < 0.0 || from > 99991231235959.0)
78  {
79  /* Convert the double to a string using boost::lexical_cast */
80  std::string tmp(boost::lexical_cast<std::string>(from));
81 
82  my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
83  return 2;
84  }
85  return Field_datetime::store((int64_t) rint(from), false);
86 }
87 
88 int Field_datetime::store(int64_t from, bool)
89 {
90  ASSERT_COLUMN_MARKED_FOR_WRITE;
91  /*
92  * Try to create a DateTime from the supplied integer. Throw an error
93  * if unable to create a valid DateTime.
94  */
95  DateTime temporal;
96  if (! temporal.from_int64_t(from))
97  {
98  /* Convert the integer to a string using boost::lexical_cast */
99  std::string tmp(boost::lexical_cast<std::string>(from));
100 
101  my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
102  return 2;
103  }
104 
105  /*
106  * Because "from" may be a silly MySQL-like "datetime number" (like, oh, 101)
107  * we must here get the value of the DateTime as its *real* int64_t, after
108  * the conversion above has been done...yuck. God, save us.
109  */
110  int64_t int_value;
111  temporal.to_int64_t(&int_value);
112 
113 #ifdef WORDS_BIGENDIAN
114  if (getTable() && getTable()->isDatabaseLowByteFirst())
115  {
116  int8store(ptr, int_value);
117  }
118  else
119 #endif
120  int64_tstore(ptr, int_value);
121  return 0;
122 }
123 
124 int Field_datetime::store_time(type::Time &ltime, type::timestamp_t)
125 {
126  DateTime temporal;
127 
128  temporal.set_years(ltime.year);
129  temporal.set_months(ltime.month);
130  temporal.set_days(ltime.day);
131  temporal.set_hours(ltime.hour);
132  temporal.set_minutes(ltime.minute);
133  temporal.set_seconds(ltime.second);
134 
135  if (! temporal.is_valid())
136  {
137  char tmp_string[type::Time::MAX_STRING_LENGTH];
138  size_t tmp_string_len;
139 
140  tmp_string_len= temporal.to_string(tmp_string, type::Time::MAX_STRING_LENGTH);
141  assert(tmp_string_len < type::Time::MAX_STRING_LENGTH);
142  my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp_string);
143  return 1;
144  }
145 
146  int64_t int_value;
147  temporal.to_int64_t(&int_value);
148 
149 #ifdef WORDS_BIGENDIAN
150  if (getTable() && getTable()->isDatabaseLowByteFirst())
151  {
152  int8store(ptr, int_value);
153  }
154  else
155 #endif
156  int64_tstore(ptr, int_value);
157 
158  return 0;
159 }
160 
161 double Field_datetime::val_real(void) const
162 {
163  return (double) Field_datetime::val_int();
164 }
165 
166 int64_t Field_datetime::val_int(void) const
167 {
168  int64_t j;
169 
170  ASSERT_COLUMN_MARKED_FOR_READ;
171 
172 #ifdef WORDS_BIGENDIAN
173  if (getTable() && getTable()->isDatabaseLowByteFirst())
174  j=sint8korr(ptr);
175  else
176 #endif
177  int64_tget(j,ptr);
178  return j;
179 }
180 
181 
182 String *Field_datetime::val_str(String *val_buffer, String *) const
183 {
184  val_buffer->alloc(DateTime::MAX_STRING_LENGTH);
185  val_buffer->length(DateTime::MAX_STRING_LENGTH);
186  int64_t tmp;
187 
188  ASSERT_COLUMN_MARKED_FOR_READ;
189 
190 #ifdef WORDS_BIGENDIAN
191  if (getTable() && getTable()->isDatabaseLowByteFirst())
192  tmp=sint8korr(ptr);
193  else
194 #endif
195  int64_tget(tmp,ptr);
196 
197  DateTime dt;
198 
199  /* TODO: add an assert that this succeeds
200  * currently fails due to bug in allowing
201  * ALTER TABLE to add a datetime column that's
202  * not null without a default value.
203  */
204  dt.from_int64_t(tmp, false); /* NOTE: this does *NOT* attempt convertion
205  from formats such as 20090101 as
206  the stored value has already been
207  converted.
208  */
209 
210  int rlen;
211  rlen= dt.to_string((char*)val_buffer->ptr(), DateTime::MAX_STRING_LENGTH);
212  assert((rlen+1) < DateTime::MAX_STRING_LENGTH);
213 
214  val_buffer->length(rlen);
215 
216  return val_buffer;
217 }
218 
219 bool Field_datetime::get_date(type::Time &ltime, uint32_t fuzzydate) const
220 {
221  int64_t tmp=Field_datetime::val_int();
222  uint32_t part1,part2;
223  part1=(uint32_t) (tmp/INT64_C(1000000));
224  part2=(uint32_t) (tmp - (uint64_t) part1*INT64_C(1000000));
225 
226  ltime.time_type= type::DRIZZLE_TIMESTAMP_DATETIME;
227  ltime.neg= 0;
228  ltime.second_part= 0;
229  ltime.second= (int) (part2%100);
230  ltime.minute= (int) (part2/100%100);
231  ltime.hour= (int) (part2/10000);
232  ltime.day= (int) (part1%100);
233  ltime.month= (int) (part1/100%100);
234  ltime.year= (int) (part1/10000);
235 
236  return (!(fuzzydate & TIME_FUZZY_DATE) && (!ltime.month || !ltime.day)) ? 1 : 0;
237 }
238 
239 bool Field_datetime::get_time(type::Time &ltime) const
240 {
241  return Field_datetime::get_date(ltime,0);
242 }
243 
244 int Field_datetime::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
245 {
246  int64_t a,b;
247 #ifdef WORDS_BIGENDIAN
248  if (getTable() && getTable()->isDatabaseLowByteFirst())
249  {
250  a=sint8korr(a_ptr);
251  b=sint8korr(b_ptr);
252  }
253  else
254 #endif
255  {
256  int64_tget(a,a_ptr);
257  int64_tget(b,b_ptr);
258  }
259  return ((uint64_t) a < (uint64_t) b) ? -1 :
260  ((uint64_t) a > (uint64_t) b) ? 1 : 0;
261 }
262 
263 void Field_datetime::sort_string(unsigned char *to,uint32_t )
264 {
265 #ifdef WORDS_BIGENDIAN
266  if (not getTable() || not getTable()->isDatabaseLowByteFirst())
267  {
268  to[0] = ptr[0];
269  to[1] = ptr[1];
270  to[2] = ptr[2];
271  to[3] = ptr[3];
272  to[4] = ptr[4];
273  to[5] = ptr[5];
274  to[6] = ptr[6];
275  to[7] = ptr[7];
276  }
277  else
278 #endif
279  {
280  to[0] = ptr[7];
281  to[1] = ptr[6];
282  to[2] = ptr[5];
283  to[3] = ptr[4];
284  to[4] = ptr[3];
285  to[5] = ptr[2];
286  to[6] = ptr[1];
287  to[7] = ptr[0];
288  }
289 }
290 
291 } /* namespace drizzled */
virtual int to_string(char *to, size_t to_len) const
Definition: temporal.cc:999
void set_hours(const uint32_t hour)
Definition: temporal.h:136
void set_years(const uint32_t year)
Definition: temporal.h:148
void to_int64_t(int64_t *to) const
Definition: temporal.cc:1073
void set_minutes(const uint32_t minute)
Definition: temporal.h:132
int store_time(type::Time &ltime, type::timestamp_t type)
Definition: datetime.cc:124
void set_days(const uint32_t day)
Definition: temporal.h:140
static const int MAX_STRING_LENGTH
Definition: temporal.h:608
void set_seconds(const uint32_t second)
Definition: temporal.h:128
void set_months(const uint32_t month)
Definition: temporal.h:144
virtual bool is_valid() const
Definition: temporal.cc:1383
unsigned char * ptr
Definition: field.h:71