Drizzled Public API Documentation

date.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 
24 #include <drizzled/field/date.h>
25 #include <drizzled/error.h>
26 #include <drizzled/table.h>
27 #include <drizzled/temporal.h>
28 #include <drizzled/session.h>
29 #include <drizzled/time_functions.h>
30 #include <drizzled/current_session.h>
31 #include <drizzled/system_variables.h>
32 
33 #include <math.h>
34 
35 #include <sstream>
36 #include <string>
37 
38 namespace drizzled
39 {
40 
41 
42 /****************************************************************************
43 ** Drizzle date type stored in 3 bytes
44 ** In number context: YYYYMMDD
45 ****************************************************************************/
46 
47 /*
48  Store string into a date field
49 
50  SYNOPSIS
51  Field_date::store()
52  from Date string
53  len Length of date field
54  cs Character set (not used)
55 
56  RETURN
57  0 ok
58  1 Value was cut during conversion
59  2 Wrong date string
60  3 Datetime value that was cut (warning level NOTE)
61  This is used by opt_range.cc:get_mm_leaf(). Note that there is a
62  nearly-identical class Field_date doesn't ever return 3 from its
63  store function.
64 */
65 int Field_date::store(const char *from,
66  uint32_t len,
67  const charset_info_st * const )
68 {
69  /*
70  * Try to create a DateTime from the supplied string. Throw an error
71  * if unable to create a valid DateTime. A DateTime is used so that
72  * automatic conversion from the higher-storage DateTime can be used
73  * and matches on datetime format strings can occur.
74  */
75  ASSERT_COLUMN_MARKED_FOR_WRITE;
76  DateTime temporal;
77  if (! temporal.from_string(from, (size_t) len))
78  {
79  my_error(ER_INVALID_DATE_VALUE, MYF(ME_FATALERROR), from);
80  return 2;
81  }
82  /* Create the stored integer format. @TODO This should go away. Should be up to engine... */
83  uint32_t int_value= (temporal.years() * 10000) + (temporal.months() * 100) + temporal.days();
84  int4store(ptr, int_value);
85  return 0;
86 }
87 
88 int Field_date::store(double from)
89 {
90  ASSERT_COLUMN_MARKED_FOR_WRITE;
91  if (from < 0.0 || from > 99991231235959.0)
92  {
93  /* Convert the double to a string using stringstream */
94  std::stringstream ss;
95  std::string tmp;
96  ss.precision(18); /* 18 places should be fine for error display of double input. */
97  ss << from; ss >> tmp;
98 
99  my_error(ER_INVALID_DATE_VALUE, MYF(ME_FATALERROR), tmp.c_str());
100  return 2;
101  }
102  return Field_date::store((int64_t) rint(from), false);
103 }
104 
105 int Field_date::store(int64_t from, bool)
106 {
107  /*
108  * Try to create a DateTime from the supplied integer. Throw an error
109  * if unable to create a valid DateTime.
110  */
111  ASSERT_COLUMN_MARKED_FOR_WRITE;
112  DateTime temporal;
113  if (! temporal.from_int64_t(from))
114  {
115  /* Convert the integer to a string using boost::lexical_cast */
116  std::string tmp(boost::lexical_cast<std::string>(from));
117 
118  my_error(ER_INVALID_DATE_VALUE, MYF(ME_FATALERROR), tmp.c_str());
119  return 2;
120  }
121 
122  /* Create the stored integer format. @TODO This should go away. Should be up to engine... */
123  uint32_t int_value= (temporal.years() * 10000) + (temporal.months() * 100) + temporal.days();
124  int4store(ptr, int_value);
125 
126  return 0;
127 }
128 
130  type::timestamp_t time_type)
131 {
132  long tmp;
133  int error= 0;
134  if (time_type == type::DRIZZLE_TIMESTAMP_DATE || time_type == type::DRIZZLE_TIMESTAMP_DATETIME)
135  {
136  tmp= ltime.year*10000 + ltime.month*100 + ltime.day;
137 
138  Session *session= getTable() ? getTable()->in_use : current_session;
139  type::cut_t cut_error= type::VALID;
140  if (ltime.check(tmp != 0,
141  (TIME_FUZZY_DATE |
142  (session->variables.sql_mode & (MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), cut_error))
143  {
144  char buff[type::Time::MAX_STRING_LENGTH];
145  String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
146  ltime.convert(str, type::DRIZZLE_TIMESTAMP_DATE);
147  set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
148  str.ptr(), str.length(), type::DRIZZLE_TIMESTAMP_DATE, 1);
149  }
150 
151  error= static_cast<int>(cut_error);
152 
153  if (not error && ltime.time_type != type::DRIZZLE_TIMESTAMP_DATE &&
154  (ltime.hour || ltime.minute || ltime.second || ltime.second_part))
155  {
156  char buff[type::Time::MAX_STRING_LENGTH];
157  String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
158  ltime.convert(str);
159  set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_NOTE,
160  ER_WARN_DATA_TRUNCATED,
161  str.ptr(), str.length(), type::DRIZZLE_TIMESTAMP_DATE, 1);
162  error= 3;
163  }
164  }
165  else
166  {
167  tmp=0;
168  error= 1;
169  set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
170  }
171 
172  int4store(ptr,tmp);
173 
174  return error;
175 }
176 
177 double Field_date::val_real(void) const
178 {
179  return (double) Field_date::val_int();
180 }
181 
182 int64_t Field_date::val_int(void) const
183 {
184  uint32_t j;
185 
186  ASSERT_COLUMN_MARKED_FOR_READ;
187 
188  j= uint4korr(ptr);
189 
190  return (int64_t) j;
191 }
192 
193 String *Field_date::val_str(String *val_buffer, String *) const
194 {
195  val_buffer->alloc(field_length);
196  val_buffer->length(field_length);
197  uint32_t tmp=(uint32_t) uint4korr(ptr);
198  int32_t part;
199  char *pos=(char*) val_buffer->ptr()+10;
200 
201  ASSERT_COLUMN_MARKED_FOR_READ;
202 
203  /* Open coded to get more speed */
204  *pos--=0; // End NULL
205  part=(int32_t) (tmp % 100);
206  *pos--= (char) ('0'+part%10);
207  *pos--= (char) ('0'+part/10);
208  *pos--= '-';
209  part=(int32_t) (tmp/100%100);
210  *pos--= (char) ('0'+part%10);
211  *pos--= (char) ('0'+part/10);
212  *pos--= '-';
213  part=(int32_t) (tmp/10000);
214  *pos--= (char) ('0'+part%10); part/=10;
215  *pos--= (char) ('0'+part%10); part/=10;
216  *pos--= (char) ('0'+part%10); part/=10;
217  *pos= (char) ('0'+part);
218  return val_buffer;
219 }
220 
221 bool Field_date::get_date(type::Time &ltime, uint32_t fuzzydate) const
222 {
223  uint32_t tmp=(uint32_t) uint4korr(ptr);
224  ltime.day= (int) (tmp%100);
225  ltime.month= (int) (tmp/100%100);
226  ltime.year= (int) (tmp/10000);
227  ltime.time_type= type::DRIZZLE_TIMESTAMP_DATE;
228  ltime.hour= ltime.minute= ltime.second= ltime.second_part= ltime.neg= 0;
229 
230  return ((!(fuzzydate & TIME_FUZZY_DATE) && (!ltime.month || !ltime.day)) ?
231  1 : 0);
232 }
233 
234 bool Field_date::get_time(type::Time &ltime) const
235 {
236  return Field_date::get_date(ltime ,0);
237 }
238 
239 int Field_date::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
240 {
241  uint32_t a,b;
242  a=(uint32_t) uint4korr(a_ptr);
243  b=(uint32_t) uint4korr(b_ptr);
244  return (a < b) ? -1 : (a > b) ? 1 : 0;
245 }
246 
247 void Field_date::sort_string(unsigned char *to,uint32_t )
248 {
249  to[0] = ptr[3];
250  to[1] = ptr[2];
251  to[2] = ptr[1];
252  to[3] = ptr[0];
253 }
254 
255 } /* namespace drizzled */
bool set_warning(DRIZZLE_ERROR::enum_warning_level, drizzled::error_t code, int cuted_increment)
Definition: field.cc:1217
int store_time(type::Time &ltime, type::timestamp_t type)
Definition: date.cc:129
uint32_t field_length
Definition: field.h:129
TODO: Rename this file - func.h is stupid.
bool check(bool not_zero_date, uint32_t flags, type::cut_t &was_cut) const
Check datetime value for validity according to flags.
Definition: time.cc:97
Session * in_use
Definition: table.h:123
drizzle_system_variables & variables
Definition: session.h:199
void set_datetime_warning(DRIZZLE_ERROR::enum_warning_level, drizzled::error_t code, const char *str, uint32_t str_len, type::timestamp_t ts_type, int cuted_increment)
Definition: field.cc:1237
unsigned char * ptr
Definition: field.h:71