~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/temporal.h

  • Committer: Brian Aker
  • Date: 2009-01-28 08:27:13 UTC
  • mfrom: (813.1.7 new-temporal)
  • Revision ID: brian@tangent.org-20090128082713-13yfi46omee0wbpx
Import work from Jay

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems
 
5
 *
 
6
 *  Authors:
 
7
 *
 
8
 *  Jay Pipes <jay.pipes@sun.com>
 
9
 *
 
10
 *  This program is free software; you can redistribute it and/or modify
 
11
 *  it under the terms of the GNU General Public License as published by
 
12
 *  the Free Software Foundation; either version 2 of the License, or
 
13
 *  (at your option) any later version.
 
14
 *
 
15
 *  This program is distributed in the hope that it will be useful,
 
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
 *  GNU General Public License for more details.
 
19
 *
 
20
 *  You should have received a copy of the GNU General Public License
 
21
 *  along with this program; if not, write to the Free Software
 
22
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
23
 */
 
24
 
 
25
/**
 
26
 * @file 
 
27
 *
 
28
 * Defines the API for dealing with temporal data inside the server.
 
29
 *
 
30
 * The Temporal class is the base class for all data of any temporal
 
31
 * type.  A number of derived classes define specialized classes 
 
32
 * representng various date, date-time, time, or timestamp types.
 
33
 *
 
34
 * All Temporal derived classes are ValueObjects.  That is to say that
 
35
 * Temporal class instances are not part of the Item hierarchy and serve
 
36
 * <em>only</em> to represent a time or date-related piece of data.
 
37
 *
 
38
 * @note
 
39
 *
 
40
 * Low-level calendrical calculations are done via routines in the
 
41
 * calendar.cc file.
 
42
 *
 
43
 * @see drizzled/calendar.cc
 
44
 */
 
45
 
 
46
#ifndef DRIZZLED_TEMPORAL_H
 
47
#define DRIZZLED_TEMPORAL_H
 
48
 
 
49
#define DRIZZLE_MAX_SECONDS 59
 
50
#define DRIZZLE_MAX_MINUTES 59
 
51
#define DRIZZLE_MAX_HOURS 23
 
52
#define DRIZZLE_MAX_DAYS 31
 
53
#define DRIZZLE_MAX_MONTHS 12
 
54
#define DRIZZLE_MAX_YEARS_SQL 9999
 
55
#define DRIZZLE_MAX_YEARS_EPOCH 2038
 
56
#define DRIZZLE_MIN_SECONDS 0
 
57
#define DRIZZLE_MIN_MINUTES 0
 
58
#define DRIZZLE_MIN_HOURS 0
 
59
#define DRIZZLE_MIN_DAYS 1
 
60
#define DRIZZLE_MIN_MONTHS 1
 
61
#define DRIZZLE_MIN_YEARS_SQL 1
 
62
#define DRIZZLE_MIN_YEARS_EPOCH 1970
 
63
 
 
64
#define DRIZZLE_SECONDS_IN_MINUTE 60
 
65
#define DRIZZLE_SECONDS_IN_HOUR (60*60)
 
66
#define DRIZZLE_SECONDS_IN_DAY (60*60*24)
 
67
#define DRIZZLE_NANOSECONDS_IN_MICROSECOND 1000
 
68
 
 
69
#define DRIZZLE_YY_PART_YEAR  70
 
70
 
 
71
#include <sys/time.h>
 
72
#include <time.h>
 
73
 
 
74
#include "drizzled/global.h"
 
75
#include "drizzled/calendar.h"
 
76
 
 
77
/* Outside forward declarations */
 
78
class my_decimal;
 
79
 
 
80
namespace drizzled 
 
