~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/enum.cc

  • Committer: Eric Lambert
  • Date: 2009-06-11 21:19:36 UTC
  • mto: (1061.1.1 merge-all)
  • mto: This revision was merged to the branch mainline in revision 1062.
  • Revision ID: eric.d.lambert@gmail.com-20090611211936-g2gij43xakupz1dw
-removed rm_dir_w_symlink method call with rmdir since dir should not be a sym link in the first place.

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)
61
92
{
62
93
  uint32_t tmp;
63
94
 
64
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
65
 
 
66
95
  /* Remove end space */
67
96
  length= field_charset->cset->lengthsp(field_charset, from, length);
68
97
  tmp= find_type2(typelib, from, length, field_charset);
101
130
 * @note MySQL allows 0 values, saying that 0 is "the index of the
102
131
 * blank string error", whatever that means.  Uhm, Drizzle doesn't
103
132
 * 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
 
133
 * must specify the 1-based index of the enum column definition's 
105
134
 * key.
106
135
 */
107
136
int Field_enum::store(int64_t from, bool)
108
137
{
109
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
110
 
 
111
138
  if (from <= 0 || (uint64_t) from > typelib->count)
112
139
  {
113
 
    /* Convert the integer to a string using boost::lexical_cast */
114
 
    std::string tmp(boost::lexical_cast<std::string>(from));
 
140
    /* Convert the integer to a string using stringstream */
 
141
    std::stringstream ss;
 
142
    std::string tmp;
 
143
    ss << from; ss >> tmp;
115
144
 
116
145
    my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), tmp.c_str());
117
146
    return 1;
127
156
 
128
157
int64_t Field_enum::val_int(void)
129
158
{
130
 
  ASSERT_COLUMN_MARKED_FOR_READ;
131
 
 
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 */
 
159
  switch (packlength) {
 
160
  case 1:
 
161
    return (int64_t) ptr[0];
 
162
  case 2:
 
163
  {
 
164
    uint16_t tmp;
 
165
#ifdef WORDS_BIGENDIAN
 
166
    if (table->s->db_low_byte_first)
 
167
      tmp=sint2korr(ptr);
 
168
    else
 
169
#endif
 
170
      shortget(tmp,ptr);
 
171
    return (int64_t) tmp;
 
172
  }
 
173
  case 3:
 
174
    return (int64_t) uint3korr(ptr);
 
175
  case 4:
 
176
  {
 
177
    uint32_t tmp;
 
178
#ifdef WORDS_BIGENDIAN
 
179
    if (table->s->db_low_byte_first)
 
180
      tmp=uint4korr(ptr);
 
181
    else
 
182
#endif
 
183
      longget(tmp,ptr);
 
184
    return (int64_t) tmp;
 
185
  }
 
186
  case 8:
 
187
  {
 
188
    int64_t tmp;
 
189
#ifdef WORDS_BIGENDIAN
 
190
    if (table->s->db_low_byte_first)
 
191
      tmp=sint8korr(ptr);
 
192
    else
 
193
#endif
 
194
      int64_tget(tmp,ptr);
 
195
    return tmp;
 
196
  }
 
197
  }
 
198
  return 0;                                     // impossible
 
199
}
 
200
 
 
201
/**
 
202
   Save the field metadata for enum fields.
 
203
 
 
204
   Saves the real type in the first byte and the pack length in the
 
205
   second byte of the field metadata array at index of *metadata_ptr and
 
206
   *(metadata_ptr + 1).
 
207
 
 
208
   @param   metadata_ptr   First byte of field metadata
 
209
 
 
210
   @returns number of bytes written to metadata_ptr
 
211
*/
 
212
int Field_enum::do_save_field_metadata(unsigned char *metadata_ptr)
 
213
{
 
214
  *metadata_ptr= real_type();
 
215
  *(metadata_ptr + 1)= pack_length();
 
216
  return 2;
140
217
}
141
218
 
142
219
String *Field_enum::val_str(String *, String *val_ptr)
143
220
{
144
221
  uint32_t tmp=(uint32_t) Field_enum::val_int();
145
 
 
146
 
  ASSERT_COLUMN_MARKED_FOR_READ;
147
 
 
148
 
  if (not tmp || tmp > typelib->count)
149
 
  {
 
222
  if (!tmp || tmp > typelib->count)
150
223
    val_ptr->set("", 0, field_charset);
151
 
  }
152
224
  else
153
 
  {
154
 
    val_ptr->set((const char*) typelib->type_names[tmp-1], typelib->type_lengths[tmp-1], field_charset);
155
 
  }
156
 
 
 
225
    val_ptr->set((const char*) typelib->type_names[tmp-1],
 
226
                 typelib->type_lengths[tmp-1],
 
227
                 field_charset);
157
228
  return val_ptr;
158
229
}
159
230
 
161
232
{
162
233
  unsigned char *old= ptr;
163
234
  ptr= (unsigned char*) a_ptr;
164
 
  uint64_t a= Field_enum::val_int();
 
235
  uint64_t a=Field_enum::val_int();
165
236
  ptr= (unsigned char*) b_ptr;
166
 
  uint64_t b= Field_enum::val_int();
 
237
  uint64_t b=Field_enum::val_int();
167
238
  ptr= old;
168
239
  return (a < b) ? -1 : (a > b) ? 1 : 0;
169
240
}
170
241
 
171
242
void Field_enum::sort_string(unsigned char *to,uint32_t )
172
243
{
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++)
 
244
  uint64_t value=Field_enum::val_int();
 
245
  to+=packlength-1;
 
246
  for (uint32_t i=0 ; i < packlength ; i++)
176
247
  {
177
248
    *to-- = (unsigned char) (value & 255);
178
249
    value>>=8;
191
262
  uint32_t *len= typelib->type_lengths;
192
263
  for (const char **pos= typelib->type_names; *pos; pos++, len++)
193
264
  {
194
 
    size_t dummy_errors;
 
265
    uint32_t dummy_errors;
195
266
    if (flag)
196
267
      res.append(',');
197
268
    /* convert to res.charset() == utf8, then quote */
202
273
  res.append(')');
203
274
}
204
275
 
205
 
Field *Field_enum::new_field(memory::Root *root, Table *new_table,
 
276
Field *Field_enum::new_field(MEM_ROOT *root, Table *new_table,
206
277
                             bool keep_type)
207
278
{
208
279
  Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
209
280
  if (res)
210
 
  {
211
281
    res->typelib= copy_typelib(root, typelib);
212
 
  }
213
282
  return res;
214
283
}
215
 
 
216
 
} /* namespace drizzled */