~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/enum.cc

  • Committer: Monty Taylor
  • Date: 2009-10-06 19:40:45 UTC
  • mto: This revision was merged to the branch mainline in revision 1184.
  • Revision ID: mordred@inaugust.com-20091006194045-ojptaq2sx6ck6q63
No more server_includes.h in headers.

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>
23
 
#include <drizzled/field/enum.h>
24
 
#include <drizzled/error.h>
25
 
#include <drizzled/table.h>
26
 
#include <drizzled/session.h>
27
 
#include <drizzled/strfunc.h>
28
 
#include <drizzled/typelib.h>
 
21
 
 
22
#include "drizzled/server_includes.h"
 
23
#include "drizzled/field/enum.h"
 
24
#include "drizzled/error.h"
 
25
#include "drizzled/table.h"
 
26
#include "drizzled/session.h"
29
27
 
30
28
#include <sstream>
31
29
#include <string>
32
30
 
33
 
namespace drizzled
34
 
{
35
 
 
36
31
/****************************************************************************
37
32
** enum type.
38
33
** This is a string which only can have a selection of different values.
39
34
** If one uses this string in a number context one gets the type number.
40
35
****************************************************************************/
41
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
 
42
49
void Field_enum::store_type(uint64_t value)
43
50
{
44
 
  value--; /* we store as starting from 0, although SQL starts from 1 */
45
 
 
46
 
#ifdef WORDS_BIGENDIAN
47
 
  if (getTable()->getShare()->db_low_byte_first)
48
 
  {
49
 
    int4store(ptr, (unsigned short) value);
50
 
  }
51
 
  else
52
 
#endif
53
 
    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
  }
54
84
}
55
85
 
56
86
/**
57
87
 * Given a supplied string, looks up the string in the internal typelib
58
 
 * 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, 
59
89
 * we always throw an error.
60
90
 */
61
91
int Field_enum::store(const char *from, uint32_t length, const CHARSET_INFO * const)
66
96
 
67
97
  /* Remove end space */
68
98
  length= field_charset->cset->lengthsp(field_charset, from, length);
69
 
  tmp= typelib->find_type2(from, length, field_charset);
 
99
  tmp= find_type2(typelib, from, length, field_charset);
70
100
  if (! tmp)
71
101
  {
72
102
    if (length < 6) /* Can't be more than 99999 enums */
102
132
 * @note MySQL allows 0 values, saying that 0 is "the index of the
103
133
 * blank string error", whatever that means.  Uhm, Drizzle doesn't
104
134
 * allow this.  To store an ENUM column value using an integer, you
105
 
 * 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 
106
136
 * key.
107
137
 */
108
138
int Field_enum::store(int64_t from, bool)
111
141
 
112
142
  if (from <= 0 || (uint64_t) from > typelib->count)
113
143
  {
114
 
    /* Convert the integer to a string using boost::lexical_cast */
115
 
    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;
116
148
 
117
149
    my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), tmp.c_str());
118
150
    return 1;
121
153
  return 0;
122
154
}
123
155
 
124
 
double Field_enum::val_real(void) const
 
156
double Field_enum::val_real(void)
125
157
{
126
158
  return (double) Field_enum::val_int();
127
159
}
128
160
 
129
 
int64_t Field_enum::val_int(void) const
 
161
int64_t Field_enum::val_int(void)
130
162
{
131
163
  ASSERT_COLUMN_MARKED_FOR_READ;
132
164
 
133
 
  uint16_t tmp;
134
 
#ifdef WORDS_BIGENDIAN
135
 
  if (getTable()->getShare()->db_low_byte_first)
136
 
    tmp= sint4korr(ptr);
137
 
  else
138
 
#endif
139
 
    longget(tmp,ptr);
140
 
  return ((int64_t) tmp) + 1; /* SQL is from 1, we store from 0 */
141
 
}
142
 
 
143
 
String *Field_enum::val_str(String *, String *val_ptr) const
 
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;
 
223
}
 
224
 
 
225
String *Field_enum::val_str(String *, String *val_ptr)
144
226
{
145
227
  uint32_t tmp=(uint32_t) Field_enum::val_int();
146
228
 
147
229
  ASSERT_COLUMN_MARKED_FOR_READ;
148
230
 
149
 
  if (not tmp || tmp > typelib->count)
150
 
  {
 
231
  if (!tmp || tmp > typelib->count)
151
232
    val_ptr->set("", 0, field_charset);
152
 
  }
153
233
  else
154
 
  {
155
 
    val_ptr->set((const char*) typelib->type_names[tmp-1], typelib->type_lengths[tmp-1], field_charset);
156
 
  }
157
 
 
 
234
    val_ptr->set((const char*) typelib->type_names[tmp-1],
 
235
                 typelib->type_lengths[tmp-1],
 
236
                 field_charset);
158
237
  return val_ptr;
159
238
}
160
239
 
162
241
{
163
242
  unsigned char *old= ptr;
164
243
  ptr= (unsigned char*) a_ptr;
165
 
  uint64_t a= Field_enum::val_int();
 
244
  uint64_t a=Field_enum::val_int();
166
245
  ptr= (unsigned char*) b_ptr;
167
 
  uint64_t b= Field_enum::val_int();
 
246
  uint64_t b=Field_enum::val_int();
168
247
  ptr= old;
169
248
  return (a < b) ? -1 : (a > b) ? 1 : 0;
170
249
}
171
250
 
172
251
void Field_enum::sort_string(unsigned char *to,uint32_t )
173
252
{
174
 
  uint64_t value=Field_enum::val_int()-1; /* SQL is 1 based, stored as 0 based*/
175
 
  to+=pack_length() -1;
176
 
  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++)
177
256
  {
178
257
    *to-- = (unsigned char) (value & 255);
179
258
    value>>=8;
192
271
  uint32_t *len= typelib->type_lengths;
193
272
  for (const char **pos= typelib->type_names; *pos; pos++, len++)
194
273
  {
195
 
    size_t dummy_errors;
 
274
    uint32_t dummy_errors;
196
275
    if (flag)
197
276
      res.append(',');
198
277
    /* convert to res.charset() == utf8, then quote */
203
282
  res.append(')');
204
283
}
205
284
 
206
 
Field *Field_enum::new_field(memory::Root *root, Table *new_table,
 
285
Field *Field_enum::new_field(MEM_ROOT *root, Table *new_table,
207
286
                             bool keep_type)
208
287
{
209
288
  Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
210
289
  if (res)
211
 
  {
212
 
    res->typelib= typelib->copy_typelib(root);
213
 
  }
 
290
    res->typelib= copy_typelib(root, typelib);
214
291
  return res;
215
292
}
216
 
 
217
 
} /* namespace drizzled */