81
{
 
82
 
 
83
/**
 
84
 * Base class for all temporal data classes.
 
85
 */
 
86
class Temporal
 
87
{
 
88
protected:
 
89
  enum calendar _calendar;
 
90
  uint32_t _years;
 
91
  uint32_t _months;
 
92
  uint32_t _days;
 
93
  uint32_t _hours;
 
94
  uint32_t _minutes;
 
95
  uint32_t _seconds;
 
96
  time_t _epoch_seconds;
 
97
  uint32_t _useconds;
 
98
  uint32_t _nseconds;
 
99
  /** Returns number of seconds in time components (hour + minute + second) */
 
100
  uint64_t _cumulative_seconds_in_time() const;
 
101
public:
 
102
  Temporal();
 
103
  virtual ~Temporal() {}
 
104
 
 
105
  /** Returns the calendar component. */
 
106
  inline enum calendar calendar() const {return _calendar;}
 
107
  /** Returns the nanoseconds component. */
 
108
  inline uint32_t nseconds() const {return _nseconds;}
 
109
  /** Sets the useconds component. */
 
110
  inline void set_useconds(const uint32_t usecond) {_useconds= usecond;}
 
111
  /** Returns the microsseconds component. */
 
112
  inline uint32_t useconds() const {return _useconds;}
 
113
  /** Sets the epoch_seconds component. */
 
114
  virtual void set_epoch_seconds();
 
115
  /** Returns the UNIX epoch seconds component. */
 
116
  inline time_t epoch_seconds() const {return _epoch_seconds;}
 
117
  /** Sets the seconds component. */
 
118
  inline void set_seconds(const uint32_t second) {_seconds= second;}
 
119
  /** Returns the seconds component. */
 
120
  inline uint32_t seconds() const {return _seconds;}
 
121
  /** Sets the days component. */
 
122
  inline void set_minutes(const uint32_t minute) {_minutes= minute;}
 
123
  /** Returns the minutes component. */
 
124
  inline uint32_t minutes() const {return _minutes;}
 
125
  /** Sets the hours component. */
 
126
  inline void set_hours(const uint32_t hour) {_hours= hour;}
 
127
  /** Returns the hours component. */
 
128
  inline uint32_t hours() const {return _hours;}
 
129
  /** Sets the days component. */
 
130
  inline void set_days(const uint32_t day) {_days= day;}
 
131
  /** Returns the days component. */
 
132
  inline uint32_t days() const {return _days;}
 
133
  /** Sets the months component. */
 
134
  inline void set_months(const uint32_t month) {_months= month;}
 
135
  /** Returns the months component. */
 
136
  inline uint32_t months() const {return _months;}
 
137
  /** Sets the years component. */
 
138
  inline void set_years(const uint32_t year) {_years= year;}
 
139
  /** Returns the years component. */
 
140
  inline uint32_t years() const {return _years;}
 
141
 
 
142
  /** Returns whether the temporal value is valid as a date. */
 
143
  virtual bool is_valid_date() const= 0;
 
144
  /** Returns whether the temporal value is valid as a datetime. */
 
145
  virtual bool is_valid_datetime() const= 0;
 
146
  /** Returns whether the temporal value is valid as a time. */
 
147
  virtual bool is_valid_time() const= 0;
 
148
  /** Returns whether the temporal value is valid as a UNIX timestamp. */
 
149
  virtual bool is_valid_timestamp() const= 0;
 
150
 
 
151
  /**
 
152
   * Returns whether the temporal
 
153
   * value is valid. Each subclass defines what is
 
154
   * valid for the range of temporal data it contains.
 
155
   */
 
156
  virtual bool is_valid() const= 0;
 
157
 
 
158
  /**
 
159
   * All Temporal derived classes must implement
 
160
   * conversion routines for converting to and from
 
161
   * a string. Subclasses implement other conversion 
 
162
   * routines, but should always follow these notes:
 
163
   *
 
164
   * 1) Ensure that ALL from_xxx methods call is_valid()
 
165
   * 2) Ensure that ALL to_xxx methods are void returns and
 
166
   *    do not call is_valid()
 
167
   *
 
168
   * This minimizes the repeated bounds-checking to
 
169
   * just the conversion from_xxx routines.
 
170
   */
 
171
 
 
172
  friend class TemporalFormat;
 
173
};
 
174
 
 
175
/**
 
176
 * Class representing temporal components in a valid
 
177
 * SQL date range, with no time component
 
178
 */
 
179
class Date: public Temporal 
 
180
{
 
181
public:
 
182
  /**
 
183
   * Comparison operator overloads to compare a Date against
 
184
   * another Date value.
 
185
   *
 
186
   * @param Date to compare against.
 
187
   */
 
188
  bool operator==(const Date &rhs);
 
189
  bool operator!=(const Date &rhs);
 
190
  bool operator>(const Date &rhs);
 
191
  bool operator>=(const Date &rhs);
 
192
  bool operator<(const Date &rhs);
 
193
  bool operator<=(const Date &rhs);
 
194
  /**
 
195
   * Operator overload for adding/subtracting another Date
 
196
   * (or subclass) to/from this temporal.  When subtracting 
 
197
   * or adding two Dates, we return a new Date instance.
 
198
   *
 
199
   * @param Temporal instance to add/subtract to/from
 
200
   */
 
201
  const Date operator-(const Date &rhs);
 
202
  const Date operator+(const Date &rhs);
 
203
  Date& operator+=(const Date &rhs);
 
204
  Date& operator-=(const Date &rhs);
 
205
 
 
206
  virtual bool is_valid_date() const {return is_valid();}
 
207
  virtual bool is_valid_datetime() const {return is_valid();}
 
208
  virtual bool is_valid_time() const {return false;}
 
209
  virtual bool is_valid_timestamp() const {return is_valid() && in_unix_epoch();}
 
210
  /** Returns whether the temporal value is valid date. */
 
211
  virtual bool is_valid() const;
 
212
  /* Returns whether the Date (or subclass) instance is in the Unix Epoch. */
 
213
  virtual bool in_unix_epoch() const;
 
214
 
 
215
  /**
 
216
   * Fills a supplied char string with a
 
217
   * string representation of the Date  
 
218
   * value.
 
219
   *
 
220
   * @param C-String to fill.
 
221
   * @param Length of filled string (out param)
 
222
   */
 
223
  virtual void to_string(char *to, size_t *to_len) const;
 
224
 
 
225
  /**
 
226
   * Attempts to populate the Date instance based
 
227
   * on the contents of a supplied string.
 
228
   *
 
229
   * Returns whether the conversion was 
 
230
   * successful.
 
231
   *
 
232
   * @param String to convert from
 
233
   * @param Length of supplied string
 
234
   */
 
235
  virtual bool from_string(const char *from, size_t from_len);
 
236
 
 
237
  /**
 
238
   * Fills a supplied 8-byte integer pointer with an
 
239
   * integer representation of the Date
 
240
   * value.
 
241
   *
 
242
   * @param Integer to fill.
 
243
   */
 
244
  virtual void to_int64_t(int64_t *to) const;
 
245
 
 
246
  /**
 
247
   * Fills a supplied 4-byte integer pointer with an
 
248
   * integer representation of the Date
 
249
   * value.
 
250
   *
 
251
   * @param Integer to fill.
 
252
   */
 
253
  virtual void to_int32_t(int32_t *to) const;
 
254
 
 
255
  /**
 
256
   * Attempts to populate the Date instance based
 
257
   * on the contents of a supplied 4-byte integer.
 
258
   *
 
259
   * Returns whether the conversion was 
 
260
   * successful.
 
261
   *
 
262
   * @param Integer to convert from
 
263
   */
 
264
  virtual bool from_int32_t(const int32_t from);
 
265
 
 
266
  /**
 
267
   * Attempts to populate the Date instance based
 
268
   * on the contents of a supplied Julian Day Number
 
269
   *
 
270
   * Returns whether the conversion was 
 
271
   * successful.
 
272
   *
 
273
   * @param Integer to convert from
 
274
   */
 
275
  virtual bool from_julian_day_number(const int64_t from);
 
276
 
 
277
  /**
 
278
   * Fills a supplied tm pointer with an
 
279
   * representation of the Date 
 
280
   * value.
 
281
   *
 
282
   * @param tm to fill.
 
283
   */
 
284
  virtual void to_tm(struct tm *to) const;
 
285
 
 
286
  /**
 
287
   * Attempts to populate the Date instance based
 
288
   * on the contents of a supplied pointer to struct tm
 
289
   * (broken time).
 
290
   *
 
291
   * Returns whether the conversion was 
 
292
   * successful.
 
293
   *
 
294
   * @param Pointe rto the struct tm to convert from
 
295
   */
 
296
  virtual bool from_tm(const struct tm *from);
 
297
 
 
298
  /**
 
299
   * Attempts to convert the Date value into
 
300
   * a supplied time_t.
 
301
   *
 
302
   * @param Pointer to a time_t to convert to
 
303
   */
 
304
  virtual void to_time_t(time_t *to) const;
 
305
 
 
306
  /**
 
307
   * Attempts to populate the Date instance based
 
308
   * on the contents of a supplied time_t
 
309
   *
 
310
   * Returns whether the conversion was 
 
311
   * successful.
 
312
   *
 
313
   * @param time_t to convert from
 
314
   */
 
315
  virtual bool from_time_t(const time_t from);
 
316
 
 
317
  /**
 
318
   * Fills a supplied my_decimal with a representation of 
 
319
   * the Date value.
 
320
   *
 
321
   * @param Pointer to the my_decimal to fill
 
322
   */
 
323
  virtual void to_decimal(my_decimal *to) const;
 
324
};
 
325
 
 
326
/* Forward declare needed for friendship */
 
327
class DateTime;
 
328
 
 
329
/**
 
330
 * Class representing temporal components having only
 
331
 * a time component, with no date structure
 
332
 */
 
333
class Time: public Temporal
 
334
{
 
335
public:
 
336
 
 
337
  /**
 
338
   * Comparison operator overloads to compare a Time against
 
339
   * another Time value.
 
340
   *
 
341
   * @param Time to compare against.
 
342
   */
 
343
  bool operator==(const Time &rhs);
 
344
  bool operator!=(const Time &rhs);
 
345
  bool operator>(const Time &rhs);
 
346
  bool operator>=(const Time &rhs);
 
347
  bool operator<(const Time &rhs);
 
348
  bool operator<=(const Time &rhs);
 
349
  /**
 
350
   * Operator to add/subtract a Time from a Time.  
 
351
   * We can return a Time new temporal instance.
 
352
   *
 
353
   * @param Temporal instance to add/subtract to/from
 
354
   */
 
355
  const Time operator-(const Time &rhs);
 
356
  const Time operator+(const Time &rhs);
 
357
  Time& operator-=(const Time &rhs);
 
358
  Time& operator+=(const Time &rhs);
 
359
 
 
360
  virtual bool is_valid_date() const {return false;}
 
361
  virtual bool is_valid_datetime() const {return false;}
 
362
  virtual bool is_valid_time() const {return is_valid();}
 
363
  virtual bool is_valid_timestamp() const {return false;}
 
364
  /** Returns whether the temporal value is valid date. */
 
365
  virtual bool is_valid() const;
 
366
 
 
367
  /**
 
368
   * Fills a supplied char string with a
 
369
   * string representation of the Time  
 
370
   * value.
 
371
   *
 
372
   * @param C-String to fill.
 
373
   * @param Length of filled string (out param)
 
374
   */
 
375
  virtual void to_string(char *to, size_t *to_len) const;
 
376
 
 
377
  /**
 
378
   * Attempts to populate the Time instance based
 
379
   * on the contents of a supplied string.
 
380
   *
 
381
   * Returns whether the conversion was 
 
382
   * successful.
 
383
   *
 
384
   * @param String to convert from
 
385
   * @param Length of supplied string
 
386
   */
 
387
  virtual bool from_string(const char *from, size_t from_len);
 
388
 
 
389
  /**
 
390
   * Fills a supplied 4-byte integer pointer with an
 
391
   * integer representation of the Time
 
392
   * value.
 
393
   *
 
394
   * @param Integer to fill.
 
395
   */
 
396
  virtual void to_int32_t(int32_t *to) const;
 
397
 
 
398
  /**
 
399
   * Attempts to populate the Time instance based
 
400
   * on the contents of a supplied 4-byte integer.
 
401
   *
 
402
   * Returns whether the conversion was 
 
403
   * successful.
 
404
   *
 
405
   * @param Integer to convert from
 
406
   */
 
407
  virtual bool from_int32_t(const int32_t from);
 
408
 
 
409
  /**
 
410
   * Fills a supplied my_decimal with a representation of 
 
411
   * the Time value.
 
412
   *
 
413
   * @param Pointer to the my_decimal to fill
 
414
   */
 
415
  virtual void to_decimal(my_decimal *to) const;
 
416
 
 
417
  friend class DateTime;
 
418
};
 
419
 
 
420
/**
 
421
 * Class representing temporal components in a valid
 
422
 * SQL datetime range, including a time component
 
423
 */
 
424
class DateTime: public Date
 
425
{
 
426
public:
 
427
  /**
 
428
   * Comparison operator overloads to compare a DateTime against
 
429
   * another DateTime value.
 
430
   *
 
431
   * @param DateTime to compare against.
 
432
   */
 
433
  bool operator==(const DateTime &rhs);
 
434
  bool operator!=(const DateTime &rhs);
 
435
  bool operator>(const DateTime &rhs);
 
436
  bool operator>=(const DateTime &rhs);
 
437
  bool operator<(const DateTime &rhs);
 
438
  bool operator<=(const DateTime &rhs);
 
439
  /**
 
440
   * Operator to add/subtract a Time from a Time.  
 
441
   * We can return a Time new temporal instance.
 
442
   *
 
443
   * @param Temporal instance to add/subtract to/from
 
444
   */
 
445
  const DateTime operator-(const Time &rhs);
 
446
  const DateTime operator+(const Time &rhs);
 
447
  DateTime& operator-=(const Time &rhs);
 
448
  DateTime& operator+=(const Time &rhs);
 
449
  /**
 
450
   * Operator overload for adding/subtracting another DateTime
 
451
   * (or subclass) to/from this temporal.  When subtracting 
 
452
   * or adding two DateTimes, we return a new DateTime instance.
 
453
   *
 
454
   * @param Temporal instance to add/subtract to/from
 
455
   */
 
456
  const DateTime operator-(const DateTime &rhs);
 
457
  const DateTime operator+(const DateTime &rhs);
 
458
  DateTime& operator+=(const DateTime &rhs);
 
459
  DateTime& operator-=(const DateTime &rhs);
 
460
 
 
461
  /* Returns whether the DateTime (or subclass) instance is in the Unix Epoch. */
 
462
  bool in_unix_epoch() const;
 
463
  /** Returns whether the temporal value is valid datetime. */
 
464
  virtual bool is_valid() const;
 
465
 
 
466
  /**
 
467
   * It's not possible to convert to and from a DateTime and 
 
468
   * a 4-byte integer, so let us know if we try and do it!
 
469
   */
 
470
  inline void to_int32_t(int32_t *) {assert(0);}
 
471
  inline bool from_int32_t(int32_t) {assert(0); return false;}
 
472
 
 
473
  /**
 
474
   * Fills a supplied char string with a
 
475
   * string representation of the DateTime
 
476
   * value.
 
477
   *
 
478
   * @param C-String to fill.
 
479
   * @param Length of filled string (out param)
 
480
   */
 
481
  virtual void to_string(char *to, size_t *to_len) const;
 
482
 
 
483
  /**
 
484
   * Attempts to populate the DateTime instance based
 
485
   * on the contents of a supplied string.
 
486
   *
 
487
   * Returns whether the conversion was 
 
488
   * successful.
 
489
   *
 
490
   * @param String to convert from
 
491
   * @param Length of supplied string
 
492
   */
 
493
  virtual bool from_string(const char *from, size_t from_len);
 
494
 
 
495
  /**
 
496
   * Fills a supplied 8-byte integer pointer with an
 
497
   * integer representation of the DateTime
 
498
   * value.
 
499
   *
 
500
   * @param Integer to fill.
 
501
   */
 
502
  virtual void to_int64_t(int64_t *to) const;
 
503
 
 
504
  /**
 
505
   * Attempts to populate the DateTime instance based
 
506
   * on the contents of a supplied time_t
 
507
   *
 
508
   * Returns whether the conversion was 
 
509
   * successful.
 
510
   *
 
511
   * @param time_t to convert from
 
512
   */
 
513
  virtual bool from_time_t(const time_t from);
 
514
 
 
515
  /**
 
516
   * Attempts to populate the DateTime instance based
 
517
   * on the contents of a supplied 8-byte integer.
 
518
   *
 
519
   * Returns whether the conversion was 
 
520
   * successful.
 
521
   *
 
522
   * @param Integer to convert from
 
523
   */
 
524
  virtual bool from_int64_t(const int64_t from);
 
525
 
 
526
  /**
 
527
   * Fills a supplied tm pointer with an
 
528
   * representation of the DateTime
 
529
   * value.
 
530
   *
 
531
   * @param tm to fill.
 
532
   */
 
533
  virtual void to_tm(struct tm *to) const;
 
534
 
 
535
  /**
 
536
   * Fills a supplied my_decimal with a representation of 
 
537
   * the DateTime value.
 
538
   *
 
539
   * @param Pointer to the my_decimal to fill
 
540
   */
 
541
  virtual void to_decimal(my_decimal *to) const;
 
542
};
 
543
 
 
544
/**
 
545
 * Class representing temporal components in the UNIX epoch
 
546
 */
 
547
class Timestamp: public DateTime 
 
548
{
 
549
public:
 
550
  /**
 
551
   * Comparison operator overloads to compare a Timestamp against
 
552
   * another Timestamp value.
 
553
   *
 
554
   * @param Timestamp to compare against.
 
555
   */
 
556
  bool operator==(const Timestamp &rhs);
 
557
  bool operator!=(const Timestamp &rhs);
 
558
  bool operator>(const Timestamp &rhs);
 
559
  bool operator>=(const Timestamp &rhs);
 
560
  bool operator<(const Timestamp &rhs);
 
561
  bool operator<=(const Timestamp &rhs);
 
562
 
 
563
  inline bool is_valid_timestamp() const {return is_valid();}
 
564
  /** Returns whether the temporal value is valid timestamp. */
 
565
  virtual bool is_valid() const;
 
566
 
 
567
  /**
 
568
   * Attempts to convert the Timestamp value into
 
569
   * a supplied time_t.
 
570
   *
 
571
   * @param Pointer to a time_t to convert to
 
572
   */
 
573
  virtual void to_time_t(time_t *to) const;
 
574
};
 
575
 
 
576
/**
 
577
 * Class representing temporal components in the UNIX epoch
 
578
 * with an additional microsecond component.
 
579
 */
 
580
class MicroTimestamp: public Timestamp
 
581
{
 
582
public:
 
583
  /** Returns whether the temporal value is valid micro-timestamp. */
 
584
  bool is_valid() const;
 
585
 
 
586
  /**
 
587
   * Fills a supplied char string with a
 
588
   * string representation of the MicroTimestamp
 
589
   * value.
 
590
   *
 
591
   * @param C-String to fill.
 
592
   * @param Length of filled string (out param)
 
593
   */
 
594
  virtual void to_string(char *to, size_t *to_len) const;
 
595
 
 
596
  /**
 
597
   * Fills a supplied timeval pointer with an
 
598
   * representation of the MicroTimestamp
 
599
   * value.
 
600
   *
 
601
   * Returns whether the conversion was 
 
602
   * successful.
 
603
   *
 
604
   * @param timeval to fill.
 
605
   */
 
606
  virtual void to_timeval(struct timeval *to) const;
 
607
};
 
608
 
 
609
/**
 
610
 * Class representing temporal components in the UNIX epoch
 
611
 * with an additional nanosecond component.
 
612
 */
 
613
class NanoTimestamp: public Timestamp
 
614
{
 
615
public:
 
616
  /** Returns whether the temporal value is valid nano-timestamp. */
 
617
  bool is_valid() const;
 
618
 
 
619
  /**
 
620
   * Fills a supplied timespec pointer with an
 
621
   * representation of the NanoTimestamp
 
622
   * value.
 
623
   *
 
624
   * Returns whether the conversion was 
 
625
   * successful.
 
626
   *
 
627
   * @param timespec to fill.
 
628
   */
 
629
  void to_timespec(struct timespec *to) const;
 
630
};
 
631
 
 
632
} /* end namespace drizzled */
 
633
 
 
634
#endif /* DRIZZLED_TEMPORAL_H */