~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/epoch.cc

  • Committer: Monty Taylor
  • Date: 2011-02-13 17:24:18 UTC
  • mfrom: (2159.1.1 remove-lint)
  • mto: This revision was merged to the branch mainline in revision 2166.
  • Revision ID: mordred@inaugust.com-20110213172418-vd210j88hiwk8jih
Removed the lint stuff.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++ c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems
 
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
5
 *
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
19
19
 */
20
20
 
21
 
 
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>
35
35
namespace drizzled
36
36
{
37
37
 
 
38
namespace field
 
39
{
 
40
 
38
41
/**
39
42
  TIMESTAMP type holds datetime values in range from 1970-01-01 00:00:01 UTC to
40
43
  2038-01-01 00:00:00 UTC stored as number of seconds since Unix
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.
80
83
 */
81
 
Field_timestamp::Field_timestamp(unsigned char *ptr_arg,
82
 
                                 uint32_t,
83
 
                                 unsigned char *null_ptr_arg,
84
 
                                 unsigned char null_bit_arg,
85
 
                                 enum utype unireg_check_arg,
86
 
                                 const char *field_name_arg,
87
 
                                 TableShare *share,
88
 
                                 const CHARSET_INFO * const cs)
89
 
  :Field_str(ptr_arg,
90
 
             DateTime::MAX_STRING_LENGTH - 1 /* no \0 */,
91
 
             null_ptr_arg,
92
 
             null_bit_arg,
93
 
             field_name_arg,
94
 
             cs)
 
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) :
 
90
  Field_str(ptr_arg,
 
91
            MicroTimestamp::MAX_STRING_LENGTH - 1, /* no \0 */
 
92
            null_ptr_arg,
 
93
            null_bit_arg,
 
94
            field_name_arg,
 
95
            &my_charset_bin)
95
96
{
96
 
  /* For 4.0 MYD and 4.0 InnoDB compatibility */
97
 
  flags|= UNSIGNED_FLAG;
98
97
  unireg_check= unireg_check_arg;
99
98
  if (! share->getTimestampField() && unireg_check != NONE)
100
99
  {
101
100
    /* This timestamp has auto-update */
102
101
    share->setTimestampField(this);
103
 
    flags|= TIMESTAMP_FLAG;
 
102
    flags|= FUNCTION_DEFAULT_FLAG;
104
103
    if (unireg_check != TIMESTAMP_DN_FIELD)
105
104
      flags|= ON_UPDATE_NOW_FLAG;
106
105
  }
107
106
}
108
107
 
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,
115
 
             0,
116
 
             field_name_arg,
117
 
             cs)
 
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,
 
113
            0,
 
114
            field_name_arg,
 
115
            &my_charset_bin)
118
116
{
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;
123
119
}
128
124
  Returns value indicating during which operations this TIMESTAMP field
129
125
  should be auto-set to current timestamp.
130
126
*/
131
 
timestamp_auto_set_type Field_timestamp::get_auto_set_type() const
 
127
timestamp_auto_set_type Epoch::get_auto_set_type() const
132
128
{
133
129
  switch (unireg_check)
134
130
  {
156
152
  }
157
153
}
158
154
 
159
 
int Field_timestamp::store(const char *from,
160
 
                           uint32_t len,
161
 
                           const CHARSET_INFO * const )
 
155
int Epoch::store(const char *from,
 
156
                 uint32_t len,
 
157
                 const CHARSET_INFO * const )
162
158
{
163
159
  Timestamp temporal;
164
160
 
165
161
  ASSERT_COLUMN_MARKED_FOR_WRITE;
166
162
 
167
 
  if (! temporal.from_string(from, (size_t) len))
 
163
  if (not temporal.from_string(from, (size_t) len))
168
164
  {
169
 
    my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
 
165
    my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
170
166
    return 1;
171
167
  }
172
168
 
173
169
  time_t tmp;
174
 
  temporal.to_time_t(&tmp);
 
170
  temporal.to_time_t(tmp);
175
171
 
176
 
  store_timestamp(tmp);
 
172
  uint64_t time_tmp= tmp;
 
173
  pack_num(time_tmp);
177
174
  return 0;
178
175
}
179
176
 
