18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
#include <boost/lexical_cast.hpp>
24
#include <drizzled/field/epoch.h>
22
#include <drizzled/server_includes.h>
23
#include <drizzled/field/timestamp.h>
25
24
#include <drizzled/error.h>
26
25
#include <drizzled/tztime.h>
27
26
#include <drizzled/table.h>
28
27
#include <drizzled/session.h>
29
#include <drizzled/current_session.h>
35
#include <drizzled/temporal.h>
29
#include "drizzled/temporal.h"
44
33
TIMESTAMP type holds datetime values in range from 1970-01-01 00:00:01 UTC to
83
72
course is non-standard.) In most cases user won't notice any change, only
84
73
exception is different behavior of old/new timestamps during ALTER TABLE.
86
Epoch::Epoch(unsigned char *ptr_arg,
87
unsigned char *null_ptr_arg,
88
unsigned char null_bit_arg,
89
enum utype unireg_check_arg,
90
const char *field_name_arg,
91
drizzled::TableShare *share) :
93
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)
83
drizzled::DateTime::MAX_STRING_LENGTH - 1 /* no \0 */,
84
null_ptr_arg, null_bit_arg,
85
unireg_check_arg, field_name_arg, cs)
99
unireg_check= unireg_check_arg;
100
if (! share->getTimestampField() && unireg_check != NONE)
87
/* For 4.0 MYD and 4.0 InnoDB compatibility */
88
flags|= UNSIGNED_FLAG;
89
if (!share->timestamp_field && unireg_check != NONE)
102
91
/* This timestamp has auto-update */
103
share->setTimestampField(this);
104
flags|= FUNCTION_DEFAULT_FLAG;
92
share->timestamp_field= this;
93
flags|= TIMESTAMP_FLAG;
105
94
if (unireg_check != TIMESTAMP_DN_FIELD)
106
95
flags|= ON_UPDATE_NOW_FLAG;
110
Epoch::Epoch(bool maybe_null_arg,
111
const char *field_name_arg) :
112
Field_str((unsigned char*) NULL,
113
MicroTimestamp::MAX_STRING_LENGTH - 1, /* no \0 */
114
maybe_null_arg ? (unsigned char*) "": 0,
99
Field_timestamp::Field_timestamp(bool maybe_null_arg,
100
const char *field_name_arg,
101
const CHARSET_INFO * const cs)
102
:Field_str((unsigned char*) 0,
103
drizzled::DateTime::MAX_STRING_LENGTH - 1 /* no \0 */,
104
maybe_null_arg ? (unsigned char*) "": 0, 0,
105
NONE, field_name_arg, cs)
119
if (unireg_check != TIMESTAMP_DN_FIELD)
120
flags|= ON_UPDATE_NOW_FLAG;
107
/* For 4.0 MYD and 4.0 InnoDB compatibility */
108
flags|= UNSIGNED_FLAG;
109
if (unireg_check != TIMESTAMP_DN_FIELD)
110
flags|= ON_UPDATE_NOW_FLAG;
157
int Epoch::store(const char *from,
159
const CHARSET_INFO * const )
147
int Field_timestamp::store(const char *from,
149
const CHARSET_INFO * const )
151
drizzled::Timestamp temporal;
163
153
ASSERT_COLUMN_MARKED_FOR_WRITE;
165
if (not temporal.from_string(from, (size_t) len))
155
if (! temporal.from_string(from, (size_t) len))
167
my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
157
my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
172
temporal.to_time_t(tmp);
162
temporal.to_time_t(&tmp);
174
uint64_t time_tmp= tmp;
164
store_timestamp(tmp);
179
int Epoch::store(double from)
168
int Field_timestamp::store(double from)
181
170
ASSERT_COLUMN_MARKED_FOR_WRITE;
183
uint64_t from_tmp= (uint64_t)from;
186
if (not temporal.from_int64_t(from_tmp))
172
if (from < 0 || from > 99991231235959.0)
188
/* Convert the integer to a string using boost::lexical_cast */
189
std::string tmp(boost::lexical_cast<std::string>(from));
174
/* Convert the double to a string using stringstream */
175
std::stringstream ss;
177
ss.precision(18); /* 18 places should be fine for error display of double input. */
178
ss << from; ss >> tmp;
191
my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
180
my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
196
temporal.to_time_t(tmp);
198
uint64_t tmp_micro= tmp;
204
int Epoch::store_decimal(const type::Decimal *value)
212
int Epoch::store(int64_t from, bool)
183
return Field_timestamp::store((int64_t) rint(from), false);
186
int Field_timestamp::store(int64_t from, bool)
214
188
ASSERT_COLUMN_MARKED_FOR_WRITE;
217
191
* Try to create a DateTime from the supplied integer. Throw an error
218
192
* if unable to create a valid DateTime.
221
if (not temporal.from_int64_t(from))
194
drizzled::Timestamp temporal;
195
if (! temporal.from_int64_t(from))
223
/* Convert the integer to a string using boost::lexical_cast */
224
std::string tmp(boost::lexical_cast<std::string>(from));
197
/* Convert the integer to a string using stringstream */
198
std::stringstream ss;
200
ss << from; ss >> tmp;
226
my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
202
my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
231
temporal.to_time_t(tmp);
207
temporal.to_time_t(&tmp);
209
store_timestamp(tmp);
239
double Epoch::val_real(void) const
213
double Field_timestamp::val_real(void)
241
return (double) Epoch::val_int();
215
return (double) Field_timestamp::val_int();
244
int64_t Epoch::val_int(void) const
218
int64_t Field_timestamp::val_int(void)
248
222
ASSERT_COLUMN_MARKED_FOR_READ;
224
#ifdef WORDS_BIGENDIAN
225
if (table && table->s->db_low_byte_first)
226
temp= uint4korr(ptr);
231
drizzled::Timestamp temporal;
253
232
(void) temporal.from_time_t((time_t) temp);
255
234
/* We must convert into a "timestamp-formatted integer" ... */
261
String *Epoch::val_str(String *val_buffer, String *) const
240
String *Field_timestamp::val_str(String *val_buffer, String *)
265
244
int to_len= field_length + 1;
267
246
val_buffer->alloc(to_len);
268
247
to= (char *) val_buffer->ptr();
249
#ifdef WORDS_BIGENDIAN
250
if (table && table->s->db_low_byte_first)
251
temp= uint4korr(ptr);
272
256
val_buffer->set_charset(&my_charset_bin); /* Safety */
258
drizzled::Timestamp temporal;
275
259
(void) temporal.from_time_t((time_t) temp);
282
266
return val_buffer;
285
bool Epoch::get_date(type::Time <ime, uint32_t) const
269
bool Field_timestamp::get_date(DRIZZLE_TIME *ltime, uint32_t)
288
type::Time::epoch_t time_temp;
273
#ifdef WORDS_BIGENDIAN
274
if (table && table->s->db_low_byte_first)
275
temp= uint4korr(ptr);
295
ltime.store(time_temp);
280
memset(ltime, 0, sizeof(*ltime));
282
drizzled::Timestamp temporal;
283
(void) temporal.from_time_t((time_t) temp);
285
/* @TODO Goodbye the below code when DRIZZLE_TIME is finally gone.. */
287
ltime->time_type= DRIZZLE_TIMESTAMP_DATETIME;
288
ltime->year= temporal.years();
289
ltime->month= temporal.months();
290
ltime->day= temporal.days();
291
ltime->hour= temporal.hours();
292
ltime->minute= temporal.minutes();
293
ltime->second= temporal.seconds();
300
bool Epoch::get_time(type::Time <ime) const
302
return Epoch::get_date(ltime, 0);
305
int Epoch::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
309
unpack_num(a, a_ptr);
310
unpack_num(b, b_ptr);
312
return (a < b) ? -1 : (a > b) ? 1 : 0;
316
void Epoch::sort_string(unsigned char *to,uint32_t )
318
#ifdef WORDS_BIGENDIAN
319
if (!getTable() || !getTable()->getShare()->db_low_byte_first)
298
bool Field_timestamp::get_time(DRIZZLE_TIME *ltime)
300
return Field_timestamp::get_date(ltime,0);
303
int Field_timestamp::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
306
#ifdef WORDS_BIGENDIAN
307
if (table && table->s->db_low_byte_first)
318
return ((uint32_t) a < (uint32_t) b) ? -1 : ((uint32_t) a > (uint32_t) b) ? 1 : 0;
322
void Field_timestamp::sort_string(unsigned char *to,uint32_t )
324
#ifdef WORDS_BIGENDIAN
325
if (!table || !table->s->db_low_byte_first)
344
void Epoch::sql_type(String &res) const
342
void Field_timestamp::sql_type(String &res) const
346
344
res.set_ascii(STRING_WITH_LEN("timestamp"));
349
void Epoch::set_time()
347
void Field_timestamp::set_time()
351
Session *session= getTable() ? getTable()->in_use : current_session;
352
time_t tmp= session->getCurrentTimestampEpoch();
349
Session *session= table ? table->in_use : current_session;
350
long tmp= (long) session->query_start();
355
pack_num(static_cast<uint32_t>(tmp));
352
store_timestamp(tmp);
358
void Epoch::set_default()
355
void Field_timestamp::set_default()
360
if (getTable()->timestamp_field == this &&
357
if (table->timestamp_field == this &&
361
358
unireg_check != TIMESTAMP_UN_FIELD)
367
361
Field::set_default();
371
long Epoch::get_timestamp(bool *null_value) const
364
long Field_timestamp::get_timestamp(bool *null_value)
373
366
if ((*null_value= is_null()))
377
return unpack_num(tmp);
368
#ifdef WORDS_BIGENDIAN
369
if (table && table->s->db_low_byte_first)
370
return sint4korr(ptr);
380
size_t Epoch::max_string_length()
377
void Field_timestamp::store_timestamp(time_t timestamp)
382
return sizeof(uint64_t);
379
#ifdef WORDS_BIGENDIAN
380
if (table && table->s->db_low_byte_first)
382
int4store(ptr,timestamp);
386
longstore(ptr,(uint32_t) timestamp);
385
} /* namespace field */
386
} /* namespace drizzled */