Drizzled Public API Documentation

string.cc

00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems, Inc.
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018  */
00019 
00020 #include <config.h>
00021 
00022 #include <drizzled/session.h>
00023 #include <drizzled/error.h>
00024 #include <drizzled/item/string.h>
00025 
00026 namespace drizzled
00027 {
00028 
00029 Item *Item_string::safe_charset_converter(const CHARSET_INFO * const tocs)
00030 {
00031   Item_string *conv;
00032   size_t conv_errors;
00033   char *ptr;
00034   String tmp, cstr, *ostr= val_str(&tmp);
00035   cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
00036   if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(),
00037                                              cstr.charset(),
00038                                              collation.derivation)))
00039   {
00040     /*
00041       Safe conversion is not possible (or EOM).
00042       We could not convert a string into the requested character set
00043       without data loss. The target charset does not cover all the
00044       characters from the string. Operation cannot be done correctly.
00045     */
00046     return NULL;
00047   }
00048 
00049   if (!(ptr= getSession().strmake(cstr.ptr(), cstr.length())))
00050     return NULL;
00051 
00052   conv->str_value.set(ptr, cstr.length(), cstr.charset());
00053   /* Ensure that no one is going to change the result string */
00054   conv->str_value.mark_as_const();
00055   return conv;
00056 }
00057 
00058 
00059 Item *Item_static_string_func::safe_charset_converter(const CHARSET_INFO * const tocs)
00060 {
00061   Item_string *conv;
00062   size_t conv_errors;
00063   String tmp, cstr, *ostr= val_str(&tmp);
00064   cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
00065   if (conv_errors ||
00066       !(conv= new Item_static_string_func(func_name,
00067                                           cstr.ptr(), cstr.length(),
00068                                           cstr.charset(),
00069                                           collation.derivation)))
00070   {
00071     /*
00072       Safe conversion is not possible (or EOM).
00073       We could not convert a string into the requested character set
00074       without data loss. The target charset does not cover all the
00075       characters from the string. Operation cannot be done correctly.
00076     */
00077     return NULL;
00078   }
00079   conv->str_value.copy();
00080   /* Ensure that no one is going to change the result string */
00081   conv->str_value.mark_as_const();
00082   return conv;
00083 }
00084 
00085 
00086 bool Item_string::eq(const Item *item, bool binary_cmp) const
00087 {
00088   if (type() == item->type() && item->basic_const_item())
00089   {
00090     if (binary_cmp)
00091       return !stringcmp(&str_value, &item->str_value);
00092     return (collation.collation == item->collation.collation &&
00093             !sortcmp(&str_value, &item->str_value, collation.collation));
00094   }
00095   return 0;
00096 }
00097 
00098 void Item_string::print(String *str)
00099 {
00100   if (is_cs_specified())
00101   {
00102     str->append('_');
00103     str->append(collation.collation->csname);
00104   }
00105 
00106   str->append('\'');
00107 
00108   str_value.print(str);
00109 
00110   str->append('\'');
00111 }
00112 
00113 double Item_string::val_real()
00114 {
00115   assert(fixed == 1);
00116   int error;
00117   char *end, *org_end;
00118   double tmp;
00119   const CHARSET_INFO * const cs= str_value.charset();
00120 
00121   org_end= (char*) str_value.ptr() + str_value.length();
00122   tmp= my_strntod(cs, (char*) str_value.ptr(), str_value.length(), &end,
00123                   &error);
00124   if (error || (end != org_end && !check_if_only_end_space(cs, end, org_end)))
00125   {
00126     /*
00127       We can use str_value.ptr() here as Item_string is gurantee to put an
00128       end \0 here.
00129     */
00130     push_warning_printf(&getSession(), DRIZZLE_ERROR::WARN_LEVEL_WARN,
00131                         ER_TRUNCATED_WRONG_VALUE,
00132                         ER(ER_TRUNCATED_WRONG_VALUE), "DOUBLE",
00133                         str_value.ptr());
00134   }
00135   return tmp;
00136 }
00137 
00142 int64_t Item_string::val_int()
00143 {
00144   assert(fixed == 1);
00145   int err;
00146   int64_t tmp;
00147   char *end= (char*) str_value.ptr()+ str_value.length();
00148   char *org_end= end;
00149   const CHARSET_INFO * const cs= str_value.charset();
00150 
00151   tmp= (*(cs->cset->strtoll10))(cs, str_value.ptr(), &end, &err);
00152   /*
00153     TODO: Give error if we wanted a signed integer and we got an unsigned
00154     one
00155   */
00156   if (err > 0 ||
00157       (end != org_end && !check_if_only_end_space(cs, end, org_end)))
00158   {
00159     push_warning_printf(&getSession(), DRIZZLE_ERROR::WARN_LEVEL_WARN,
00160                         ER_TRUNCATED_WRONG_VALUE,
00161                         ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
00162                         str_value.ptr());
00163   }
00164   return tmp;
00165 }
00166 
00167 type::Decimal *Item_string::val_decimal(type::Decimal *decimal_value)
00168 {
00169   return val_decimal_from_string(decimal_value);
00170 }
00171 
00172 int Item_string::save_in_field(Field *field, bool)
00173 {
00174   String *result;
00175   result=val_str(&str_value);
00176   return save_str_value_in_field(field, result);
00177 }
00178 
00179 
00180 } /* namespace drizzled */