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/enum.h>
00024 #include <drizzled/error.h>
00025 #include <drizzled/table.h>
00026 #include <drizzled/session.h>
00027 #include <drizzled/typelib.h>
00028
00029 #include <sstream>
00030 #include <string>
00031
00032 namespace drizzled {
00033
00034
00035
00036
00037
00038
00039
00040 void Field_enum::store_type(uint64_t value)
00041 {
00042 value--;
00043
00044 #ifdef WORDS_BIGENDIAN
00045 if (getTable()->getShare()->db_low_byte_first)
00046 {
00047 int4store(ptr, (unsigned short) value);
00048 }
00049 else
00050 #endif
00051 longstore(ptr, (unsigned short) value);
00052 }
00053
00059 int Field_enum::store(const char *from, uint32_t length, const charset_info_st * const)
00060 {
00061 uint32_t tmp;
00062
00063 ASSERT_COLUMN_MARKED_FOR_WRITE;
00064
00065
00066 length= field_charset->cset->lengthsp(field_charset, from, length);
00067 tmp= typelib->find_type2(from, length, field_charset);
00068 if (! tmp)
00069 {
00070 if (length < 6)
00071 {
00072
00073
00074 std::stringstream ss;
00075 ss << from;
00076 ss >> tmp;
00077
00078 if (tmp == 0 || tmp > typelib->count)
00079 {
00080 my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), from);
00081 return 1;
00082 }
00083 }
00084 else
00085 {
00086 my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), from);
00087 return 1;
00088 }
00089 }
00090 store_type((uint64_t) tmp);
00091 return 0;
00092 }
00093
00094 int Field_enum::store(double from)
00095 {
00096 return Field_enum::store((int64_t) from, false);
00097 }
00098
00106 int Field_enum::store(int64_t from, bool)
00107 {
00108 ASSERT_COLUMN_MARKED_FOR_WRITE;
00109
00110 if (from <= 0 || (uint64_t) from > typelib->count)
00111 {
00112
00113 std::string tmp(boost::lexical_cast<std::string>(from));
00114
00115 my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), tmp.c_str());
00116 return 1;
00117 }
00118 store_type((uint64_t) (uint32_t) from);
00119 return 0;
00120 }
00121
00122 double Field_enum::val_real(void) const
00123 {
00124 return (double) Field_enum::val_int();
00125 }
00126
00127 int64_t Field_enum::val_int(void) const
00128 {
00129 ASSERT_COLUMN_MARKED_FOR_READ;
00130
00131 uint16_t tmp;
00132 #ifdef WORDS_BIGENDIAN
00133 if (getTable()->getShare()->db_low_byte_first)
00134 tmp= sint4korr(ptr);
00135 else
00136 #endif
00137 longget(tmp,ptr);
00138 return ((int64_t) tmp) + 1;
00139 }
00140
00141 String *Field_enum::val_str(String *, String *val_ptr) const
00142 {
00143 uint32_t tmp=(uint32_t) Field_enum::val_int();
00144
00145 ASSERT_COLUMN_MARKED_FOR_READ;
00146
00147 if (not tmp || tmp > typelib->count)
00148 {
00149 val_ptr->set("", 0, field_charset);
00150 }
00151 else
00152 {
00153 val_ptr->set((const char*) typelib->type_names[tmp-1], typelib->type_lengths[tmp-1], field_charset);
00154 }
00155
00156 return val_ptr;
00157 }
00158
00159 int Field_enum::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
00160 {
00161 unsigned char *old= ptr;
00162 ptr= (unsigned char*) a_ptr;
00163 uint64_t a= Field_enum::val_int();
00164 ptr= (unsigned char*) b_ptr;
00165 uint64_t b= Field_enum::val_int();
00166 ptr= old;
00167 return (a < b) ? -1 : (a > b) ? 1 : 0;
00168 }
00169
00170 void Field_enum::sort_string(unsigned char *to,uint32_t )
00171 {
00172 uint64_t value=Field_enum::val_int()-1;
00173 to+=pack_length() -1;
00174 for (uint32_t i=0 ; i < pack_length() ; i++)
00175 {
00176 *to-- = (unsigned char) (value & 255);
00177 value>>=8;
00178 }
00179 }
00180
00181 Field *Field_enum::new_field(memory::Root *root, Table *new_table,
00182 bool keep_type)
00183 {
00184 Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
00185 if (res)
00186 {
00187 res->typelib= typelib->copy_typelib(*root);
00188 }
00189 return res;
00190 }
00191
00192 }