~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/timestamp.cc

  • Committer: Brian Aker
  • Date: 2009-03-12 14:38:12 UTC
  • mfrom: (910.4.20 sparc)
  • Revision ID: brian@tangent.org-20090312143812-g02zsr6krx54nxjp
Merge from Stewart.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
19
 */
20
20
 
21
 
#include "config.h"
22
 
#include <boost/lexical_cast.hpp>
 
21
 
 
22
#include <drizzled/server_includes.h>
23
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>
28
28
 
29
 
#include <math.h>
30
 
 
31
 
#include <sstream>
32
 
 
33
29
#include "drizzled/temporal.h"
34
30
 
35
 
namespace drizzled
36
 
{
37
31
 
38
32
/**
39
33
  TIMESTAMP type holds datetime values in range from 1970-01-01 00:00:01 UTC to
79
73
  exception is different behavior of old/new timestamps during ALTER TABLE.
80
74
 */
81
75
Field_timestamp::Field_timestamp(unsigned char *ptr_arg,
82
 
                                 uint32_t,
83
 
                                 unsigned char *null_ptr_arg,
84
 
                                 unsigned char null_bit_arg,
 
76
                                 uint32_t ,
 
77
                                 unsigned char *null_ptr_arg, unsigned char null_bit_arg,
85
78
                                 enum utype unireg_check_arg,
86
79
                                 const char *field_name_arg,
87
 
                                 TableShare *share,
 
80
                                 TABLE_SHARE *share,
88
81
                                 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)
 
82
  :Field_str(ptr_arg, MAX_DATETIME_WIDTH, null_ptr_arg, null_bit_arg,
 
83
             unireg_check_arg, field_name_arg, cs)
95
84
{
96
85
  /* For 4.0 MYD and 4.0 InnoDB compatibility */
97
86
  flags|= UNSIGNED_FLAG;
98
 
  unireg_check= unireg_check_arg;
99
 
  if (! share->getTimestampField() && unireg_check != NONE)
 
87
  if (!share->timestamp_field && unireg_check != NONE)
100
88
  {
101
89
    /* This timestamp has auto-update */
102
 
    share->setTimestampField(this);
103
 
    flags|= FUNCTION_DEFAULT_FLAG;
 
90
    share->timestamp_field= this;
 
91
    flags|= TIMESTAMP_FLAG;
104
92
    if (unireg_check != TIMESTAMP_DN_FIELD)
105
93
      flags|= ON_UPDATE_NOW_FLAG;
106
94
  }
109
97
Field_timestamp::Field_timestamp(bool maybe_null_arg,
110
98
                                 const char *field_name_arg,
111
99
                                 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)
 
100
  :Field_str((unsigned char*) 0, MAX_DATETIME_WIDTH,
 
101
             maybe_null_arg ? (unsigned char*) "": 0, 0,
 
102
             NONE, field_name_arg, cs)
118
103
{
119
104
  /* For 4.0 MYD and 4.0 InnoDB compatibility */
120
105
  flags|= UNSIGNED_FLAG;
121
 
  if (unireg_check != TIMESTAMP_DN_FIELD)
122
 
    flags|= ON_UPDATE_NOW_FLAG;
 
106
    if (unireg_check != TIMESTAMP_DN_FIELD)
 
107
      flags|= ON_UPDATE_NOW_FLAG;
123
108
}
124
109
 
125
110
/**
142
127
      function should be called only for first of them (i.e. the one
143
128
      having auto-set property).
144
129
    */
145
 
    assert(getTable()->timestamp_field == this);
 
130
    assert(table->timestamp_field == this);
146
131
    /* Fall-through */
147
132
  case TIMESTAMP_DNUN_FIELD:
148
133
    return TIMESTAMP_AUTO_SET_ON_BOTH;
160
145
                           uint32_t len,
161
146
                           const CHARSET_INFO * const )
162
147
{
163
 
  Timestamp temporal;
164
 
 
165
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
 
148
  drizzled::Timestamp temporal;
166
149
 
167
150
  if (! temporal.from_string(from, (size_t) len))
168
151
  {
179
162
 
180
163
int Field_timestamp::store(double from)
181
164
{
182
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
183
 
 
184
165
  if (from < 0 || from > 99991231235959.0)
185
166
  {
186
167
    /* Convert the double to a string using stringstream */
187
168
    std::stringstream ss;
188
169
    std::string tmp;
189
170
    ss.precision(18); /* 18 places should be fine for error display of double input. */
190
 
    ss << from; 
191
 
    ss >> tmp;
 
171
    ss << from; ss >> tmp;
192
172
 
193
173
    my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
194
174
    return 2;
198
178
 
199
179
int Field_timestamp::store(int64_t from, bool)
200
180
{
201
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
202
 
 
203
181
  /* 
204
182
   * Try to create a DateTime from the supplied integer.  Throw an error
205
183
   * if unable to create a valid DateTime.  
206
184
   */
207
 
  Timestamp temporal;
 
185
  drizzled::Timestamp temporal;
208
186
  if (! temporal.from_int64_t(from))
209
187
  {
210
 
    /* Convert the integer to a string using boost::lexical_cast */
211
 
    std::string tmp(boost::lexical_cast<std::string>(from));
 
188
    /* Convert the integer to a string using stringstream */
 
189
    std::stringstream ss;
 
190
    std::string tmp;
 
191
    ss << from; ss >> tmp;
212
192
 
213
193
    my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
214
194
    return 2;
228
208
 
229
209
int64_t Field_timestamp::val_int(void)
230
210
{
231
 
  uint64_t temp;
232
 
 
233
 
  ASSERT_COLUMN_MARKED_FOR_READ;
 
211
  uint32_t temp;
234
212
 
235
213
#ifdef WORDS_BIGENDIAN
236
 
  if (getTable() && getTable()->getShare()->db_low_byte_first)
237
 
    temp= uint8korr(ptr);
 
214
  if (table && table->s->db_low_byte_first)
 
215
    temp= uint4korr(ptr);
238
216
  else
239
217
#endif
240
 
    int64_tget(temp, ptr);
 
218
    longget(temp, ptr);
241
219
 
242
 
  Timestamp temporal;
 
220
  drizzled::Timestamp temporal;
243
221
  (void) temporal.from_time_t((time_t) temp);
244
222
 
245
223
  /* We must convert into a "timestamp-formatted integer" ... */
250
228
 
251
229
String *Field_timestamp::val_str(String *val_buffer, String *)
252
230
{
253
 
  uint64_t temp;
 
231
  uint32_t temp;
254
232
  char *to;
255
 
  int to_len= field_length + 1;
256
233
 
257
 
  val_buffer->alloc(to_len);
 
234
  val_buffer->alloc(field_length + 1);
258
235
  to= (char *) val_buffer->ptr();
259
236
 
260
237
#ifdef WORDS_BIGENDIAN
261
 
  if (getTable() && getTable()->getShare()->db_low_byte_first)
262
 
    temp= uint8korr(ptr);
 
238
  if (table && table->s->db_low_byte_first)
 
239
    temp= uint4korr(ptr);
263
240
  else
264
241
#endif
265
 
    int64_tget(temp, ptr);
 
242
    longget(temp, ptr);
266
243
 
267
244
  val_buffer->set_charset(&my_charset_bin);     /* Safety */
268
245
 
269
 
  Timestamp temporal;
 
246
  drizzled::Timestamp temporal;
270
247
  (void) temporal.from_time_t((time_t) temp);
271
 
 
272
 
  int rlen;
273
 
  rlen= temporal.to_string(to, to_len);
274
 
  assert(rlen < to_len);
275
 
 
276
 
  val_buffer->length(rlen);
 
248
  size_t to_len;
 
249
 
 
250
  temporal.to_string(to, &to_len);
 
251
  val_buffer->length((uint32_t) to_len);
277
252
  return val_buffer;
278
253
}
279
254
 
280
255
bool Field_timestamp::get_date(DRIZZLE_TIME *ltime, uint32_t)
281
256
{
282
 
  uint64_t temp;
 
257
  uint32_t temp;
283
258
 
284
259
#ifdef WORDS_BIGENDIAN
285
 
  if (getTable() && getTable()->getShare()->db_low_byte_first)
286
 
    temp= uint8korr(ptr);
 
260
  if (table && table->s->db_low_byte_first)
 
261
    temp= uint4korr(ptr);
287
262
  else
288
263
#endif
289
 
    int64_tget(temp, ptr);
 
264
    longget(temp, ptr);
290
265
  
291
266
  memset(ltime, 0, sizeof(*ltime));
292
267
 
293
 
  Timestamp temporal;
 
268
  drizzled::Timestamp temporal;
294
269
  (void) temporal.from_time_t((time_t) temp);
295
270
 
296
271
  /* @TODO Goodbye the below code when DRIZZLE_TIME is finally gone.. */
313
288
 
314
289
int Field_timestamp::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
315
290
{
316
 
  int64_t a,b;
 
291
  int32_t a,b;
317
292
#ifdef WORDS_BIGENDIAN
318
 
  if (getTable() && getTable()->getShare()->db_low_byte_first)
 
293
  if (table && table->s->db_low_byte_first)
319
294
  {
320
 
    a=sint8korr(a_ptr);
321
 
    b=sint8korr(b_ptr);
 
295
    a=sint4korr(a_ptr);
 
296
    b=sint4korr(b_ptr);
322
297
  }
323
298
  else
324
299
#endif
325
300
  {
326
 
    int64_tget(a, a_ptr);
327
 
    int64_tget(b, b_ptr);
 
301
  longget(a,a_ptr);
 
302
  longget(b,b_ptr);
328
303
  }
329
 
  return ((uint64_t) a < (uint64_t) b) ? -1 : ((uint64_t) a > (uint64_t) b) ? 1 : 0;
 
304
  return ((uint32_t) a < (uint32_t) b) ? -1 : ((uint32_t) a > (uint32_t) b) ? 1 : 0;
330
305
}
331
306
 
332
307
 
333
308
void Field_timestamp::sort_string(unsigned char *to,uint32_t )
334
309
{
335
310
#ifdef WORDS_BIGENDIAN
336
 
  if (!getTable() || !getTable()->getShare()->db_low_byte_first)
 
311
  if (!table || !table->s->db_low_byte_first)
337
312
  {
338
313
    to[0] = ptr[0];
339
314
    to[1] = ptr[1];
340
315
    to[2] = ptr[2];
341
316
    to[3] = ptr[3];
342
 
    to[4] = ptr[4];
343
 
    to[5] = ptr[5];
344
 
    to[6] = ptr[6];
345
 
    to[7] = ptr[7];
346
317
  }
347
318
  else
348
319
#endif
349
320
  {
350
 
    to[0] = ptr[7];
351
 
    to[1] = ptr[6];
352
 
    to[2] = ptr[5];
353
 
    to[3] = ptr[4];
354
 
    to[4] = ptr[3];
355
 
    to[5] = ptr[2];
356
 
    to[6] = ptr[1];
357
 
    to[7] = ptr[0];
 
321
    to[0] = ptr[3];
 
322
    to[1] = ptr[2];
 
323
    to[2] = ptr[1];
 
324
    to[3] = ptr[0];
358
325
  }
359
326
}
360
327
 
365
332
 
366
333
void Field_timestamp::set_time()
367
334
{
368
 
  Session *session= getTable() ? getTable()->in_use : current_session;
369
 
  time_t tmp= session->query_start();
 
335
  Session *session= table ? table->in_use : current_session;
 
336
  long tmp= (long) session->query_start();
370
337
  set_notnull();
371
338
  store_timestamp(tmp);
372
339
}
373
340
 
374
341
void Field_timestamp::set_default()
375
342
{
376
 
  if (getTable()->timestamp_field == this &&
 
343
  if (table->timestamp_field == this &&
377
344
      unireg_check != TIMESTAMP_UN_FIELD)
378
345
    set_time();
379
346
  else
385
352
  if ((*null_value= is_null()))
386
353
    return 0;
387
354
#ifdef WORDS_BIGENDIAN
388
 
  if (getTable() && getTable()->getShare()->db_low_byte_first)
389
 
    return sint8korr(ptr);
 
355
  if (table && table->s->db_low_byte_first)
 
356
    return sint4korr(ptr);
390
357
#endif
391
 
  int64_t tmp;
392
 
  int64_tget(tmp, ptr);
 
358
  long tmp;
 
359
  longget(tmp,ptr);
393
360
  return tmp;
394
361
}
395
362
 
396
 
void Field_timestamp::store_timestamp(int64_t timestamp)
 
363
void Field_timestamp::store_timestamp(time_t timestamp)
397
364
{
398
365
#ifdef WORDS_BIGENDIAN
399
 
  if (getTable() && getTable()->getShare()->db_low_byte_first)
 
366
  if (table && table->s->db_low_byte_first)
400
367
  {
401
 
    int8store(ptr, timestamp);
 
368
    int4store(ptr,timestamp);
402
369
  }
403
370
  else
404
371
#endif
405
 
    int64_tstore(ptr, timestamp);
 
372
    longstore(ptr,(uint32_t) timestamp);
406
373
}
407
 
 
408
 
} /* namespace drizzled */