~drizzle-trunk/drizzle/development

466 by Monty Taylor
Fixed modelines... these files are c++.
1
/* - mode: c++ c-basic-offset: 2; indent-tabs-mode: nil; -*-
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
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
873.1.2 by Jay Pipes
Fixed Field_datetime to never accept any bad datetimes as a string. This broke
21
#include "drizzled/server_includes.h"
22
#include "drizzled/field/datetime.h"
23
#include "drizzled/error.h"
24
#include "drizzled/table.h"
25
#include "drizzled/temporal.h"
26
#include "drizzled/session.h"
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
27
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
28
#include <sstream>
29
#include <string>
30
572.1.4 by Monty Taylor
Removed a bunch of unusued tests and defines from autoconf.
31
#include CMATH_H
32
33
#if defined(CMATH_NAMESPACE)
34
using namespace CMATH_NAMESPACE;
35
#endif
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
36
37
/****************************************************************************
38
** datetime type
39
** In string context: YYYY-MM-DD HH:MM:DD
40
** In number context: YYYYMMDDHHMMDD
41
** Stored as a 8 byte unsigned int. Should sometimes be change to a 6 byte int.
42
****************************************************************************/
43
44
int Field_datetime::store(const char *from,
482 by Brian Aker
Remove uint.
45
                          uint32_t len,
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
46
                          const CHARSET_INFO * const )
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
47
{
873.1.2 by Jay Pipes
Fixed Field_datetime to never accept any bad datetimes as a string. This broke
48
  /* 
49
   * Try to create a DateTime from the supplied string.  Throw an error
50
   * if unable to create a valid DateTime.  
51
   */
52
  drizzled::DateTime temporal;
53
  if (! temporal.from_string(from, (size_t) len))
54
  {
55
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), from);
56
    return 2;
57
  }
58
  /* Create the stored integer format. @TODO This should go away. Should be up to engine... */
59
  int64_t int_value;
60
  temporal.to_int64_t(&int_value);
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
61
62
#ifdef WORDS_BIGENDIAN
63
  if (table && table->s->db_low_byte_first)
64
  {
65
    int8store(ptr, int_value);
66
  }
67
  else
68
#endif
69
    int64_tstore(ptr, int_value);
70
  return 0;
71
}
72
73
int Field_datetime::store(double from)
74
{
75
  if (from < 0.0 || from > 99991231235959.0)
76
  {
77
    /* Convert the double to a string using stringstream */
78
    std::stringstream ss;
79
    std::string tmp;
80
    ss.precision(18); /* 18 places should be fine for error display of double input. */
81
    ss << from; ss >> tmp;
82
83
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
84
    return 2;
85
  }
86
  return Field_datetime::store((int64_t) rint(from), false);
87
}
88
89
int Field_datetime::store(int64_t from, bool)
90
{
91
  /* 
873.1.8 by Jay Pipes
Fixes Arg_comparator::can_compare_as_dates to never, ever allow bad
92
   * Try to create a DateTime from the supplied integer.  Throw an error
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
93
   * if unable to create a valid DateTime.  
94
   */
95
  drizzled::DateTime temporal;
96
  if (! temporal.from_int64_t(from))
97
  {
98
    /* Convert the integer to a string using stringstream */
99
    std::stringstream ss;
100
    std::string tmp;
101
    ss << from; ss >> tmp;
102
103
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
104
    return 2;
105
  }
106
107
  /* 
108
   * Because "from" may be a silly MySQL-like "datetime number" (like, oh, 101)
109
   * we must here get the value of the DateTime as its *real* int64_t, after
110
   * the conversion above has been done...yuck. God, save us.
111
   */
112
  int64_t int_value;
113
  temporal.to_int64_t(&int_value);
114
115
#ifdef WORDS_BIGENDIAN
116
  if (table && table->s->db_low_byte_first)
117
  {
118
    int8store(ptr, int_value);
119
  }
120
  else
121
#endif
122
    int64_tstore(ptr, int_value);
123
  return 0;
124
}
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
125
907.1.7 by Jay Pipes
Merged in remove-timezone work
126
int Field_datetime::store_time(DRIZZLE_TIME *ltime, enum enum_drizzle_timestamp_type)
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
127
{
907.1.7 by Jay Pipes
Merged in remove-timezone work
128
  drizzled::DateTime temporal;
129
130
  temporal.set_years(ltime->year);
131
  temporal.set_months(ltime->month);
132
  temporal.set_days(ltime->day);
133
  temporal.set_hours(ltime->hour);
134
  temporal.set_minutes(ltime->minute);
135
  temporal.set_seconds(ltime->second);
136
137
  if (! temporal.is_valid())
138
  {
139
    char tmp_string[MAX_DATE_STRING_REP_LENGTH];
140
    size_t tmp_string_len;
141
142
    temporal.to_string(tmp_string, &tmp_string_len);
143
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp_string);
144
    return 1;
145
  }
146
147
  int64_t int_value;
148
  temporal.to_int64_t(&int_value);
149
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
150
#ifdef WORDS_BIGENDIAN
151
  if (table && table->s->db_low_byte_first)
152
  {
907.1.7 by Jay Pipes
Merged in remove-timezone work
153
    int8store(ptr, int_value);
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
154
  }