180
 
int Field_timestamp::store(double from)
 
177
int Epoch::store(double from)
181
178
{
182
179
  ASSERT_COLUMN_MARKED_FOR_WRITE;
183
180
 
184
 
  if (from < 0 || from > 99991231235959.0)
 
181
  uint64_t from_tmp= (uint64_t)from;
 
182
 
 
183
  Timestamp temporal;
 
184
  if (not temporal.from_int64_t(from_tmp))
185
185
  {
186
 
    /* Convert the double to a string using stringstream */
187
 
    std::stringstream ss;
188
 
    std::string tmp;
189
 
    ss.precision(18); /* 18 places should be fine for error display of double input. */
190
 
    ss << from; ss >> tmp;
 
186
    /* Convert the integer to a string using boost::lexical_cast */
 
187
    std::string tmp(boost::lexical_cast<std::string>(from));
191
188
 
192
 
    my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
 
189
    my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
193
190
    return 2;
194
191
  }
195
 
  return Field_timestamp::store((int64_t) rint(from), false);
196
 
}
197
 
 
198
 
int Field_timestamp::store(int64_t from, bool)
 
192
 
 
193
  time_t tmp;
 
194
  temporal.to_time_t(tmp);
 
195
 
 
196
  uint64_t tmp_micro= tmp;
 
197
  pack_num(tmp_micro);
 
198
 
 
199
  return 0;
 
200
}
 
201
 
 
202
int Epoch::store_decimal(const type::Decimal *value)
 
203
{
 
204
  double tmp;
 
205
  value->convert(tmp);
 
206
 
 
207
  return store(tmp);
 
208
}
 
209
 
 
210
int Epoch::store(int64_t from, bool)
199
211
{
200
212
  ASSERT_COLUMN_MARKED_FOR_WRITE;
201
213
 
204
216
   * if unable to create a valid DateTime.  
205
217
   */
206
218
  Timestamp temporal;
207
 
  if (! temporal.from_int64_t(from))
 
219
  if (not temporal.from_int64_t(from))
208
220
  {
209
 
    /* Convert the integer to a string using stringstream */
210
 
    std::stringstream ss;
211
 
    std::string tmp;
212
 
    ss << from; ss >> tmp;
 
221
    /* Convert the integer to a string using boost::lexical_cast */
 
222
    std::string tmp(boost::lexical_cast<std::string>(from));
213
223
 
214
 
    my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
 
224
    my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
215
225
    return 2;
216
226
  }
217
227
 
218
228
  time_t tmp;
219
 
  temporal.to_time_t(&tmp);
220
 
 
221
 
  store_timestamp(tmp);
 
229
  temporal.to_time_t(tmp);
 
230
 
 
231
  uint64_t tmp64= tmp;
 
232
  pack_num(tmp64);
 
233
 
222
234
  return 0;
223
235
}
224
236
 
225
 
double Field_timestamp::val_real(void)
 
237
double Epoch::val_real(void)
226
238
{
227
 
  return (double) Field_timestamp::val_int();
 
239
  return (double) Epoch::val_int();
228
240
}
229
241
 
230
 
int64_t Field_timestamp::val_int(void)
 
242
int64_t Epoch::val_int(void)
231
243
{
232
 
  uint32_t temp;
 
244
  uint64_t temp;
233
245
 
234
246
  ASSERT_COLUMN_MARKED_FOR_READ;
235
247
 
236
 
#ifdef WORDS_BIGENDIAN
237
 
  if (getTable() && getTable()->s->db_low_byte_first)
238
 
    temp= uint4korr(ptr);
239
 
  else
240
 
#endif
241
 
    longget(temp, ptr);
 
248
  unpack_num(temp);
242
249
 
243
250
  Timestamp temporal;
244
251
  (void) temporal.from_time_t((time_t) temp);
249
256
  return result;
250
257
}
251
258
 
