00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022 #include <boost/lexical_cast.hpp>
00023 #include <drizzled/field/time.h>
00024 #include <drizzled/error.h>
00025 #include <drizzled/tztime.h>
00026 #include <drizzled/table.h>
00027 #include <drizzled/session.h>
00028
00029 #include <math.h>
00030
00031 #include <sstream>
00032
00033 #include <drizzled/temporal.h>
00034
00035 namespace drizzled
00036 {
00037
00038 namespace field
00039 {
00040
00048 Time::Time(unsigned char *ptr_arg,
00049 uint32_t,
00050 unsigned char *null_ptr_arg,
00051 unsigned char null_bit_arg,
00052 const char *field_name_arg) :
00053 Field_str(ptr_arg,
00054 DateTime::MAX_STRING_LENGTH - 1 ,
00055 null_ptr_arg,
00056 null_bit_arg,
00057 field_name_arg,
00058 &my_charset_bin)
00059 {
00060 }
00061
00062 Time::Time(bool maybe_null_arg,
00063 const char *field_name_arg) :
00064 Field_str((unsigned char*) NULL,
00065 DateTime::MAX_STRING_LENGTH - 1 ,
00066 maybe_null_arg ? (unsigned char*) "": 0,
00067 0,
00068 field_name_arg,
00069 &my_charset_bin)
00070 {
00071 }
00072
00073 int Time::store(const char *from,
00074 uint32_t len,
00075 const CHARSET_INFO * const )
00076 {
00077 drizzled::Time temporal;
00078
00079 ASSERT_COLUMN_MARKED_FOR_WRITE;
00080
00081 if (not temporal.from_string(from, (size_t) len))
00082 {
00083 std::string tmp(boost::lexical_cast<std::string>(from));
00084 my_error(ER_INVALID_TIME_VALUE, MYF(0), tmp.c_str());
00085 return 1;
00086 }
00087
00088 pack_time(temporal);
00089
00090 return 0;
00091 }
00092
00093 int Time::store(double from)
00094 {
00095 ASSERT_COLUMN_MARKED_FOR_WRITE;
00096
00097 do
00098 {
00099 int64_t tmp;
00100
00101 if (from > (double)TIME_MAX_VALUE)
00102 {
00103 tmp= TIME_MAX_VALUE;
00104 break;
00105 }
00106 else if (from < (double) - TIME_MAX_VALUE)
00107 {
00108 tmp= -TIME_MAX_VALUE;
00109 break;
00110 }
00111 else
00112 {
00113 tmp=(long) floor(fabs(from));
00114
00115 if (from < 0)
00116 tmp= -tmp;
00117
00118 if (tmp % 100 > 59 || tmp/100 % 100 > 59)
00119 {
00120 break;
00121 }
00122 }
00123
00124 return store(tmp, false);
00125
00126 } while (0);
00127
00128 std::string tmp(boost::lexical_cast<std::string>(from));
00129 my_error(ER_INVALID_TIME_VALUE, MYF(0), tmp.c_str());
00130
00131 return 1;
00132 }
00133
00134 int Time::store(int64_t from, bool)
00135 {
00136 ASSERT_COLUMN_MARKED_FOR_WRITE;
00137
00138
00139
00140
00141
00142 drizzled::Time temporal;
00143 if (not temporal.from_time_t(from))
00144 {
00145
00146 std::string tmp(boost::lexical_cast<std::string>(from));
00147 my_error(ER_INVALID_TIME_VALUE, MYF(0), tmp.c_str());
00148 return 2;
00149 }
00150
00151 pack_time(temporal);
00152
00153 return 0;
00154 }
00155
00156 void Time::pack_time(drizzled::Time &temporal)
00157 {
00158 int32_t tmp;
00159 temporal.to_int32_t(&tmp);
00160 tmp= htonl(tmp);
00161 memcpy(ptr, &tmp, sizeof(int32_t));
00162 }
00163
00164 void Time::unpack_time(drizzled::Time &temporal) const
00165 {
00166 int32_t tmp;
00167
00168 memcpy(&tmp, ptr, sizeof(int32_t));
00169 tmp= htonl(tmp);
00170
00171 temporal.from_int32_t(tmp);
00172 }
00173
00174 void Time::unpack_time(int32_t &destination, const unsigned char *source) const
00175 {
00176 memcpy(&destination, source, sizeof(int32_t));
00177 destination= htonl(destination);
00178 }
00179
00180 double Time::val_real(void) const
00181 {
00182 return (double) Time::val_int();
00183 }
00184
00185 int64_t Time::val_int(void) const
00186 {
00187 ASSERT_COLUMN_MARKED_FOR_READ;
00188
00189 drizzled::Time temporal;
00190 unpack_time(temporal);
00191
00192
00193 uint64_t result;
00194 temporal.to_uint64_t(result);
00195 return result;
00196 }
00197
00198 String *Time::val_str(String *val_buffer, String *) const
00199 {
00200 char *to;
00201 int to_len= field_length + 1;
00202
00203 val_buffer->alloc(to_len);
00204 to= (char *) val_buffer->ptr();
00205
00206 val_buffer->set_charset(&my_charset_bin);
00207
00208 drizzled::Time temporal;
00209 unpack_time(temporal);
00210
00211 int rlen;
00212 rlen= temporal.to_string(to, to_len);
00213 assert(rlen < to_len);
00214
00215 val_buffer->length(rlen);
00216 return val_buffer;
00217 }
00218
00219 bool Time::get_date(type::Time <ime, uint32_t) const
00220 {
00221 ltime.reset();
00222
00223 drizzled::Time temporal;
00224 unpack_time(temporal);
00225
00226 ltime.time_type= type::DRIZZLE_TIMESTAMP_DATETIME;
00227 ltime.year= temporal.years();
00228 ltime.month= temporal.months();
00229 ltime.day= temporal.days();
00230 ltime.hour= temporal.hours();
00231 ltime.minute= temporal.minutes();
00232 ltime.second= temporal.seconds();
00233
00234 return 0;
00235 }
00236
00237 bool Time::get_time(type::Time <ime) const
00238 {
00239 return Time::get_date(ltime, 0);
00240 }
00241
00242 int Time::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
00243 {
00244 int32_t a,b;
00245
00246 unpack_time(a, a_ptr);
00247 unpack_time(b, b_ptr);
00248
00249 return (a < b) ? -1 : (a > b) ? 1 : 0;
00250 }
00251
00252
00253 void Time::sort_string(unsigned char *to,uint32_t )
00254 {
00255 #ifdef WORDS_BIGENDIAN
00256 if (!getTable() || !getTable()->getShare()->db_low_byte_first)
00257 {
00258 to[0] = ptr[0];
00259 to[1] = ptr[1];
00260 to[2] = ptr[2];
00261 to[3] = ptr[3];
00262 }
00263 else
00264 #endif
00265 {
00266 to[0] = ptr[3];
00267 to[1] = ptr[2];
00268 to[2] = ptr[1];
00269 to[3] = ptr[0];
00270 }
00271 }
00272
00273 void Time::sql_type(String &res) const
00274 {
00275 res.set_ascii(STRING_WITH_LEN("timestamp"));
00276 }
00277
00278 long Time::get_timestamp(bool *null_value) const
00279 {
00280 if ((*null_value= is_null()))
00281 return 0;
00282
00283 uint64_t tmp;
00284 return unpack_num(tmp);
00285 }
00286
00287 size_t Time::max_string_length()
00288 {
00289 return sizeof(int64_t);
00290 }
00291
00292 }
00293 }