155
  else
156
#endif
907.1.7 by Jay Pipes
Merged in remove-timezone work
157
    int64_tstore(ptr, int_value);
158
  return 0;
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
159
}
160
161
double Field_datetime::val_real(void)
162
{
163
  return (double) Field_datetime::val_int();
164
}
165
166
int64_t Field_datetime::val_int(void)
167
{
168
  int64_t j;
169
#ifdef WORDS_BIGENDIAN
170
  if (table && table->s->db_low_byte_first)
171
    j=sint8korr(ptr);
172
  else
173
#endif
174
    int64_tget(j,ptr);
175
  return j;
176
}
177
178
179
String *Field_datetime::val_str(String *val_buffer,
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
180
				String *)
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
181
{
182
  val_buffer->alloc(field_length);
183
  val_buffer->length(field_length);
184
  uint64_t tmp;
185
  long part1,part2;
186
  char *pos;
187
  int part3;
188
189
#ifdef WORDS_BIGENDIAN
190
  if (table && table->s->db_low_byte_first)
191
    tmp=sint8korr(ptr);
192
  else
193
#endif
194
    int64_tget(tmp,ptr);
195
196
  /*
197
    Avoid problem with slow int64_t arithmetic and sprintf
198
  */
199
422 by Monty
Various int64 constant fixes.
200
  part1=(long) (tmp/INT64_C(1000000));
201
  part2=(long) (tmp - (uint64_t) part1*INT64_C(1000000));
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
202
203
  pos=(char*) val_buffer->ptr() + MAX_DATETIME_WIDTH;
204
  *pos--=0;
205
  *pos--= (char) ('0'+(char) (part2%10)); part2/=10;
206
  *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10);
207
  *pos--= ':';
208
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
209
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
210
  *pos--= ':';
211
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
212
  *pos--= (char) ('0'+(char) part3);
213
  *pos--= ' ';
214
  *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
215
  *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
216
  *pos--= '-';
217
  *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
218
  *pos--= (char) ('0'+(char) (part1%10)); part3= (int) (part1/10);
219
  *pos--= '-';
220
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
221
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
222
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
223
  *pos=(char) ('0'+(char) part3);
224
  return val_buffer;
225
}
226
482 by Brian Aker
Remove uint.
227
bool Field_datetime::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzydate)
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
228
{
229
  int64_t tmp=Field_datetime::val_int();
205 by Brian Aker
uint32 -> uin32_t
230
  uint32_t part1,part2;
422 by Monty
Various int64 constant fixes.
231
  part1=(uint32_t) (tmp/INT64_C(1000000));
232
  part2=(uint32_t) (tmp - (uint64_t) part1*INT64_C(1000000));
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
233
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
234
  ltime->time_type=	DRIZZLE_TIMESTAMP_DATETIME;
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
235
  ltime->neg=		0;
236
  ltime->second_part=	0;
237
  ltime->second=	(int) (part2%100);
238
  ltime->minute=	(int) (part2/100%100);
239
  ltime->hour=		(int) (part2/10000);
240
  ltime->day=		(int) (part1%100);
241
  ltime->month= 	(int) (part1/100%100);
242
  ltime->year= 		(int) (part1/10000);
243
  return (!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ? 1 : 0;
244
}
245
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
246
bool Field_datetime::get_time(DRIZZLE_TIME *ltime)
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
247
{
248
  return Field_datetime::get_date(ltime,0);
249
}
250
481 by Brian Aker
Remove all of uchar.
251
int Field_datetime::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
252
{
253
  int64_t a,b;
254
#ifdef WORDS_BIGENDIAN
255
  if (table && table->s->db_low_byte_first)
256
  {
257
    a=sint8korr(a_ptr);
258
    b=sint8korr(b_ptr);
259
  }
260
  else
261
#endif
262
  {
263
    int64_tget(a,a_ptr);
264
    int64_tget(b,b_ptr);
265
  }
266
  return ((uint64_t) a < (uint64_t) b) ? -1 :
267
    ((uint64_t) a > (uint64_t) b) ? 1 : 0;
268
}
269
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
270
void Field_datetime::sort_string(unsigned char *to,uint32_t )
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
271
{
272
#ifdef WORDS_BIGENDIAN
273
  if (!table || !table->s->db_low_byte_first)
274
  {
275
    to[0] = ptr[0];
276
    to[1] = ptr[1];
277
    to[2] = ptr[2];
278
    to[3] = ptr[3];
279
    to[4] = ptr[4];
280
    to[5] = ptr[5];
281
    to[6] = ptr[6];
282
    to[7] = ptr[7];
283
  }
284
  else
285
#endif
286
  {
287
    to[0] = ptr[7];
288
    to[1] = ptr[6];
289
    to[2] = ptr[5];
290
    to[3] = ptr[4];
291
    to[4] = ptr[3];
292
    to[5] = ptr[2];
293
    to[6] = ptr[1];
294
    to[7] = ptr[0];
295
  }
296
}
297
298
299
void Field_datetime::sql_type(String &res) const
300
{
301
  res.set_ascii(STRING_WITH_LEN("datetime"));
302
}
303