~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/datetime.cc

Removed/replaced DBUG symbols and TRUE/FALSE

Show diffs side-by-side

added added

removed removed

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