252
 
String *Field_timestamp::val_str(String *val_buffer, String *)
 
259
String *Epoch::val_str(String *val_buffer, String *)
253
260
{
254
 
  uint32_t temp;
 
261
  uint64_t temp= 0;
255
262
  char *to;
256
263
  int to_len= field_length + 1;
257
264
 
258
265
  val_buffer->alloc(to_len);
259
266
  to= (char *) val_buffer->ptr();
260
267
 
261
 
#ifdef WORDS_BIGENDIAN
262
 
  if (getTable() && getTable()->s->db_low_byte_first)
263
 
    temp= uint4korr(ptr);
264
 
  else
265
 
#endif
266
 
    longget(temp, ptr);
 
268
  unpack_num(temp);
267
269
 
268
270
  val_buffer->set_charset(&my_charset_bin);     /* Safety */
269
271
 
278
280
  return val_buffer;
279
281
}
280
282
 
281
 
bool Field_timestamp::get_date(DRIZZLE_TIME *ltime, uint32_t)
 
283
bool Epoch::get_date(type::Time &ltime, uint32_t)
282
284
{
283
 
  uint32_t temp;
 
285
  uint64_t temp;
 
286
  type::Time::epoch_t time_temp;
284
287
 
285
 
#ifdef WORDS_BIGENDIAN
286
 
  if (getTable() && getTable()->s->db_low_byte_first)
287
 
    temp= uint4korr(ptr);
288
 
  else
289
 
#endif
290
 
    longget(temp, ptr);
 
288
  unpack_num(temp);
 
289
  time_temp= temp;
291
290
  
292
 
  memset(ltime, 0, sizeof(*ltime));
293
 
 
294
 
  Timestamp temporal;
295
 
  (void) temporal.from_time_t((time_t) temp);
296
 
 
297
 
  /* @TODO Goodbye the below code when DRIZZLE_TIME is finally gone.. */
298
 
 
299
 
  ltime->time_type= DRIZZLE_TIMESTAMP_DATETIME;
300
 
  ltime->year= temporal.years();
301
 
  ltime->month= temporal.months();
302
 
  ltime->day= temporal.days();
303
 
  ltime->hour= temporal.hours();
304
 
  ltime->minute= temporal.minutes();
305
 
  ltime->second= temporal.seconds();
 
291
  ltime.reset();
 
292
 
 
293
  ltime.store(time_temp);
306
294
 
307
295
  return 0;
308
296
}
309
297
 
310
 
bool Field_timestamp::get_time(DRIZZLE_TIME *ltime)
311
 
{
312
 
  return Field_timestamp::get_date(ltime,0);
313
 
}
314
 
 
315
 
int Field_timestamp::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
316
 
{
317
 
  int32_t a,b;
318
 
#ifdef WORDS_BIGENDIAN
319
 
  if (getTable() && getTable()->s->db_low_byte_first)
320
 
  {
321
 
    a=sint4korr(a_ptr);
322
 
    b=sint4korr(b_ptr);
323
 
  }
324
 
  else
325
 
#endif
326
 
  {
327
 
  longget(a,a_ptr);
328
 
  longget(b,b_ptr);
329
 
  }
330
 
  return ((uint32_t) a < (uint32_t) b) ? -1 : ((uint32_t) a > (uint32_t) b) ? 1 : 0;
331
 
}
332
 
 
333
 
 
334
 
void Field_timestamp::sort_string(unsigned char *to,uint32_t )
335
 
