18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
#include <boost/lexical_cast.hpp>
23
#include <drizzled/field/epoch.h>
22
#include <drizzled/server_includes.h>
23
#include <drizzled/field/timestamp.h>
24
24
#include <drizzled/error.h>
25
25
#include <drizzled/tztime.h>
26
26
#include <drizzled/table.h>
27
27
#include <drizzled/session.h>
33
29
#include "drizzled/temporal.h"
42
33
TIMESTAMP type holds datetime values in range from 1970-01-01 00:00:01 UTC to
81
72
course is non-standard.) In most cases user won't notice any change, only
82
73
exception is different behavior of old/new timestamps during ALTER TABLE.
84
Epoch::Epoch(unsigned char *ptr_arg,
85
unsigned char *null_ptr_arg,
86
unsigned char null_bit_arg,
87
enum utype unireg_check_arg,
88
const char *field_name_arg,
89
drizzled::TableShare *share) :
91
MicroTimestamp::MAX_STRING_LENGTH - 1, /* no \0 */
75
Field_timestamp::Field_timestamp(unsigned char *ptr_arg,
77
unsigned char *null_ptr_arg, unsigned char null_bit_arg,
78
enum utype unireg_check_arg,
79
const char *field_name_arg,
81
const CHARSET_INFO * const cs)
82
:Field_str(ptr_arg, MAX_DATETIME_WIDTH, null_ptr_arg, null_bit_arg,
83
unireg_check_arg, field_name_arg, cs)
97
unireg_check= unireg_check_arg;
98
if (! share->getTimestampField() && unireg_check != NONE)
85
/* For 4.0 MYD and 4.0 InnoDB compatibility */
86
flags|= UNSIGNED_FLAG;
87
if (!share->timestamp_field && unireg_check != NONE)
100
89
/* This timestamp has auto-update */
101
share->setTimestampField(this);
102
flags|= FUNCTION_DEFAULT_FLAG;
90
share->timestamp_field= this;
91
flags|= TIMESTAMP_FLAG;
103
92
if (unireg_check != TIMESTAMP_DN_FIELD)
104
93
flags|= ON_UPDATE_NOW_FLAG;
108
Epoch::Epoch(bool maybe_null_arg,
109
const char *field_name_arg) :
110
Field_str((unsigned char*) NULL,
111
MicroTimestamp::MAX_STRING_LENGTH - 1, /* no \0 */
112
maybe_null_arg ? (unsigned char*) "": 0,
97
Field_timestamp::Field_timestamp(bool maybe_null_arg,
98
const char *field_name_arg,
99
const CHARSET_INFO * const cs)
100
:Field_str((unsigned char*) 0, MAX_DATETIME_WIDTH,
101
maybe_null_arg ? (unsigned char*) "": 0, 0,
102
NONE, field_name_arg, cs)
117
if (unireg_check != TIMESTAMP_DN_FIELD)
118
flags|= ON_UPDATE_NOW_FLAG;
104
/* For 4.0 MYD and 4.0 InnoDB compatibility */
105
flags|= UNSIGNED_FLAG;
106
if (unireg_check != TIMESTAMP_DN_FIELD)
107
flags|= ON_UPDATE_NOW_FLAG;
155
int Epoch::store(const char *from,
157
const CHARSET_INFO * const )
144
int Field_timestamp::store(const char *from,
146
const CHARSET_INFO * const )
161
ASSERT_COLUMN_MARKED_FOR_WRITE;
163
if (not temporal.from_string(from, (size_t) len))
148
drizzled::Timestamp temporal;
150
if (! temporal.from_string(from, (size_t) len))
165
my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
152
my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
170
temporal.to_time_t(tmp);
157
temporal.to_time_t(&tmp);
172
uint64_t time_tmp= tmp;
159
store_timestamp(tmp);
177
int Epoch::store(double from)
163
int Field_timestamp::store(double from)
179
ASSERT_COLUMN_MARKED_FOR_WRITE;
181
uint64_t from_tmp= (uint64_t)from;
184
if (not temporal.from_int64_t(from_tmp))
165
if (from < 0 || from > 99991231235959.0)
186
/* Convert the integer to a string using boost::lexical_cast */
187
std::string tmp(boost::lexical_cast<std::string>(from));
167
/* Convert the double to a string using stringstream */
168
std::stringstream ss;
170
ss.precision(18); /* 18 places should be fine for error display of double input. */
171
ss << from; ss >> tmp;
189
my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
173
my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
194
temporal.to_time_t(tmp);
196
uint64_t tmp_micro= tmp;
202
int Epoch::store_decimal(const type::Decimal *value)
210
int Epoch::store(int64_t from, bool)
212
ASSERT_COLUMN_MARKED_FOR_WRITE;
176
return Field_timestamp::store((int64_t) rint(from), false);
179
int Field_timestamp::store(int64_t from, bool)
215
182
* Try to create a DateTime from the supplied integer. Throw an error
216
183
* if unable to create a valid DateTime.
219
if (not temporal.from_int64_t(from))
185
drizzled::Timestamp temporal;
186
if (! temporal.from_int64_t(from))
221
/* Convert the integer to a string using boost::lexical_cast */
222
std::string tmp(boost::lexical_cast<std::string>(from));
188
/* Convert the integer to a string using stringstream */
189
std::stringstream ss;
191
ss << from; ss >> tmp;
224
my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
193
my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
229
temporal.to_time_t(tmp);
198
temporal.to_time_t(&tmp);
200
store_timestamp(tmp);
237
double Epoch::val_real(void)
204
double Field_timestamp::val_real(void)
239
return (double) Epoch::val_int();
206
return (double) Field_timestamp::val_int();
242
int64_t Epoch::val_int(void)
209
int64_t Field_timestamp::val_int(void)
246
ASSERT_COLUMN_MARKED_FOR_READ;
213
#ifdef WORDS_BIGENDIAN
214
if (table && table->s->db_low_byte_first)
215
temp= uint4korr(ptr);
220
drizzled::Timestamp temporal;
251
221
(void) temporal.from_time_t((time_t) temp);
253
223
/* We must convert into a "timestamp-formatted integer" ... */
259
String *Epoch::val_str(String *val_buffer, String *)
229
String *Field_timestamp::val_str(String *val_buffer, String *)
263
int to_len= field_length + 1;
265
val_buffer->alloc(to_len);
234
val_buffer->alloc(field_length + 1);
266
235
to= (char *) val_buffer->ptr();
237
#ifdef WORDS_BIGENDIAN
238
if (table && table->s->db_low_byte_first)
239
temp= uint4korr(ptr);
270
244
val_buffer->set_charset(&my_charset_bin); /* Safety */
246
drizzled::Timestamp temporal;
273
247
(void) temporal.from_time_t((time_t) temp);
276
rlen= temporal.to_string(to, to_len);
277
assert(rlen < to_len);
279
val_buffer->length(rlen);
250
temporal.to_string(to, &to_len);
251
val_buffer->length((uint32_t) to_len);
280
252
return val_buffer;
283
bool Epoch::get_date(type::Time <ime, uint32_t)
255
bool Field_timestamp::get_date(DRIZZLE_TIME *ltime, uint32_t)
286
type::Time::epoch_t time_temp;
259
#ifdef WORDS_BIGENDIAN
260
if (table && table->s->db_low_byte_first)
261
temp= uint4korr(ptr);
293
ltime.store(time_temp);
266
memset(ltime, 0, sizeof(*ltime));
268
drizzled::Timestamp temporal;
269
(void) temporal.from_time_t((time_t) temp);
271
/* @TODO Goodbye the below code when DRIZZLE_TIME is finally gone.. */
273
ltime->time_type= DRIZZLE_TIMESTAMP_DATETIME;
274
ltime->year= temporal.years();
275
ltime->month= temporal.months();
276
ltime->day= temporal.days();
277
ltime->hour= temporal.hours();
278
ltime->minute= temporal.minutes();
279
ltime->second= temporal.seconds();
298
bool Epoch::get_time(type::Time <ime)
300
return Epoch::get_date(ltime, 0);
303
int Epoch::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
307
unpack_num(a, a_ptr);
308
unpack_num(b, b_ptr);
310
return (a < b) ? -1 : (a > b) ? 1 : 0;
314
void Epoch::sort_string(unsigned char *to,uint32_t )
316
#ifdef WORDS_BIGENDIAN
317
if (!getTable() || !getTable()->getShare()->db_low_byte_first)
284
bool Field_timestamp::get_time(DRIZZLE_TIME *ltime)
286
return Field_timestamp::get_date(ltime,0);
289
int Field_timestamp::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
292
#ifdef WORDS_BIGENDIAN
293
if (table && table->s->db_low_byte_first)
304
return ((uint32_t) a < (uint32_t) b) ? -1 : ((uint32_t) a > (uint32_t) b) ? 1 : 0;
308
void Field_timestamp::sort_string(unsigned char *to,uint32_t )
310
#ifdef WORDS_BIGENDIAN
311
if (!table || !table->s->db_low_byte_first)
342
void Epoch::sql_type(String &res) const
328
void Field_timestamp::sql_type(String &res) const
344
330
res.set_ascii(STRING_WITH_LEN("timestamp"));
347
void Epoch::set_time()
333
void Field_timestamp::set_time()
349
Session *session= getTable() ? getTable()->in_use : current_session;
350
time_t tmp= session->getCurrentTimestampEpoch();
335
Session *session= table ? table->in_use : current_session;
336
long tmp= (long) session->query_start();
353
pack_num(static_cast<uint32_t>(tmp));
338
store_timestamp(tmp);
356
void Epoch::set_default()
341
void Field_timestamp::set_default()
358
if (getTable()->timestamp_field == this &&
343
if (table->timestamp_field == this &&
359
344
unireg_check != TIMESTAMP_UN_FIELD)
365
347
Field::set_default();
369
long Epoch::get_timestamp(bool *null_value)
350
long Field_timestamp::get_timestamp(bool *null_value)
371
352
if ((*null_value= is_null()))
375
return unpack_num(tmp);
354
#ifdef WORDS_BIGENDIAN
355
if (table && table->s->db_low_byte_first)
356
return sint4korr(ptr);
378
size_t Epoch::max_string_length()
363
void Field_timestamp::store_timestamp(time_t timestamp)
380
return sizeof(uint64_t);
365
#ifdef WORDS_BIGENDIAN
366
if (table && table->s->db_low_byte_first)
368
int4store(ptr,timestamp);
372
longstore(ptr,(uint32_t) timestamp);
383
} /* namespace field */
384
} /* namespace drizzled */