Drizzled Public API Documentation

str.cc
1 /* - mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2008 MySQL
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 
22 #include <config.h>
23 #include <drizzled/field/str.h>
24 #include <drizzled/error.h>
25 #include <drizzled/table.h>
26 #include <drizzled/session.h>
27 #include <drizzled/internal/m_string.h>
28 
29 namespace drizzled {
30 
31 namespace internal
32 {
33  extern char _dig_vec_upper[];
34 }
35 
36 Field_str::Field_str(unsigned char *ptr_arg,
37  uint32_t len_arg,
38  unsigned char *null_ptr_arg,
39  unsigned char null_bit_arg,
40  const char *field_name_arg,
41  const charset_info_st * const charset_arg)
42  :Field(ptr_arg, len_arg,
43  null_ptr_arg,
44  null_bit_arg,
45  Field::NONE,
46  field_name_arg)
47 {
48  field_charset= charset_arg;
49  if (charset_arg->state & MY_CS_BINSORT)
50  flags|= BINARY_FLAG;
51  field_derivation= DERIVATION_IMPLICIT;
52 }
53 
54 /*
55  Check if we lost any important data and send a truncation error/warning
56 
57  SYNOPSIS
58  Field_str::report_if_important_data()
59  ptr - Truncated rest of string
60  end - End of truncated string
61 
62  RETURN VALUES
63  0 - None was truncated (or we don't count cut fields)
64  2 - Some bytes was truncated
65 
66  NOTE
67  Check if we lost any important data (anything in a binary string,
68  or any non-space in others). If only trailing spaces was lost,
69  send a truncation note, otherwise send a truncation error.
70 */
71 
72 int Field_str::report_if_important_data(const char *field_ptr, const char *end)
73 {
74  if (field_ptr < end && getTable()->in_use->count_cuted_fields)
75  {
76  set_warning(DRIZZLE_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
77  return 2;
78  }
79  return 0;
80 }
81 
103 {
104  char buff[DECIMAL_MAX_STR_LENGTH+1];
105  String str(buff, sizeof(buff), &my_charset_bin);
106  class_decimal2string(d, 0, &str);
107  return store(str.ptr(), str.length(), str.charset());
108 }
109 
110 type::Decimal *Field_str::val_decimal(type::Decimal *decimal_value) const
111 {
112  int2_class_decimal(E_DEC_FATAL_ERROR, val_int(), 0, decimal_value);
113  return decimal_value;
114 }
115 
124 int Field_str::store(double nr)
125 {
126  char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
127  uint32_t local_char_length= field_length / charset()->mbmaxlen;
128  bool error;
129 
130  ASSERT_COLUMN_MARKED_FOR_WRITE;
131 
132  size_t length= internal::my_gcvt(nr, internal::MY_GCVT_ARG_DOUBLE, local_char_length, buff, &error);
133  if (error)
134  {
135  if (getTable()->getSession()->abortOnWarning())
136  {
137  set_warning(DRIZZLE_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
138  }
139  else
140  {
141  set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
142  }
143  }
144  return store(buff, length, charset());
145 }
146 
147 
148 bool check_string_copy_error(Field_str *field,
149  const char *well_formed_error_pos,
150  const char *cannot_convert_error_pos,
151  const char *end,
152  const charset_info_st * const cs)
153 {
154  const char* pos= well_formed_error_pos;
155  if (not pos && not (pos= cannot_convert_error_pos))
156  return false;
157 
158  const char* end_orig= end;
159  set_if_smaller(end, pos + 6);
160 
161  char tmp[64];
162  char* t= tmp;
163  for (; pos < end; pos++)
164  {
165  /*
166  If the source string is ASCII compatible (mbminlen==1)
167  and the source character is in ASCII printable range (0x20..0x7F),
168  then display the character as is.
169 
170  Otherwise, if the source string is not ASCII compatible (e.g. UCS2),
171  or the source character is not in the printable range,
172  then print the character using HEX notation.
173  */
174  if (((unsigned char) *pos) >= 0x20 && ((unsigned char) *pos) <= 0x7F && cs->mbminlen == 1)
175  {
176  *t++= *pos;
177  }
178  else
179  {
180  *t++= '\\';
181  *t++= 'x';
182  *t++= internal::_dig_vec_upper[((unsigned char) *pos) >> 4];
183  *t++= internal::_dig_vec_upper[((unsigned char) *pos) & 15];
184  }
185  }
186  if (end_orig > end)
187  {
188  *t++= '.';
189  *t++= '.';
190  *t++= '.';
191  }
192  *t= '\0';
193  push_warning_printf(field->getTable()->in_use,
194  field->getTable()->in_use->abortOnWarning() ? DRIZZLE_ERROR::WARN_LEVEL_ERROR : DRIZZLE_ERROR::WARN_LEVEL_WARN,
195  ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
196  ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
197  "string", tmp, field->field_name,
198  (uint32_t) field->getTable()->in_use->row_count);
199  return true;
200 }
201 
203 {
204  return field_length + (field_length > 255 ? 2 : 1);
205 }
206 
207 } /* namespace drizzled */
uint32_t max_data_length() const
Definition: str.cc:202
uint32_t row_count
Definition: session.h:447
TODO: Rename this file - func.h is stupid.
int store_decimal(const type::Decimal *)
Definition: str.cc:102
Session * in_use
Definition: table.h:123
int class_decimal2string(const type::Decimal *d, uint32_t fixed_dec, String *str)
Converting decimal to string.
Definition: decimal.cc:197
int store(double nr)
Definition: str.cc:124
const char * field_name
Definition: field.h:102