~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/enum.cc

Merge Stewart's dead code removal

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"
22
 
#include <boost/lexical_cast.hpp>
 
21
 
 
22
#include "drizzled/server_includes.h"
23
23
#include "drizzled/field/enum.h"
24
24
#include "drizzled/error.h"
25
25
#include "drizzled/table.h"
26
26
#include "drizzled/session.h"
27
 
#include "drizzled/strfunc.h"
28
27
 
29
28
#include <sstream>
30
29
#include <string>
31
30
 
32
 
namespace drizzled
33
 
{
34
 
 
35
31
/****************************************************************************
36
32
** enum type.
37
33
** This is a string which only can have a selection of different values.
38
34
** If one uses this string in a number context one gets the type number.
39
35
****************************************************************************/
40
36
 
 
37
enum ha_base_keytype Field_enum::key_type() const
 
38
{
 
39
  switch (packlength) 
 
40
  {
 
41
    default: return HA_KEYTYPE_BINARY;
 
42
    case 2: assert(1);
 
43
    case 3: assert(1);
 
44
    case 4: return HA_KEYTYPE_ULONG_INT;
 
45
    case 8: return HA_KEYTYPE_ULONGLONG;
 
46
  }
 
47
}
 
48
 
41
49
void Field_enum::store_type(uint64_t value)
42
50
{
43
 
  value--; /* we store as starting from 0, although SQL starts from 1 */
44
 
 
45
 
#ifdef WORDS_BIGENDIAN
46
 
  if (getTable()->getShare()->db_low_byte_first)
47
 
  {
48
 
    int4store(ptr, (unsigned short) value);
49
 
  }
50
 
  else
51
 
#endif
52
 
    longstore(ptr, (unsigned short) value);
 
51
  switch (packlength) {
 
52
  case 1: ptr[0]= (unsigned char) value;  break;
 
53
  case 2:
 
54
#ifdef WORDS_BIGENDIAN
 
55
  if (table->s->db_low_byte_first)
 
56
  {
 
57
    int2store(ptr,(unsigned short) value);
 
58
  }
 
59
  else
 
60
#endif
 
61
    shortstore(ptr,(unsigned short) value);
 
62
  break;
 
63
  case 3: int3store(ptr,(long) value); break;
 
64
  case 4:
 
65
#ifdef WORDS_BIGENDIAN
 
66
  if (table->s->db_low_byte_first)
 
67
  {
 
68
    int4store(ptr,value);
 
69
  }
 
70
  else
 
71
#endif
 
72
    longstore(ptr,(long) value);
 
73
  break;
 
74
  case 8:
 
75
#ifdef WORDS_BIGENDIAN
 
76
  if (table->s->db_low_byte_first)
 
77
  {
 
78
    int8store(ptr,value);
 
79
  }
 
80
  else
 
81
#endif
 
82
    int64_tstore(ptr,value); break;
 
83
  }
53
84
}
54
85
 
55
86
/**
56
87
 * Given a supplied string, looks up the string in the internal typelib
57
 
 * and stores the found key.  Upon not finding an entry in the typelib,
 
88
 * and stores the found key.  Upon not finding an entry in the typelib, 
58
89
 * we always throw an error.
59
90
 */
60
91
int Field_enum::store(const char *from, uint32_t length, const CHARSET_INFO * const)
101
132
 * @note MySQL allows 0 values, saying that 0 is "the index of the
102
133
 * blank string error", whatever that means.  Uhm, Drizzle doesn't
103
134
 * allow this.  To store an ENUM column value using an integer, you
104
 
 * must specify the 1-based index of the enum column definition's
 
135
 * must specify the 1-based index of the enum column definition's 
105
136
 * key.
106
137
 */
107
138
int Field_enum::store(int64_t from, bool)
110
141
 
111
142
  if (from <= 0 || (uint64_t) from > typelib->count)
112
143
  {
113
 
    /* Convert the integer to a string using boost::lexical_cast */
114
 
    std::string tmp(boost::lexical_cast<std::string>(from));
 
144
    /* Convert the integer to a string using stringstream */
 
145
    std::stringstream ss;
 
146
    std::string tmp;
 
147
    ss << from; ss >> tmp;
115
148
 
116
149
    my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), tmp.c_str());
117
150
    return 1;
