00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #if !defined(MYSQLPP_MYSTRING_H)
00030 #define MYSQLPP_MYSTRING_H
00031
00032 #include "common.h"
00033
00034 #include "datetime.h"
00035 #include "exceptions.h"
00036 #include "null.h"
00037 #include "sql_buffer.h"
00038
00039 #include <string>
00040 #include <sstream>
00041 #include <limits>
00042
00043 #include <stdlib.h>
00044 #include <string.h>
00045
00046 namespace mysqlpp {
00047
00048 #if !defined(DOXYGEN_IGNORE)
00049
00050
00051 namespace detail
00052 {
00053 template<typename T, bool is_signed = std::numeric_limits<T>::is_signed>
00054 struct conv_promotion;
00055
00056 template<>
00057 struct conv_promotion<float>
00058 {
00059 typedef double type;
00060 };
00061
00062 template<>
00063 struct conv_promotion<double>
00064 {
00065 typedef double type;
00066 };
00067
00068 # if !defined(NO_LONG_LONGS)
00069 template<>
00070 struct conv_promotion<unsigned long long>
00071 {
00072 typedef unsigned long long type;
00073 };
00074
00075 template<>
00076 struct conv_promotion<long long>
00077 {
00078 typedef long long type;
00079 };
00080 # endif
00081
00082
00083 template<>
00084 struct conv_promotion<char>
00085 {
00086 typedef long type;
00087 };
00088
00089
00090
00091 template<typename T>
00092 struct conv_promotion<T, true>
00093 {
00094 typedef long type;
00095 };
00096
00097 template<typename T>
00098 struct conv_promotion<T, false>
00099 {
00100 typedef unsigned long type;
00101 };
00102 }
00103
00104 class MYSQLPP_EXPORT SQLTypeAdapter;
00105 #endif // !defined(DOXYGEN_IGNORE)
00106
00138
00139 class MYSQLPP_EXPORT String
00140 {
00141 public:
00144 typedef const char value_type;
00145
00147 typedef size_t size_type;
00148
00150 typedef const char* const_iterator;
00151
00154 typedef const_iterator iterator;
00155
00156 #if !defined(DOXYGEN_IGNORE)
00157
00158 typedef int difference_type;
00159 typedef const char* const_pointer;
00160 typedef const_pointer pointer;
00161 #endif // !defined(DOXYGEN_IGNORE)
00162
00167 String() :
00168 buffer_()
00169 {
00170 }
00171
00179 String(const String& other) :
00180 buffer_(other.buffer_)
00181 {
00182 }
00183
00196 explicit String(const char* str, size_type len,
00197 mysql_type_info type = mysql_type_info::string_type,
00198 bool is_null = false) :
00199 buffer_(new SQLBuffer(str, len, type, is_null))
00200 {
00201 }
00202
00210 explicit String(const std::string& str,
00211 mysql_type_info type = mysql_type_info::string_type,
00212 bool is_null = false) :
00213 buffer_(new SQLBuffer(str.data(), static_cast<size_type>(str.length()),
00214 type, is_null))
00215 {
00216 }
00217
00225 explicit String(const char* str,
00226 mysql_type_info type = mysql_type_info::string_type,
00227 bool is_null = false) :
00228 buffer_(new SQLBuffer(str, static_cast<size_type>(strlen(str)),
00229 type, is_null))
00230 {
00231 }
00232
00234 ~String() { }
00235
00242 void assign(const char* str, size_type len,
00243 mysql_type_info type = mysql_type_info::string_type,
00244 bool is_null = false)
00245 {
00246 buffer_ = new SQLBuffer(str, len, type, is_null);
00247 }
00248
00255 void assign(const std::string& str,
00256 mysql_type_info type = mysql_type_info::string_type,
00257 bool is_null = false)
00258 {
00259 buffer_ = new SQLBuffer(str.data(),
00260 static_cast<size_type>(str.length()), type, is_null);
00261 }
00262
00269 void assign(const char* str,
00270 mysql_type_info type = mysql_type_info::string_type,
00271 bool is_null = false)
00272 {
00273 buffer_ = new SQLBuffer(str, static_cast<size_type>(strlen(str)),
00274 type, is_null);
00275 }
00276
00281 char at(size_type pos) const;
00282
00285 const_iterator begin() const { return data(); }
00286
00288 const char* c_str() const { return data(); }
00289
00290 #if defined(MYSQLPP_PLATFORM_VISUAL_CPP)
00291
00292 # pragma warning(disable: 4244)
00293 #endif
00294
00297 template <class Type>
00298 Type conv(Type) const
00299 {
00300
00301
00302
00303 typedef typename detail::conv_promotion<Type>::type conv_type;
00304 return do_conv<conv_type>(typeid(Type).name());
00305 }
00306
00307 #if defined(MYSQLPP_PLATFORM_VISUAL_CPP)
00308 # pragma warning(default: 4244)
00309 #endif
00310
00317 template <class T, class B>
00318 Null<T, B> conv(Null<T, B>) const
00319 {
00320 if (is_null()) {
00321 return Null<T, B>(null);
00322 }
00323 else {
00324 return Null<T, B>(conv(T()));
00325 }
00326 }
00327
00333 int compare(const String& other) const;
00334
00340 int compare(const std::string& other) const;
00341
00350 int compare(size_type pos, size_type num, std::string& other) const;
00351
00357 int compare(const char* other) const;
00358
00369 int compare(size_type pos, size_type num, const char* other) const;
00370
00373 const char* data() const;
00374
00377 const_iterator end() const;
00378
00381 bool escape_q() const;
00382
00384 bool is_null() const;
00385
00387 void it_is_null();
00388
00397 size_type length() const;
00398
00404 size_type max_size() const { return size(); }
00405
00408 bool quote_q() const;
00409
00414 size_type size() const { return length(); }
00415
00418 void strip_leading_blanks(std::string& s) const
00419 {
00420 const char* pc = data();
00421 if (pc) {
00422 size_type n = length();
00423 while (n && (*pc == ' ')) {
00424 ++pc;
00425 --n;
00426 }
00427
00428 s.assign(pc, n);
00429 }
00430 else {
00431 s.clear();
00432 }
00433 }
00434
00442 void to_string(std::string& s) const;
00443
00445 mysql_type_info type() const
00446 {
00447 return buffer_ ? buffer_->type() : mysql_type_info::string_type;
00448 }
00449
00451 String& operator =(const std::string& rhs)
00452 {
00453 buffer_ = new SQLBuffer(rhs.data(),
00454 static_cast<size_type>(rhs.length()),
00455 mysql_type_info::string_type, false);
00456
00457 return *this;
00458 }
00459
00464 String& operator =(const char* str)
00465 {
00466 buffer_ = new SQLBuffer(str,
00467 static_cast<size_type>(strlen(str)),
00468 mysql_type_info::string_type, false);
00469
00470 return *this;
00471 }
00472
00478 String& operator =(const String& other)
00479 {
00480 buffer_ = other.buffer_;
00481
00482 return *this;
00483 }
00484
00489 template <typename T>
00490 bool operator ==(const T& rhs) const
00491 {
00492 return compare(rhs) == 0;
00493 }
00494
00498 bool operator ==(const mysqlpp::null_type&) const
00499 {
00500 return is_null();
00501 }
00502
00507 template <typename T>
00508 bool operator !=(const T& rhs) const
00509 {
00510 return compare(rhs) != 0;
00511 }
00512
00516 bool operator !=(const mysqlpp::null_type&) const
00517 {
00518 return !is_null();
00519 }
00520
00525 char operator [](size_type pos) const;
00526
00528 operator const char*() const { return data(); }
00529
00531 operator signed char() const
00532 { return conv(static_cast<signed char>(0)); }
00533
00535 operator unsigned char() const
00536 { return conv(static_cast<unsigned char>(0)); }
00537
00539 operator int() const
00540 { return conv(static_cast<int>(0)); }
00541
00543 operator unsigned int() const
00544 { return conv(static_cast<unsigned int>(0)); }
00545
00547 operator short int() const
00548 { return conv(static_cast<short int>(0)); }
00549
00552 operator unsigned short int() const
00553 { return conv(static_cast<unsigned short int>(0)); }
00554
00556 operator long int() const
00557 { return conv(static_cast<long int>(0)); }
00558
00561 operator unsigned long int() const
00562 { return conv(static_cast<unsigned long int>(0)); }
00563
00564 #if !defined(NO_LONG_LONGS)
00567 operator longlong() const
00568 { return conv(static_cast<longlong>(0)); }
00569
00572 operator ulonglong() const
00573 { return conv(static_cast<ulonglong>(0)); }
00574 #endif
00575
00577 operator float() const
00578 { return conv(static_cast<float>(0)); }
00579
00581 operator double() const
00582 { return conv(static_cast<double>(0)); }
00583
00585 operator bool() const { return buffer_ ? atoi(c_str()) : false; }
00586
00588 operator Date() const { return buffer_ ? Date(*this) : Date(); }
00589
00591 operator DateTime() const
00592 { return buffer_ ? DateTime(*this) : DateTime(); }
00593
00595 operator Time() const { return buffer_ ? Time(*this) : Time(); }
00596
00600 template <class T, class B>
00601 operator Null<T, B>() const { return conv(Null<T, B>()); }
00602
00603 private:
00605 template <class Type>
00606 Type do_conv(const char* type_name) const
00607 {
00608 if (buffer_) {
00609 std::stringstream buf;
00610 buf.write(data(), length());
00611 buf.imbue(std::locale::classic());
00612 Type num = Type();
00613
00614 if (buf >> num) {
00615 char c;
00616 if (!(buf >> c)) {
00617
00618
00619 return num;
00620 }
00621
00622 if (c == '.' &&
00623 (typeid(Type) != typeid(float)) &&
00624 (typeid(Type) != typeid(double))) {
00625
00626
00627
00628
00629 c = '0';
00630 while (buf >> c && c == '0') ;
00631 if (buf.eof() && c == '0') {
00632 return num;
00633 }
00634 }
00635 }
00636 else if (buf.eof()) {
00637 return num;
00638 }
00639
00640 throw BadConversion(type_name, data(), 0, length());
00641 }
00642 else {
00643 return 0;
00644 }
00645 }
00646
00647 RefCountedBuffer buffer_;
00648
00649 friend class SQLTypeAdapter;
00650 };
00651
00652 MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& o,
00653 const String& in);
00654
00655
00656 #if !defined(MYSQLPP_NO_BINARY_OPERS) && !defined(DOXYGEN_IGNORE)
00657
00658
00659
00660
00661
00662 #define oprsw(opr, other, conv) \
00663 inline other operator opr (String x, other y) \
00664 { return static_cast<conv>(x) opr y; } \
00665 inline other operator opr (other x, String y) \
00666 { return x opr static_cast<conv>(y); }
00667
00668 #define operator_binary(other, conv) \
00669 oprsw(+, other, conv) \
00670 oprsw(-, other, conv) \
00671 oprsw(*, other, conv) \
00672 oprsw(/, other, conv)
00673
00674 #define operator_binary_int(other, conv) \
00675 operator_binary(other, conv) \
00676 oprsw(%, other, conv) \
00677 oprsw(&, other, conv) \
00678 oprsw(^, other, conv) \
00679 oprsw(|, other, conv) \
00680 oprsw(<<, other, conv) \
00681 oprsw(>>, other, conv)
00682
00683
00684 #if defined(MYSQLPP_PLATFORM_VISUAL_CPP)
00685 # pragma warning(disable: 4244)
00686 #endif
00687
00688 operator_binary(float, double)
00689 operator_binary(double, double)
00690
00691 operator_binary_int(char, long int)
00692 operator_binary_int(int, long int)
00693 operator_binary_int(short int, long int)
00694 operator_binary_int(long int, long int)
00695
00696 operator_binary_int(unsigned char, unsigned long int)
00697 operator_binary_int(unsigned int, unsigned long int)
00698 operator_binary_int(unsigned short int, unsigned long int)
00699 operator_binary_int(unsigned long int, unsigned long int)
00700
00701 #if defined(MYSQLPP_PLATFORM_VISUAL_CPP)
00702 # pragma warning(default: 4244)
00703 #endif
00704
00705 #if !defined(NO_LONG_LONGS)
00706 operator_binary_int(longlong, longlong)
00707 operator_binary_int(ulonglong, ulonglong)
00708 #endif // !defined(NO_LONG_LONGS)
00709 #endif // !defined(MYSQLPP_NO_BINARY_OPERS) && !defined(DOXYGEN_IGNORE)
00710
00711
00712 #if !defined(DOXYGEN_IGNORE)
00713
00714
00715
00721 template <> MYSQLPP_EXPORT bool String::conv(bool) const;
00722
00735 template <> MYSQLPP_EXPORT String String::conv(String) const;
00736
00738 template <> MYSQLPP_EXPORT std::string String::conv(std::string) const;
00739
00745 template <> MYSQLPP_EXPORT Date String::conv(Date) const;
00746
00752 template <> MYSQLPP_EXPORT DateTime String::conv(DateTime) const;
00753
00759 template <> MYSQLPP_EXPORT Time String::conv(Time) const;
00760
00761 #endif // !defined(DOXYGEN_IGNORE)
00762
00763 }
00764
00765 #endif // !defined(MYSQLPP_MYSTRING_H)