~drizzle-trunk/drizzle/development

813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
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
813.1.12 by Jay Pipes
Fixes for SECOND() function to use new Temporal system. Because
69
#define DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING 40
70
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
71
#define DRIZZLE_YY_PART_YEAR  70
72
73
#include "drizzled/calendar.h"
74
75
/* Outside forward declarations */
76
class my_decimal;
77
78
namespace drizzled 
79
{
80
81
/**
82
 * Base class for all temporal data classes.
83
 */
84
class Temporal
85
{
86
protected:
87
  enum calendar _calendar;
88
  uint32_t _years;
89
  uint32_t _months;
90
  uint32_t _days;
91
  uint32_t _hours;
92
  uint32_t _minutes;
93
  uint32_t _seconds;
94
  time_t _epoch_seconds;
95
  uint32_t _useconds;
96
  uint32_t _nseconds;
97
  /** Returns number of seconds in time components (hour + minute + second) */
98
  uint64_t _cumulative_seconds_in_time() const;
99
public:
100
  Temporal();
101
  virtual ~Temporal() {}
102
103
  /** Returns the calendar component. */
104
  inline enum calendar calendar() const {return _calendar;}
105
  /** Returns the nanoseconds component. */
106
  inline uint32_t nseconds() const {return _nseconds;}
107
  /** Sets the useconds component. */
108
  inline void set_useconds(const uint32_t usecond) {_useconds= usecond;}
109
  /** Returns the microsseconds component. */
110
  inline uint32_t useconds() const {return _useconds;}
111
  /** Sets the epoch_seconds component. */
112
  virtual void set_epoch_seconds();
113
  /** Returns the UNIX epoch seconds component. */
114
  inline time_t epoch_seconds() const {return _epoch_seconds;}
115
  /** Sets the seconds component. */
116
  inline void set_seconds(const uint32_t second) {_seconds= second;}
117
  /** Returns the seconds component. */
118
  inline uint32_t seconds() const {return _seconds;}
119
  /** Sets the days component. */
120
  inline void set_minutes(const uint32_t minute) {_minutes= minute;}
121
  /** Returns the minutes component. */
122
  inline uint32_t minutes() const {return _minutes;}
123
  /** Sets the hours component. */
124
  inline void set_hours(const uint32_t hour) {_hours= hour;}
125
  /** Returns the hours component. */
126
  inline uint32_t hours() const {return _hours;}
127
  /** Sets the days component. */
128
  inline void set_days(const uint32_t day) {_days= day;}
129
  /** Returns the days component. */
130
  inline uint32_t days() const {return _days;}
131
  /** Sets the months component. */
132
  inline void set_months(const uint32_t month) {_months= month;}
133
  /** Returns the months component. */
134
  inline uint32_t months() const {return _months;}
135
  /** Sets the years component. */
136
  inline void set_years(const uint32_t year) {_years= year;}
137
  /** Returns the years component. */
138
  inline uint32_t years() const {return _years;}
139
140
  /** Returns whether the temporal value is valid as a date. */
141
  virtual bool is_valid_date() const= 0;
142
  /** Returns whether the temporal value is valid as a datetime. */
143
  virtual bool is_valid_datetime() const= 0;
144
  /** Returns whether the temporal value is valid as a time. */
145
  virtual bool is_valid_time() const= 0;
146
  /** Returns whether the temporal value is valid as a UNIX timestamp. */
147
  virtual bool is_valid_timestamp() const= 0;
148
149
  /**
150
   * Returns whether the temporal
151
   * value is valid. Each subclass defines what is
152
   * valid for the range of temporal data it contains.
153
   */
154
  virtual bool is_valid() const= 0;
155
156
  /**
157
   * All Temporal derived classes must implement
158
   * conversion routines for converting to and from
159
   * a string. Subclasses implement other conversion 
160
   * routines, but should always follow these notes:
161
   *
162
   * 1) Ensure that ALL from_xxx methods call is_valid()
163
   * 2) Ensure that ALL to_xxx methods are void returns and
164
   *    do not call is_valid()
165
   *
166
   * This minimizes the repeated bounds-checking to
167
   * just the conversion from_xxx routines.
168
   */
169
170
  friend class TemporalFormat;
171
};
172
173
/**
174
 * Class representing temporal components in a valid
175
 * SQL date range, with no time component
176
 */
177
class Date: public Temporal 
178
{
179
public:
180
  /**
181
   * Comparison operator overloads to compare a Date against
182
   * another Date value.
183
   *
184
   * @param Date to compare against.
185
   */
186
  bool operator==(const Date &rhs);
187
  bool operator!=(const Date &rhs);
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
  /**
193
   * Operator overload for adding/subtracting another Date
194
   * (or subclass) to/from this temporal.  When subtracting 
195
   * or adding two Dates, we return a new Date instance.
196
   *
197
   * @param Temporal instance to add/subtract to/from
198
   */
199
  const Date operator-(const Date &rhs);
200
  const Date operator+(const Date &rhs);
201
  Date& operator+=(const Date &rhs);
202
  Date& operator-=(const Date &rhs);
203
204
  virtual bool is_valid_date() const {return is_valid();}
205
  virtual bool is_valid_datetime() const {return is_valid();}
206
  virtual bool is_valid_time() const {return false;}
207
  virtual bool is_valid_timestamp() const {return is_valid() && in_unix_epoch();}
208
  /** Returns whether the temporal value is valid date. */
209
  virtual bool is_valid() const;
210
  /* Returns whether the Date (or subclass) instance is in the Unix Epoch. */
211
  virtual bool in_unix_epoch() const;
212
213
  /**
214
   * Fills a supplied char string with a
215
   * string representation of the Date  
216
   * value.
217
   *
218
   * @param C-String to fill.
219
   * @param Length of filled string (out param)
220
   */
221
  virtual void to_string(char *to, size_t *to_len) const;
222
223
  /**
224
   * Attempts to populate the Date instance based
225
   * on the contents of a supplied string.
226
   *
227
   * Returns whether the conversion was 
228
   * successful.
229
   *
230
   * @param String to convert from
231
   * @param Length of supplied string
232
   */
233
  virtual bool from_string(const char *from, size_t from_len);
234
235
  /**
236
   * Fills a supplied 8-byte integer pointer with an
237
   * integer representation of the Date
238
   * value.
239
   *
240
   * @param Integer to fill.
241
   */
242
  virtual void to_int64_t(int64_t *to) const;
243
244
  /**
245
   * Fills a supplied 4-byte integer pointer with an
246
   * integer representation of the Date
247
   * value.
248
   *
249
   * @param Integer to fill.
250
   */
251
  virtual void to_int32_t(int32_t *to) const;
252
253
  /**
254
   * Attempts to populate the Date instance based
255
   * on the contents of a supplied 4-byte integer.
256
   *
257
   * Returns whether the conversion was 
258
   * successful.
259
   *
260
   * @param Integer to convert from
261
   */
262
  virtual bool from_int32_t(const int32_t from);
263
264
  /**
265
   * Attempts to populate the Date instance based
266
   * on the contents of a supplied Julian Day Number
267
   *
268
   * Returns whether the conversion was 
269
   * successful.
270
   *
271
   * @param Integer to convert from
272
   */
273
  virtual bool from_julian_day_number(const int64_t from);
274
275
  /**
276
   * Fills a supplied tm pointer with an
277
   * representation of the Date 
278
   * value.
279
   *
280
   * @param tm to fill.
281
   */
282
  virtual void to_tm(struct tm *to) const;
283
284
  /**
285
   * Attempts to populate the Date instance based
286
   * on the contents of a supplied pointer to struct tm
287
   * (broken time).
288
   *
289
   * Returns whether the conversion was 
290
   * successful.
291
   *
292
   * @param Pointe rto the struct tm to convert from
293
   */
294
  virtual bool from_tm(const struct tm *from);
295
296
  /**
297
   * Attempts to convert the Date value into
298
   * a supplied time_t.
299
   *
300
   * @param Pointer to a time_t to convert to
301
   */
302
  virtual void to_time_t(time_t *to) const;
303
304
  /**
305
   * Attempts to populate the Date instance based
306
   * on the contents of a supplied time_t
307
   *
308
   * Returns whether the conversion was 
309
   * successful.
310
   *
311
   * @param time_t to convert from
312
   */
313
  virtual bool from_time_t(const time_t from);
314
315
  /**
316
   * Fills a supplied my_decimal with a representation of 
317
   * the Date value.
318
   *
319
   * @param Pointer to the my_decimal to fill
320
   */
321
  virtual void to_decimal(my_decimal *to) const;
322
};
323
324
/* Forward declare needed for friendship */
325
class DateTime;
326
327
/**
328
 * Class representing temporal components having only
329
 * a time component, with no date structure
330
 */
331
class Time: public Temporal
332
{
333
public:
334
335
  /**
336
   * Comparison operator overloads to compare a Time against
337
   * another Time value.
338
   *
339
   * @param Time to compare against.
340
   */
341
  bool operator==(const Time &rhs);
342
  bool operator!=(const Time &rhs);
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
  /**
348
   * Operator to add/subtract a Time from a Time.  
349
   * We can return a Time new temporal instance.
350
   *
351
   * @param Temporal instance to add/subtract to/from
352
   */
353
  const Time operator-(const Time &rhs);
354
  const Time operator+(const Time &rhs);
355
  Time& operator-=(const Time &rhs);
356
  Time& operator+=(const Time &rhs);
357
358
  virtual bool is_valid_date() const {return false;}
359
  virtual bool is_valid_datetime() const {return false;}
360
  virtual bool is_valid_time() const {return is_valid();}
361
  virtual bool is_valid_timestamp() const {return false;}
362
  /** Returns whether the temporal value is valid date. */
363
  virtual bool is_valid() const;
364
365
  /**
366
   * Fills a supplied char string with a
367
   * string representation of the Time  
368
   * value.
369
   *
370
   * @param C-String to fill.
371
   * @param Length of filled string (out param)
372
   */
373
  virtual void to_string(char *to, size_t *to_len) const;
374
375
  /**
376
   * Attempts to populate the Time instance based
377
   * on the contents of a supplied string.
378
   *
379
   * Returns whether the conversion was 
380
   * successful.
381
   *
382
   * @param String to convert from
383
   * @param Length of supplied string
384
   */
385
  virtual bool from_string(const char *from, size_t from_len);
386
387
  /**
388
   * Fills a supplied 4-byte integer pointer with an
389
   * integer representation of the Time
390
   * value.
391
   *
392
   * @param Integer to fill.
393
   */
394
  virtual void to_int32_t(int32_t *to) const;
395
396
  /**
397
   * Attempts to populate the Time instance based
398
   * on the contents of a supplied 4-byte integer.
399
   *
400
   * Returns whether the conversion was 
401
   * successful.
402
   *
403
   * @param Integer to convert from
404
   */
405
  virtual bool from_int32_t(const int32_t from);
406
407
  /**
408
   * Fills a supplied my_decimal with a representation of 
409
   * the Time value.
410
   *
411
   * @param Pointer to the my_decimal to fill
412
   */
413
  virtual void to_decimal(my_decimal *to) const;
414
415
  friend class DateTime;
416
};
417
418
/**
419
 * Class representing temporal components in a valid
420
 * SQL datetime range, including a time component
421
 */
422
class DateTime: public Date
423
{
424
public:
425
  /**
426
   * Comparison operator overloads to compare a DateTime against
427
   * another DateTime value.
428
   *
429
   * @param DateTime to compare against.
430
   */
431
  bool operator==(const DateTime &rhs);
432
  bool operator!=(const DateTime &rhs);
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
  /**
438
   * Operator to add/subtract a Time from a Time.  
439
   * We can return a Time new temporal instance.
440
   *
441
   * @param Temporal instance to add/subtract to/from
442
   */
443
  const DateTime operator-(const Time &rhs);
444
  const DateTime operator+(const Time &rhs);
445
  DateTime& operator-=(const Time &rhs);
446
  DateTime& operator+=(const Time &rhs);
447
  /**
448
   * Operator overload for adding/subtracting another DateTime
449
   * (or subclass) to/from this temporal.  When subtracting 
450
   * or adding two DateTimes, we return a new DateTime instance.
451
   *
452
   * @param Temporal instance to add/subtract to/from
453
   */
454
  const DateTime operator-(const DateTime &rhs);
455
  const DateTime operator+(const DateTime &rhs);
456
  DateTime& operator+=(const DateTime &rhs);
457
  DateTime& operator-=(const DateTime &rhs);
458
459
  /* Returns whether the DateTime (or subclass) instance is in the Unix Epoch. */
460
  bool in_unix_epoch() const;
461
  /** Returns whether the temporal value is valid datetime. */
462
  virtual bool is_valid() const;
463
464
  /**
465
   * It's not possible to convert to and from a DateTime and 
466
   * a 4-byte integer, so let us know if we try and do it!
467
   */
468
  inline void to_int32_t(int32_t *) {assert(0);}
469
  inline bool from_int32_t(int32_t) {assert(0); return false;}
470
471
  /**
472
   * Fills a supplied char string with a
473
   * string representation of the DateTime
474
   * value.
475
   *
476
   * @param C-String to fill.
477
   * @param Length of filled string (out param)
478
   */
479
  virtual void to_string(char *to, size_t *to_len) const;
480
481
  /**
482
   * Attempts to populate the DateTime instance based
483
   * on the contents of a supplied string.
484
   *
485
   * Returns whether the conversion was 
486
   * successful.
487
   *
488
   * @param String to convert from
489
   * @param Length of supplied string
490
   */
491
  virtual bool from_string(const char *from, size_t from_len);
492
493
  /**
494
   * Fills a supplied 8-byte integer pointer with an
495
   * integer representation of the DateTime
496
   * value.
497
   *
498
   * @param Integer to fill.
499
   */
500
  virtual void to_int64_t(int64_t *to) const;
501
502
  /**
503
   * Attempts to populate the DateTime instance based
504
   * on the contents of a supplied time_t
505
   *
506
   * Returns whether the conversion was 
507
   * successful.
508
   *
509
   * @param time_t to convert from
510
   */
511
  virtual bool from_time_t(const time_t from);
512
513
  /**
514
   * Attempts to populate the DateTime instance based
515
   * on the contents of a supplied 8-byte integer.
516
   *
517
   * Returns whether the conversion was 
518
   * successful.
519
   *
520
   * @param Integer to convert from
521
   */
522
  virtual bool from_int64_t(const int64_t from);
523
524
  /**
525
   * Fills a supplied tm pointer with an
526
   * representation of the DateTime
527
   * value.
528
   *
529
   * @param tm to fill.
530
   */
531
  virtual void to_tm(struct tm *to) const;
532
533
  /**
534
   * Fills a supplied my_decimal with a representation of 
535
   * the DateTime value.
536
   *
537
   * @param Pointer to the my_decimal to fill
538
   */
539
  virtual void to_decimal(my_decimal *to) const;
540
};
541
542
/**
543
 * Class representing temporal components in the UNIX epoch
544
 */
545
class Timestamp: public DateTime 
546
{
547
public:
548
  /**
549
   * Comparison operator overloads to compare a Timestamp against
550
   * another Timestamp value.
551
   *
552
   * @param Timestamp to compare against.
553
   */
554
  bool operator==(const Timestamp &rhs);
555
  bool operator!=(const Timestamp &rhs);
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
561
  inline bool is_valid_timestamp() const {return is_valid();}
562
  /** Returns whether the temporal value is valid timestamp. */
563
  virtual bool is_valid() const;
564
565
  /**
566
   * Attempts to convert the Timestamp value into
567
   * a supplied time_t.
568
   *
569
   * @param Pointer to a time_t to convert to
570
   */
571
  virtual void to_time_t(time_t *to) const;
572
};
573
574
/**
575
 * Class representing temporal components in the UNIX epoch
576
 * with an additional microsecond component.
577
 */
578
class MicroTimestamp: public Timestamp
579
{
580
public:
581
  /** Returns whether the temporal value is valid micro-timestamp. */
582
  bool is_valid() const;
583
584
  /**
585
   * Fills a supplied char string with a
586
   * string representation of the MicroTimestamp
587
   * value.
588
   *
589
   * @param C-String to fill.
590
   * @param Length of filled string (out param)
591
   */
592
  virtual void to_string(char *to, size_t *to_len) const;
593
594
  /**
595
   * Fills a supplied timeval pointer with an
596
   * representation of the MicroTimestamp
597
   * value.
598
   *
599
   * Returns whether the conversion was 
600
   * successful.
601
   *
602
   * @param timeval to fill.
603
   */
604
  virtual void to_timeval(struct timeval *to) const;
605
};
606
607
/**
608
 * Class representing temporal components in the UNIX epoch
609
 * with an additional nanosecond component.
610
 */
611
class NanoTimestamp: public Timestamp
612
{
613
public:
614
  /** Returns whether the temporal value is valid nano-timestamp. */
615
  bool is_valid() const;
616
617
  /**
618
   * Fills a supplied timespec pointer with an
619
   * representation of the NanoTimestamp
620
   * value.
621
   *
622
   * Returns whether the conversion was 
623
   * successful.
624
   *
625
   * @param timespec to fill.
626
   */
627
  void to_timespec(struct timespec *to) const;
628
};
629
630
} /* end namespace drizzled */
631
632
#endif /* DRIZZLED_TEMPORAL_H */