129
162
{
130
163
  ASSERT_COLUMN_MARKED_FOR_READ;
131
164
 
132
 
  uint16_t tmp;
133
 
#ifdef WORDS_BIGENDIAN
134
 
  if (getTable()->getShare()->db_low_byte_first)
135
 
    tmp= sint4korr(ptr);
136
 
  else
137
 
#endif
138
 
    longget(tmp,ptr);
139
 
  return ((int64_t) tmp) + 1; /* SQL is from 1, we store from 0 */
 
165
  switch (packlength) {
 
166
  case 1:
 
167
    return (int64_t) ptr[0];
 
168
  case 2:
 
169
  {
 
170
    uint16_t tmp;
 
171
#ifdef WORDS_BIGENDIAN
 
172
    if (table->s->db_low_byte_first)
 
173
      tmp=sint2korr(ptr);
 
174
    else
 
175
#endif
 
176
      shortget(tmp,ptr);
 
177
    return (int64_t) tmp;
 
178
  }
 
179
  case 3:
 
180
    return (int64_t) uint3korr(ptr);
 
181
  case 4:
 
182
  {
 
183
    uint32_t tmp;
 
184
#ifdef WORDS_BIGENDIAN
 
185
    if (table->s->db_low_byte_first)
 
186
      tmp=uint4korr(ptr);
 
187
    else
 
188
#endif
 
189
      longget(tmp,ptr);
 
190
    return (int64_t) tmp;
 
191
  }
 
192
  case 8:
 
193
  {
 
194
    int64_t tmp;
 
195
#ifdef WORDS_BIGENDIAN
 
196
    if (table->s->db_low_byte_first)
 
197
      tmp=sint8korr(ptr);
 
198
    else
 
199
#endif
 
200
      int64_tget(tmp,ptr);
 
201
    return tmp;
 
202
  }
 
203
  }
 
204
  return 0;                                     // impossible
 
205
}
 
206
 
 
207
/**
 
208
   Save the field metadata for enum fields.
 
209
 
 
210
   Saves the real type in the first byte and the pack length in the
 
211
   second byte of the field metadata array at index of *metadata_ptr and
 
212
   *(metadata_ptr + 1).
 
213
 
 
214
   @param   metadata_ptr   First byte of field metadata
 
215
 
 
216
   @returns number of bytes written to metadata_ptr
 
217
*/
 
218
int Field_enum::do_save_field_metadata(unsigned char *metadata_ptr)
 
219
{
 
220
  *metadata_ptr= real_type();
 
221
  *(metadata_ptr + 1)= pack_length();
 
222
  return 2;
140
223
}
141
224
 
142
225
String *Field_enum::val_str(String *, String *val_ptr)
145
228
 
146
229
  ASSERT_COLUMN_MARKED_FOR_READ;
147
230
 
148
 
  if (not tmp || tmp > typelib->count)
149
 
  {
 
231
  if (!tmp || tmp > typelib->count)
150
232
    val_ptr->set("", 0, field_charset);
151
 
  }
152
233
  else
153
 
  {
154
 
    val_ptr->set((const char*) typelib->type_names[tmp-1], typelib->type_lengths[tmp-1], field_charset);
155
 
  }
156
 
 
 
234
    val_ptr->set((const char*) typelib->type_names[tmp-1],
 
235
                 typelib->type_lengths[tmp-1],
 
236
                 field_charset);
157
237
  return val_ptr;
158
238
}
159
239
 
161
241
{
162
242
  unsigned char *old= ptr;
163
243
  ptr= (unsigned char*) a_ptr;
164
 
  uint64_t a= Field_enum::val_int();
 
244
  uint64_t a=Field_enum::val_int();
165
245
  ptr= (unsigned char*) b_ptr;
166
 
  uint64_t b= Field_enum::val_int();
 
246
  uint64_t b=Field_enum::val_int();
167
247
  ptr= old;
168
248
  return (a < b) ? -1 : (a > b) ? 1 : 0;
169
249
}
170
250
 
171
251
void Field_enum::sort_string(unsigned char *to,uint32_t )
172
252
{
173
 
  uint64_t value=Field_enum::val_int()-1; /* SQL is 1 based, stored as 0 based*/
174
 
  to+=pack_length() -1;
175
 
  for (uint32_t i=0 ; i < pack_length() ; i++)
 
253
  uint64_t value=Field_enum::val_int();
 
254
  to+=packlength-1;
 
255
  for (uint32_t i=0 ; i < packlength ; i++)
176
256
  {
177
257
    *to-- = (unsigned char) (value & 255);
178
258
    value>>=8;
191
271
  uint32_t *len= typelib->type_lengths;
192
272
  for (const char **pos= typelib->type_names; *pos; pos++, len++)
193
273
  {
194
 
    size_t dummy_errors;
 
274
    uint32_t dummy_errors;
195
275
    if (flag)
196
276
      res.append(',');
197
277
    /* convert to res.charset() == utf8, then quote */
202
282
  res.append(')');
203
283
}
204
284
 
205
 
Field *Field_enum::new_field(memory::Root *root, Table *new_table,
 
285
Field *Field_enum::new_field(MEM_ROOT *root, Table *new_table,
206
286
                             bool keep_type)
207
287
{
208
288
  Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
209
289
  if (res)
210
 
  {
211
 
    res->typelib= typelib->copy_typelib(root);
212
 
  }
 
290
    res->typelib= copy_typelib(root, typelib);
213
291
  return res;
214
292
}
215
 
 
216
 
} /* namespace drizzled */