~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/microtime.cc

edit

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>
 
21
#include "config.h"
22
22
#include <boost/lexical_cast.hpp>
23
23
#include <drizzled/field/microtime.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
 
#include <drizzled/current_session.h>
29
28
 
30
29
#include <math.h>
31
30
 
33
32
 
34
33
#include <boost/date_time/posix_time/posix_time.hpp>
35
34
 
36
 
#include <drizzled/temporal.h>
 
35
#include "drizzled/temporal.h"
37
36
 
38
37
namespace drizzled
39
38
{
55
54
        unireg_check_arg,
56
55
        field_name_arg,
57
56
        share)
58
 
{
59
 
}
 
57
  {
 
58
  }
60
59
 
61
60
Microtime::Microtime(bool maybe_null_arg,
62
61
                     const char *field_name_arg) :
75
74
 
76
75
  if (not temporal.from_string(from, (size_t) len))
77
76
  {
78
 
    my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
 
77
    my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
79
78
    return 1;
80
79
  }
81
80
 
91
90
  return 0;
92
91
}
93
92
 
94
 
int Microtime::store_time(type::Time &ltime, type::timestamp_t )
 
93
int Microtime::store_time(type::Time *ltime, enum enum_drizzle_timestamp_type )
95
94
{
96
95
  long my_timezone;
97
96
  bool in_dst_time_gap;
98
97
 
99
 
  type::Time::epoch_t time_tmp;
100
 
  ltime.convert(time_tmp, &my_timezone, &in_dst_time_gap, true);
 
98
  time_t time_tmp= my_system_gmt_sec(ltime, &my_timezone, &in_dst_time_gap, true);
101
99
  uint64_t tmp_seconds= time_tmp;
102
 
  uint32_t tmp_micro= ltime.second_part;
 
100
  uint32_t tmp_micro= ltime->second_part;
103
101
 
104
102
  pack_num(tmp_seconds);
105
103
  pack_num(tmp_micro, ptr +8);
111
109
{
112
110
  ASSERT_COLUMN_MARKED_FOR_WRITE;
113
111
 
114
 
  uint64_t from_tmp= (uint64_t)from;
115
 
  type::Time::usec_t fractional_seconds= (type::Time::usec_t)((from - from_tmp) * type::Time::FRACTIONAL_DIGITS) % type::Time::FRACTIONAL_DIGITS;
116
 
 
117
 
  MicroTimestamp temporal;
118
 
  if (not temporal.from_int64_t(from_tmp))
 
112
  if (from < 0 || from > 99991231235959.0)
119
113
  {
120
 
    /* Convert the integer to a string using boost::lexical_cast */
121
 
    std::string tmp(boost::lexical_cast<std::string>(from));
 
114
    /* Convert the double to a string using stringstream */
 
115
    std::stringstream ss;
 
116
    std::string tmp;
 
117
    ss.precision(18); /* 18 places should be fine for error display of double input. */
 
118
    ss << from; 
 
119
    ss >> tmp;
122
120
 
123
 
    my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
 
121
    my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
124
122
    return 2;
125
123
  }
126
 
 
127
 
  time_t tmp;
128
 
  temporal.to_time_t(tmp);
129
 
 
130
 
  uint64_t tmp_micro= tmp;
131
 
  pack_num(tmp_micro);
132
 
  pack_num(fractional_seconds, ptr +8);
133
 
 
134
 
  return 0;
 
124
  return Microtime::store((int64_t) rint(from), false);
135
125
}
136
126
 
137
127
int Microtime::store(int64_t from, bool)
144
134
    /* Convert the integer to a string using boost::lexical_cast */
145
135
    std::string tmp(boost::lexical_cast<std::string>(from));
146
136
 
147
 
    my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
 
137
    my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
148
138
    return 2;
149
139
  }
150
140
 
158
148
  return 0;
159
149
}
160
150
 
161
 
double Microtime::val_real(void) const
162
 
{
163
 
  uint64_t temp;
164
 
  type::Time::usec_t micro_temp;
165
 
 
166
 
  ASSERT_COLUMN_MARKED_FOR_READ;
167
 
 
168
 
  unpack_num(temp);
169
 
  unpack_num(micro_temp, ptr +8);
170
 
 
171
 
  Timestamp temporal;
172
 
  (void) temporal.from_time_t((time_t) temp);
173
 
 
174
 
  /* We must convert into a "timestamp-formatted integer" ... */
175
 
  int64_t result;
176
 
  temporal.to_int64_t(&result);
177
 
 
178
 
  result+= micro_temp % type::Time::FRACTIONAL_DIGITS;
179
 
 
180
 
  return result;
181
 
}
182
 
 
183
 
type::Decimal *Microtime::val_decimal(type::Decimal *decimal_value) const
184
 
{
185
 
  type::Time ltime;
186
 
 
187
 
  get_date(ltime, 0);
188
 
 
189
 
  return date2_class_decimal(&ltime, decimal_value);
190
 
}
191
 
 
192
 
int64_t Microtime::val_int(void) const
193
 
