~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/enum.cc

  • Committer: Monty Taylor
  • Date: 2009-12-14 22:00:27 UTC
  • mto: (1241.9.10 out-of-tree)
  • mto: This revision was merged to the branch mainline in revision 1250.
  • Revision ID: mordred@inaugust.com-20091214220027-kpmfbl452nctzc0g
pandora-build v0.85 - Fixed C++ standard setting.

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
140
205
}
141
206
 
142
207
String *Field_enum::val_str(String *, String *val_ptr)
145
210
 
146
211
  ASSERT_COLUMN_MARKED_FOR_READ;
147
212
 
148
 
  if (not tmp || tmp > typelib->count)
149
 
  {
 
213
  if (!tmp || tmp > typelib->count)
150
214
    val_ptr->set("", 0, field_charset);
151
 
  }
152
215
  else
153
 
  {
154
 
    val_ptr->set((const char*) typelib->type_names[tmp-1], typelib->type_lengths[tmp-1], field_charset);
155
 
  }
156
 
 
 
216
    val_ptr->set((const char*) typelib->type_names[tmp-1],
 
217
                 typelib->type_lengths[tmp-1],
 
218
                 field_charset);
157
219
  return val_ptr;
158
220
}
159
221
 
161
223
{
162
224
  unsigned char *old= ptr;
163
225
  ptr= (unsigned char*) a_ptr;
164
 
  uint64_t a= Field_enum::val_int();
 
226
  uint64_t a=Field_enum::val_int();
165
227
  ptr= (unsigned char*) b_ptr;
166
 
  uint64_t b= Field_enum::val_int();
 
228
  uint64_t b=Field_enum::val_int();
167
229
  ptr= old;
168
230
  return (a < b) ? -1 : (a > b) ? 1 : 0;
169
231
}
170
232
 
171
233
void Field_enum::sort_string(unsigned char *to,uint32_t )
172
234
{
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++)
 
235
  uint64_t value=Field_enum::val_int();
 
236
  to+=packlength-1;
 
237
  for (uint32_t i=0 ; i < packlength ; i++)
176
238
  {
177
239
    *to-- = (unsigned char) (value & 255);
178
240
    value>>=8;
191
253
  uint32_t *len= typelib->type_lengths;
192
254
  for (const char **pos= typelib->type_names; *pos; pos++, len++)
193
255
  {
194
 
    size_t dummy_errors;
 
256
    uint32_t dummy_errors;
195
257
    if (flag)
196
258
      res.append(',');
197
259
    /* convert to res.charset() == utf8, then quote */
202
264
  res.append(')');
203
265
}
204
266
 
205
 
Field *Field_enum::new_field(memory::Root *root, Table *new_table,
 
267
Field *Field_enum::new_field(MEM_ROOT *root, Table *new_table,
206
268
                             bool keep_type)
207
269
{
208
270
  Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
209
271
  if (res)
210
 
  {
211
272
    res->typelib= copy_typelib(root, typelib);
212
 
  }
213
273
  return res;
214
274
}
215
 
 
216
 
} /* namespace drizzled */