1
1
/* -*- mode: c++ c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
4
* Copyright (C) 2008 Sun Microsystems, Inc.
6
6
* This program is free software; you can redistribute it and/or modify
7
7
* it under the terms of the GNU General Public License as published by
18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
21
#include "config.h"
23
#include <drizzled/field/timestamp.h>
22
#include <boost/lexical_cast.hpp>
23
#include <drizzled/field/epoch.h>
24
24
#include <drizzled/error.h>
25
25
#include <drizzled/tztime.h>
26
26
#include <drizzled/table.h>
78
81
course is non-standard.) In most cases user won't notice any change, only
79
82
exception is different behavior of old/new timestamps during ALTER TABLE.
81
Field_timestamp::Field_timestamp(unsigned char *ptr_arg,
83
unsigned char *null_ptr_arg,
84
unsigned char null_bit_arg,
85
enum utype unireg_check_arg,
86
const char *field_name_arg,
88
const CHARSET_INFO * const cs)
90
DateTime::MAX_STRING_LENGTH - 1 /* no \0 */,
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 */
96
/* For 4.0 MYD and 4.0 InnoDB compatibility */
97
flags|= UNSIGNED_FLAG;
98
97
unireg_check= unireg_check_arg;
99
if (! share->timestamp_field && unireg_check != NONE)
98
if (! share->getTimestampField() && unireg_check != NONE)
101
100
/* This timestamp has auto-update */
102
share->timestamp_field= this;
103
flags|= TIMESTAMP_FLAG;
101
share->setTimestampField(this);
102
flags|= FUNCTION_DEFAULT_FLAG;
104
103
if (unireg_check != TIMESTAMP_DN_FIELD)
105
104
flags|= ON_UPDATE_NOW_FLAG;
109
Field_timestamp::Field_timestamp(bool maybe_null_arg,
110
const char *field_name_arg,
111
const CHARSET_INFO * const cs)
112
:Field_str((unsigned char*) NULL,
113
DateTime::MAX_STRING_LENGTH - 1 /* no \0 */,
114
maybe_null_arg ? (unsigned char*) "": 0,
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,
119
/* For 4.0 MYD and 4.0 InnoDB compatibility */
120
flags|= UNSIGNED_FLAG;
121
117
if (unireg_check != TIMESTAMP_DN_FIELD)
122
118
flags|= ON_UPDATE_NOW_FLAG;
159
int Field_timestamp::store(const char *from,
161
const CHARSET_INFO * const )
155
int Epoch::store(const char *from,
157
const CHARSET_INFO * const )
163
159
Timestamp temporal;
165
161
ASSERT_COLUMN_MARKED_FOR_WRITE;
167
if (! temporal.from_string(from, (size_t) len))
163
if (not temporal.from_string(from, (size_t) len))
169
165
my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
174
temporal.to_time_t(&tmp);
170
temporal.to_time_t(tmp);
176
store_timestamp(tmp);
172
uint64_t time_tmp= tmp;
180
int Field_timestamp::store(double from)
177
int Epoch::store(double from)
182
179
ASSERT_COLUMN_MARKED_FOR_WRITE;
187
184
std::stringstream ss;
189
186
ss.precision(18); /* 18 places should be fine for error display of double input. */
190
ss << from; ss >> tmp;
192
190
my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
195
return Field_timestamp::store((int64_t) rint(from), false);
193
return Epoch::store((int64_t) rint(from), false);
198
int Field_timestamp::store(int64_t from, bool)
196
int Epoch::store(int64_t from, bool)
200
198
ASSERT_COLUMN_MARKED_FOR_WRITE;
206
204
Timestamp temporal;
207
205
if (! temporal.from_int64_t(from))
209
/* Convert the integer to a string using stringstream */
210
std::stringstream ss;
212
ss << from; ss >> tmp;
207
/* Convert the integer to a string using boost::lexical_cast */
208
std::string tmp(boost::lexical_cast<std::string>(from));
214
210
my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
219
temporal.to_time_t(&tmp);
221
store_timestamp(tmp);
215
temporal.to_time_t(tmp);
225
double Field_timestamp::val_real(void)
223
double Epoch::val_real(void)
227
return (double) Field_timestamp::val_int();
225
return (double) Epoch::val_int();
230
int64_t Field_timestamp::val_int(void)
228
int64_t Epoch::val_int(void)
234
232
ASSERT_COLUMN_MARKED_FOR_READ;
236
#ifdef WORDS_BIGENDIAN
237
if (table && table->s->db_low_byte_first)
238
temp= uint4korr(ptr);
243
236
Timestamp temporal;
244
237
(void) temporal.from_time_t((time_t) temp);
252
String *Field_timestamp::val_str(String *val_buffer, String *)
245
String *Epoch::val_str(String *val_buffer, String *)
256
249
int to_len= field_length + 1;
258
251
val_buffer->alloc(to_len);
259
252
to= (char *) val_buffer->ptr();
261
#ifdef WORDS_BIGENDIAN
262
if (table && table->s->db_low_byte_first)
263
temp= uint4korr(ptr);
268
256
val_buffer->set_charset(&my_charset_bin); /* Safety */
278
266
return val_buffer;
281
bool Field_timestamp::get_date(DRIZZLE_TIME *ltime, uint32_t)
269
bool Epoch::get_date(type::Time *ltime, uint32_t)
285
#ifdef WORDS_BIGENDIAN
286
if (table && table->s->db_low_byte_first)
287
temp= uint4korr(ptr);
292
275
memset(ltime, 0, sizeof(*ltime));
294
277
Timestamp temporal;
295
278
(void) temporal.from_time_t((time_t) temp);
297
/* @TODO Goodbye the below code when DRIZZLE_TIME is finally gone.. */
280
/* @TODO Goodbye the below code when type::Time is finally gone.. */
299
282
ltime->time_type= DRIZZLE_TIMESTAMP_DATETIME;
300
283
ltime->year= temporal.years();
310
bool Field_timestamp::get_time(DRIZZLE_TIME *ltime)
312
return Field_timestamp::get_date(ltime,0);
315
int Field_timestamp::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
318
#ifdef WORDS_BIGENDIAN
319
if (table && table->s->db_low_byte_first)
330
return ((uint32_t) a < (uint32_t) b) ? -1 : ((uint32_t) a > (uint32_t) b) ? 1 : 0;
334
void Field_timestamp::sort_string(unsigned char *to,uint32_t )
336
#ifdef WORDS_BIGENDIAN
337
if (!table || !table->s->db_low_byte_first)
293
bool Epoch::get_time(type::Time *ltime)
295
return Epoch::get_date(ltime,0);
298
int Epoch::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
302
unpack_num(a, a_ptr);
303
unpack_num(b, b_ptr);
305
return (a < b) ? -1 : (a > b) ? 1 : 0;
309
void Epoch::sort_string(unsigned char *to,uint32_t )
311
#ifdef WORDS_BIGENDIAN
312
if (!getTable() || !getTable()->getShare()->db_low_byte_first)
354
void Field_timestamp::sql_type(String &res) const
337
void Epoch::sql_type(String &res) const
356
339
res.set_ascii(STRING_WITH_LEN("timestamp"));
359
void Field_timestamp::set_time()
342
void Epoch::set_time()
361
Session *session= table ? table->in_use : current_session;
362
long tmp= (long) session->query_start();
344
Session *session= getTable() ? getTable()->in_use : current_session;
345
time_t tmp= session->getCurrentTimestampEpoch();
364
store_timestamp(tmp);
348
pack_num(static_cast<uint32_t>(tmp));
367
void Field_timestamp::set_default()
351
void Epoch::set_default()
369
if (table->timestamp_field == this &&
353
if (getTable()->timestamp_field == this &&
370
354
unireg_check != TIMESTAMP_UN_FIELD)
373
360
Field::set_default();
376
long Field_timestamp::get_timestamp(bool *null_value)
364
long Epoch::get_timestamp(bool *null_value)
378
366
if ((*null_value= is_null()))
380
#ifdef WORDS_BIGENDIAN
381
if (table && table->s->db_low_byte_first)
382
return sint4korr(ptr);
370
return unpack_num(tmp);
389
void Field_timestamp::store_timestamp(time_t timestamp)
373
size_t Epoch::max_string_length()
391
#ifdef WORDS_BIGENDIAN
392
if (table && table->s->db_low_byte_first)
394
int4store(ptr,timestamp);
398
longstore(ptr,(uint32_t) timestamp);
375
return sizeof(uint64_t);
378
} /* namespace field */
401
379
} /* namespace drizzled */