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
00024 #include <drizzled/field/date.h>
00025 #include <drizzled/error.h>
00026 #include <drizzled/table.h>
00027 #include <drizzled/temporal.h>
00028 #include <drizzled/session.h>
00029 #include <drizzled/time_functions.h>
00030 #include <drizzled/current_session.h>
00031
00032 #include <math.h>
00033
00034 #include <sstream>
00035 #include <string>
00036
00037 namespace drizzled
00038 {
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 int Field_date::store(const char *from,
00065 uint32_t len,
00066 const CHARSET_INFO * const )
00067 {
00068
00069
00070
00071
00072
00073
00074 ASSERT_COLUMN_MARKED_FOR_WRITE;
00075 DateTime temporal;
00076 if (! temporal.from_string(from, (size_t) len))
00077 {
00078 my_error(ER_INVALID_DATE_VALUE, MYF(ME_FATALERROR), from);
00079 return 2;
00080 }
00081
00082 uint32_t int_value= (temporal.years() * 10000) + (temporal.months() * 100) + temporal.days();
00083 int4store(ptr, int_value);
00084 return 0;
00085 }
00086
00087 int Field_date::store(double from)
00088 {
00089 ASSERT_COLUMN_MARKED_FOR_WRITE;
00090 if (from < 0.0 || from > 99991231235959.0)
00091 {
00092
00093 std::stringstream ss;
00094 std::string tmp;
00095 ss.precision(18);
00096 ss << from; ss >> tmp;
00097
00098 my_error(ER_INVALID_DATE_VALUE, MYF(ME_FATALERROR), tmp.c_str());
00099 return 2;
00100 }
00101 return Field_date::store((int64_t) rint(from), false);
00102 }
00103
00104 int Field_date::store(int64_t from, bool)
00105 {
00106
00107
00108
00109
00110 ASSERT_COLUMN_MARKED_FOR_WRITE;
00111 DateTime temporal;
00112 if (! temporal.from_int64_t(from))
00113 {
00114
00115 std::string tmp(boost::lexical_cast<std::string>(from));
00116
00117 my_error(ER_INVALID_DATE_VALUE, MYF(ME_FATALERROR), tmp.c_str());
00118 return 2;
00119 }
00120
00121
00122 uint32_t int_value= (temporal.years() * 10000) + (temporal.months() * 100) + temporal.days();
00123 int4store(ptr, int_value);
00124
00125 return 0;
00126 }
00127
00128 int Field_date::store_time(type::Time <ime,
00129 type::timestamp_t time_type)
00130 {
00131 long tmp;
00132 int error= 0;
00133 if (time_type == type::DRIZZLE_TIMESTAMP_DATE || time_type == type::DRIZZLE_TIMESTAMP_DATETIME)
00134 {
00135 tmp= ltime.year*10000 + ltime.month*100 + ltime.day;
00136
00137 Session *session= getTable() ? getTable()->in_use : current_session;
00138 type::cut_t cut_error= type::VALID;
00139 if (ltime.check(tmp != 0,
00140 (TIME_FUZZY_DATE |
00141 (session->variables.sql_mode & (MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), cut_error))
00142 {
00143 char buff[type::Time::MAX_STRING_LENGTH];
00144 String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
00145 ltime.convert(str, type::DRIZZLE_TIMESTAMP_DATE);
00146 set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
00147 str.ptr(), str.length(), type::DRIZZLE_TIMESTAMP_DATE, 1);
00148 }
00149
00150 error= static_cast<int>(cut_error);
00151
00152 if (not error && ltime.time_type != type::DRIZZLE_TIMESTAMP_DATE &&
00153 (ltime.hour || ltime.minute || ltime.second || ltime.second_part))
00154 {
00155 char buff[type::Time::MAX_STRING_LENGTH];
00156 String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
00157 ltime.convert(str);
00158 set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_NOTE,
00159 ER_WARN_DATA_TRUNCATED,
00160 str.ptr(), str.length(), type::DRIZZLE_TIMESTAMP_DATE, 1);
00161 error= 3;
00162 }
00163 }
00164 else
00165 {
00166 tmp=0;
00167 error= 1;
00168 set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
00169 }
00170
00171 int4store(ptr,tmp);
00172
00173 return error;
00174 }
00175
00176 double Field_date::val_real(void) const
00177 {
00178 return (double) Field_date::val_int();
00179 }
00180
00181 int64_t Field_date::val_int(void) const
00182 {
00183 uint32_t j;
00184
00185 ASSERT_COLUMN_MARKED_FOR_READ;
00186
00187 j= uint4korr(ptr);
00188
00189 return (int64_t) j;
00190 }
00191
00192 String *Field_date::val_str(String *val_buffer, String *) const
00193 {
00194 val_buffer->alloc(field_length);
00195 val_buffer->length(field_length);
00196 uint32_t tmp=(uint32_t) uint4korr(ptr);
00197 int32_t part;
00198 char *pos=(char*) val_buffer->ptr()+10;
00199
00200 ASSERT_COLUMN_MARKED_FOR_READ;
00201
00202
00203 *pos--=0;
00204 part=(int32_t) (tmp % 100);
00205 *pos--= (char) ('0'+part%10);
00206 *pos--= (char) ('0'+part/10);
00207 *pos--= '-';
00208 part=(int32_t) (tmp/100%100);
00209 *pos--= (char) ('0'+part%10);
00210 *pos--= (char) ('0'+part/10);
00211 *pos--= '-';
00212 part=(int32_t) (tmp/10000);
00213 *pos--= (char) ('0'+part%10); part/=10;
00214 *pos--= (char) ('0'+part%10); part/=10;
00215 *pos--= (char) ('0'+part%10); part/=10;
00216 *pos= (char) ('0'+part);
00217 return val_buffer;
00218 }
00219
00220 bool Field_date::get_date(type::Time <ime, uint32_t fuzzydate) const
00221 {
00222 uint32_t tmp=(uint32_t) uint4korr(ptr);
00223 ltime.day= (int) (tmp%100);
00224 ltime.month= (int) (tmp/100%100);
00225 ltime.year= (int) (tmp/10000);
00226 ltime.time_type= type::DRIZZLE_TIMESTAMP_DATE;
00227 ltime.hour= ltime.minute= ltime.second= ltime.second_part= ltime.neg= 0;
00228
00229 return ((!(fuzzydate & TIME_FUZZY_DATE) && (!ltime.month || !ltime.day)) ?
00230 1 : 0);
00231 }
00232
00233 bool Field_date::get_time(type::Time <ime) const
00234 {
00235 return Field_date::get_date(ltime ,0);
00236 }
00237
00238 int Field_date::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
00239 {
00240 uint32_t a,b;
00241 a=(uint32_t) uint4korr(a_ptr);
00242 b=(uint32_t) uint4korr(b_ptr);
00243 return (a < b) ? -1 : (a > b) ? 1 : 0;
00244 }
00245
00246 void Field_date::sort_string(unsigned char *to,uint32_t )
00247 {
00248 to[0] = ptr[3];
00249 to[1] = ptr[2];
00250 to[2] = ptr[1];
00251 to[3] = ptr[0];
00252 }
00253
00254 void Field_date::sql_type(String &res) const
00255 {
00256 res.set_ascii(STRING_WITH_LEN("date"));
00257 }
00258
00259 }