{
194
 
  uint64_t temp;
195
 
 
196
 
  ASSERT_COLUMN_MARKED_FOR_READ;
197
 
 
198
 
  unpack_num(temp);
199
 
 
200
 
  Timestamp temporal;
201
 
  (void) temporal.from_time_t((time_t) temp);
202
 
 
203
 
  /* We must convert into a "timestamp-formatted integer" ... */
204
 
  int64_t result;
205
 
  temporal.to_int64_t(&result);
206
 
 
207
 
  return result;
208
 
}
209
 
 
210
 
String *Microtime::val_str(String *val_buffer, String *) const
 
151
double Microtime::val_real(void)
 
152
{
 
153
  return (double) Microtime::val_int();
 
154
}
 
155
 
 
156
int64_t Microtime::val_int(void)
 
157
{
 
158
  uint64_t temp;
 
159
 
 
160
  ASSERT_COLUMN_MARKED_FOR_READ;
 
161
 
 
162
  unpack_num(temp);
 
163
 
 
164
  Timestamp temporal;
 
165
  (void) temporal.from_time_t((time_t) temp);
 
166
 
 
167
  /* We must convert into a "timestamp-formatted integer" ... */
 
168
  int64_t result;
 
169
  temporal.to_int64_t(&result);
 
170
 
 
171
  return result;
 
172
}
 
173
 
 
174
String *Microtime::val_str(String *val_buffer, String *)
211
175
{
212
176
  uint64_t temp= 0;
213
 
  type::Time::usec_t micro_temp= 0;
 
177
  uint32_t micro_temp= 0;
 
178
  char *to;
 
179
  int to_len= field_length + 1 + 8;
 
180
 
 
181
  val_buffer->alloc(to_len);
 
182
  to= (char *) val_buffer->ptr();
214
183
 
215
184
  unpack_num(temp);
216
185
  unpack_num(micro_temp, ptr +8);
217
186
 
218
 
  type::Time tmp_time;
219
 
  tmp_time.store(temp, micro_temp);
220
 
 
221
 
  tmp_time.convert(*val_buffer);
222
 
 
 
187
  val_buffer->set_charset(&my_charset_bin);     /* Safety */
 
188
 
 
189
  struct timeval buffer;
 
190
  buffer.tv_sec= temp;
 
191
  buffer.tv_usec= micro_temp;
 
192
 
 
193
  MicroTimestamp temporal;
 
194
  (void) temporal.from_timeval(buffer);
 
195
 
 
196
  int rlen= temporal.to_string(to, to_len);
 
197
  assert(rlen <= to_len);
 
198
 
 
199
  val_buffer->length(rlen);
223
200
 
224
201
  return val_buffer;
225
202
}
226
203
 
227
 
bool Microtime::get_date(type::Time &ltime, uint32_t) const
 
204
bool Microtime::get_date(type::Time *ltime, uint32_t)
228
205
{
229
206
  uint64_t temp;
230
207
  uint32_t micro_temp= 0;
232
209
  unpack_num(temp);
233
210
  unpack_num(micro_temp, ptr +8);
234
211
  
235
 
  ltime.reset();
236
 
 
237
 
  ltime.store(temp, micro_temp);
238
 
 
239
 
  return false;
 
212
  memset(ltime, 0, sizeof(*ltime));
 
213
 
 
214
  Timestamp temporal;
 
215
  (void) temporal.from_time_t((time_t) temp);
 
216
 
 
217
  /* @TODO Goodbye the below code when type::Time is finally gone.. */
 
218
 
 
219
  ltime->time_type= DRIZZLE_TIMESTAMP_DATETIME;
 
220
  ltime->year= temporal.years();
 
221
  ltime->month= temporal.months();
 
222
  ltime->day= temporal.days();
 
223
  ltime->hour= temporal.hours();
 
224
  ltime->minute= temporal.minutes();
 
225
  ltime->second= temporal.seconds();
 
226
  ltime->second_part= temporal.useconds();
 
227
 
 
228
  return 0;
240
229
}
241
230
 
242
 
bool Microtime::get_time(type::Time &ltime) const
 
231
bool Microtime::get_time(type::Time *ltime)
243
232
{
244
 
  return Microtime::get_date(ltime, 0);
 
233
  return Microtime::get_date(ltime,0);
245
234
}
246
235
 
247
236
int Microtime::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
286
275
{
287
276
  Session *session= getTable() ? getTable()->in_use : current_session;
288
277
 
289
 
  type::Time::usec_t fractional_seconds= 0;
 
278
  uint32_t fractional_seconds= 0;
290
279
  uint64_t epoch_seconds= session->getCurrentTimestampEpoch(fractional_seconds);
291
280
 
292
281
  set_notnull();
294
283
  pack_num(fractional_seconds, ptr +8);
295
284
}
296
285
 
297
 
long Microtime::get_timestamp(bool *null_value) const
 
286
long Microtime::get_timestamp(bool *null_value)
298
287
{
299
288
  if ((*null_value= is_null()))
300
289
    return 0;