18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
#include <boost/lexical_cast.hpp>
21
#include "drizzled/server_includes.h"
23
22
#include "drizzled/field/datetime.h"
24
23
#include "drizzled/error.h"
25
24
#include "drizzled/table.h"
26
25
#include "drizzled/temporal.h"
27
26
#include "drizzled/session.h"
38
32
/****************************************************************************
40
34
** In string context: YYYY-MM-DD HH:MM:DD
41
35
** In number context: YYYYMMDDHHMMDD
36
** Stored as a 8 byte unsigned int. Should sometimes be change to a 6 byte int.
42
37
****************************************************************************/
44
39
int Field_datetime::store(const char *from,
46
41
const CHARSET_INFO * const )
48
ASSERT_COLUMN_MARKED_FOR_WRITE;
50
44
* Try to create a DateTime from the supplied string. Throw an error
51
45
* if unable to create a valid DateTime.
47
drizzled::DateTime temporal;
54
48
if (! temporal.from_string(from, (size_t) len))
56
50
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), from);
61
55
temporal.to_int64_t(&int_value);
63
57
#ifdef WORDS_BIGENDIAN
64
if (getTable() && getTable()->getShare()->db_low_byte_first)
58
if (table && table->s->db_low_byte_first)
66
60
int8store(ptr, int_value);
74
68
int Field_datetime::store(double from)
76
ASSERT_COLUMN_MARKED_FOR_WRITE;
77
70
if (from < 0.0 || from > 99991231235959.0)
79
/* Convert the double to a string using boost::lexical_cast */
80
std::string tmp(boost::lexical_cast<std::string>(from));
72
/* Convert the double to a string using stringstream */
75
ss.precision(18); /* 18 places should be fine for error display of double input. */
76
ss << from; ss >> tmp;
82
78
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
88
84
int Field_datetime::store(int64_t from, bool)
90
ASSERT_COLUMN_MARKED_FOR_WRITE;
92
87
* Try to create a DateTime from the supplied integer. Throw an error
93
88
* if unable to create a valid DateTime.
90
drizzled::DateTime temporal;
96
91
if (! temporal.from_int64_t(from))
98
/* Convert the integer to a string using boost::lexical_cast */
99
std::string tmp(boost::lexical_cast<std::string>(from));
93
/* Convert the integer to a string using stringstream */
96
ss << from; ss >> tmp;
101
98
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
111
108
temporal.to_int64_t(&int_value);
113
110
#ifdef WORDS_BIGENDIAN
114
if (getTable() && getTable()->getShare()->db_low_byte_first)
111
if (table && table->s->db_low_byte_first)
116
113
int8store(ptr, int_value);
124
121
int Field_datetime::store_time(DRIZZLE_TIME *ltime, enum enum_drizzle_timestamp_type)
123
drizzled::DateTime temporal;
128
125
temporal.set_years(ltime->year);
129
126
temporal.set_months(ltime->month);
137
134
char tmp_string[MAX_DATE_STRING_REP_LENGTH];
138
135
size_t tmp_string_len;
140
tmp_string_len= temporal.to_string(tmp_string, MAX_DATE_STRING_REP_LENGTH);
141
assert(tmp_string_len < MAX_DATE_STRING_REP_LENGTH);
137
temporal.to_string(tmp_string, &tmp_string_len);
142
138
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp_string);
147
143
temporal.to_int64_t(&int_value);
149
145
#ifdef WORDS_BIGENDIAN
150
if (getTable() && getTable()->getShare()->db_low_byte_first)
146
if (table && table->s->db_low_byte_first)
152
148
int8store(ptr, int_value);
181
174
String *Field_datetime::val_str(String *val_buffer,
184
val_buffer->alloc(DateTime::MAX_STRING_LENGTH);
185
val_buffer->length(DateTime::MAX_STRING_LENGTH);
188
ASSERT_COLUMN_MARKED_FOR_READ;
177
val_buffer->alloc(field_length);
178
val_buffer->length(field_length);
190
184
#ifdef WORDS_BIGENDIAN
191
if (getTable() && getTable()->getShare()->db_low_byte_first)
185
if (table && table->s->db_low_byte_first)
192
186
tmp=sint8korr(ptr);
195
189
int64_tget(tmp,ptr);
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.
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
211
rlen= dt.to_string((char*)val_buffer->ptr(), DateTime::MAX_STRING_LENGTH);
212
assert((rlen+1) < DateTime::MAX_STRING_LENGTH);
214
val_buffer->length(rlen);
192
Avoid problem with slow int64_t arithmetic and sprintf
195
part1=(long) (tmp/INT64_C(1000000));
196
part2=(long) (tmp - (uint64_t) part1*INT64_C(1000000));
198
pos=(char*) val_buffer->ptr() + MAX_DATETIME_WIDTH;
200
*pos--= (char) ('0'+(char) (part2%10)); part2/=10;
201
*pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10);
203
*pos--= (char) ('0'+(char) (part3%10)); part3/=10;
204
*pos--= (char) ('0'+(char) (part3%10)); part3/=10;
206
*pos--= (char) ('0'+(char) (part3%10)); part3/=10;
207
*pos--= (char) ('0'+(char) part3);
209
*pos--= (char) ('0'+(char) (part1%10)); part1/=10;
210
*pos--= (char) ('0'+(char) (part1%10)); part1/=10;
212
*pos--= (char) ('0'+(char) (part1%10)); part1/=10;
213
*pos--= (char) ('0'+(char) (part1%10)); part3= (int) (part1/10);
215
*pos--= (char) ('0'+(char) (part3%10)); part3/=10;
216
*pos--= (char) ('0'+(char) (part3%10)); part3/=10;
217
*pos--= (char) ('0'+(char) (part3%10)); part3/=10;
218
*pos=(char) ('0'+(char) part3);
216
219
return val_buffer;