{
336
 
#ifdef WORDS_BIGENDIAN
337
 
  if (!getTable() || !getTable()->s->db_low_byte_first)
 
298
bool Epoch::get_time(type::Time &ltime)
 
299
{
 
300
  return Epoch::get_date(ltime, 0);
 
301
}
 
302
 
 
303
int Epoch::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
 
304
{
 
305
  uint64_t a,b;
 
306
 
 
307
  unpack_num(a, a_ptr);
 
308
  unpack_num(b, b_ptr);
 
309
 
 
310
  return (a < b) ? -1 : (a > b) ? 1 : 0;
 
311
}
 
312
 
 
313
 
 
314
void Epoch::sort_string(unsigned char *to,uint32_t )
 
315
{
 
316
#ifdef WORDS_BIGENDIAN
 
317
  if (!getTable() || !getTable()->getShare()->db_low_byte_first)
338
318
  {
339
319
    to[0] = ptr[0];
340
320
    to[1] = ptr[1];
341
321
    to[2] = ptr[2];
342
322
    to[3] = ptr[3];
 
323
    to[4] = ptr[4];
 
324
    to[5] = ptr[5];
 
325
    to[6] = ptr[6];
 
326
    to[7] = ptr[7];
343
327
  }
344
328
  else
345
329
#endif
346
330
  {
347
 
    to[0] = ptr[3];
348
 
    to[1] = ptr[2];
349
 
    to[2] = ptr[1];
350
 
    to[3] = ptr[0];
 
331
    to[0] = ptr[7];
 
332
    to[1] = ptr[6];
 
333
    to[2] = ptr[5];
 
334
    to[3] = ptr[4];
 
335
    to[4] = ptr[3];
 
336
    to[5] = ptr[2];
 
337
    to[6] = ptr[1];
 
338
    to[7] = ptr[0];
351
339
  }
352
340
}
353
341
 
354
 
void Field_timestamp::sql_type(String &res) const
 
342
void Epoch::sql_type(String &res) const
355
343
{
356
344
  res.set_ascii(STRING_WITH_LEN("timestamp"));
357
345
}
358
346
 
359
 
void Field_timestamp::set_time()
 
347
void Epoch::set_time()
360
348
{
361
349
  Session *session= getTable() ? getTable()->in_use : current_session;
362
 
  long tmp= (long) session->query_start();
 
350
  time_t tmp= session->getCurrentTimestampEpoch();
 
351
 
363
352
  set_notnull();
364
 
  store_timestamp(tmp);
 
353
  pack_num(static_cast<uint32_t>(tmp));
365
354
}
366
355
 
367
 
void Field_timestamp::set_default()
 
356
void Epoch::set_default()
368
357
{
369
358
  if (getTable()->timestamp_field == this &&
370
359
      unireg_check != TIMESTAMP_UN_FIELD)
 
360
  {
371
361
    set_time();
 
362
  }
372
363
  else
 
364
  {
373
365
    Field::set_default();
 
366
  }
374
367
}
375
368
 
376
 
long Field_timestamp::get_timestamp(bool *null_value)
 
369
long Epoch::get_timestamp(bool *null_value)
377
370
{
378
371
  if ((*null_value= is_null()))
379
372
    return 0;
380
 
#ifdef WORDS_BIGENDIAN
381
 
  if (getTable() && getTable()->s->db_low_byte_first)
382
 
    return sint4korr(ptr);
383
 
#endif
384
 
  long tmp;
385
 
  longget(tmp,ptr);
386
 
  return tmp;
 
373
 
 
374
  uint64_t tmp;
 
375
  return unpack_num(tmp);
387
376
}
388
377
 
389
 
void Field_timestamp::store_timestamp(time_t timestamp)
 
378
size_t Epoch::max_string_length()
390
379
{
391
 
#ifdef WORDS_BIGENDIAN
392
 
  if (getTable() && getTable()->s->db_low_byte_first)
393
 
  {
394
 
    int4store(ptr,timestamp);
395
 
  }
396
 
  else
397
 
#endif
398
 
    longstore(ptr,(uint32_t) timestamp);
 
380
  return sizeof(uint64_t);
399
381
}
400
382
 
 
383
} /* namespace field */
401
384
} /* namespace drizzled */