- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

mystring.h
Go to the documentation of this file.
1
5 /***********************************************************************
6 Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and
7 (c) 2004-2008 by Educational Technology Resources, Inc. Others may
8 also hold copyrights on code in this file. See the CREDITS.txt file
9 in the top directory of the distribution for details.
10
11 This file is part of MySQL++.
12
13 MySQL++ is free software; you can redistribute it and/or modify it
14 under the terms of the GNU Lesser General Public License as published
15 by the Free Software Foundation; either version 2.1 of the License, or
16 (at your option) any later version.
17
18 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
21 License for more details.
22
23 You should have received a copy of the GNU Lesser General Public
24 License along with MySQL++; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
26 USA
27 ***********************************************************************/
28
29 #if !defined(MYSQLPP_MYSTRING_H)
30 #define MYSQLPP_MYSTRING_H
31
32 #include "common.h"
33
34 #include "datetime.h"
35 #include "exceptions.h"
36 #include "null.h"
37 #include "sql_buffer.h"
38
39 #include <string>
40 #include <sstream>
41 #include <limits>
42
43 #include <stdlib.h>
44 #include <string.h>
45
46 namespace mysqlpp {
47
48 #if !defined(DOXYGEN_IGNORE)
49 // Doxygen will not generate documentation for this section.
50
51 namespace detail
52 {
53 template<typename T, bool is_signed = std::numeric_limits<T>::is_signed>
54 struct conv_promotion;
55
56 template<>
57 struct conv_promotion<float>
58 {
59 typedef double type;
60 };
61
62 template<>
63 struct conv_promotion<double>
64 {
65 typedef double type;
66 };
67
68 # if !defined(NO_LONG_LONGS)
69 template<>
70 struct conv_promotion<unsigned long long>
71 {
72 typedef unsigned long long type;
73 };
74
75 template<>
76 struct conv_promotion<long long>
77 {
78 typedef long long type;
79 };
80 # endif
81
82 // preserve existing behaviour, char converted as signed long
83 template<>
84 struct conv_promotion<char>
85 {
86 typedef long type;
87 };
88
89 // all other types use signed/unsigned long
90
91 template<typename T>
92 struct conv_promotion<T, true>
93 {
94 typedef long type;
95 };
96
97 template<typename T>
98 struct conv_promotion<T, false>
99 {
100 typedef unsigned long type;
101 };
102 } // namespace detail
103
104 class MYSQLPP_EXPORT SQLTypeAdapter;
105 #endif // !defined(DOXYGEN_IGNORE)
106
138
139 class MYSQLPP_EXPORT String
140 {
141 public:
144 typedef const char value_type;
145
147 typedef size_t size_type;
148
150 typedef const char* const_iterator;
151
154 typedef const_iterator iterator;
155
156 #if !defined(DOXYGEN_IGNORE)
157 // Doxygen will not generate documentation for this section.
158 typedef int difference_type;
159 typedef const char* const_pointer;
160 typedef const_pointer pointer;
161 #endif // !defined(DOXYGEN_IGNORE)
162
167 String() :
168 buffer_()
169 {
170 }
171
179 String(const String& other) :
180 buffer_(other.buffer_)
181 {
182 }
183
196 explicit String(const char* str, size_type len,
197 mysql_type_info type = mysql_type_info::string_type,
198 bool is_null = false) :
199 buffer_(new SQLBuffer(str, len, type, is_null))
200 {
201 }
202
210 explicit String(const std::string& str,
211 mysql_type_info type = mysql_type_info::string_type,
212 bool is_null = false) :
213 buffer_(new SQLBuffer(str.data(), static_cast<size_type>(str.length()),
214 type, is_null))
215 {
216 }
217
225 explicit String(const char* str,
226 mysql_type_info type = mysql_type_info::string_type,
227 bool is_null = false) :
228 buffer_(new SQLBuffer(str, static_cast<size_type>(strlen(str)),
229 type, is_null))
230 {
231 }
232
234 ~String() { }
235
242 void assign(const char* str, size_type len,
243 mysql_type_info type = mysql_type_info::string_type,
244 bool is_null = false)
245 {
246 buffer_ = new SQLBuffer(str, len, type, is_null);
247 }
248
255 void assign(const std::string& str,
256 mysql_type_info type = mysql_type_info::string_type,
257 bool is_null = false)
258 {
259 buffer_ = new SQLBuffer(str.data(),
260 static_cast<size_type>(str.length()), type, is_null);
261 }
262
269 void assign(const char* str,
270 mysql_type_info type = mysql_type_info::string_type,
271 bool is_null = false)
272 {
273 buffer_ = new SQLBuffer(str, static_cast<size_type>(strlen(str)),
274 type, is_null);
275 }
276
281 char at(size_type pos) const;
282
285 const_iterator begin() const { return data(); }
286
288 const char* c_str() const { return data(); }
289
290 #if defined(MYSQLPP_PLATFORM_VISUAL_CPP)
291 // Squish VC++ warning about "possible loss of data" for these conversions
292 # pragma warning(disable: 4244)
293 #endif
294
297 template <class Type>
298 Type conv(Type) const
299 {
300 // Conversions are done using one of double/long/ulong/llong/ullong
301 // so we call a helper function to do the work using that type.
302 // This reduces the amount of template code instantiated.
303 typedef typename detail::conv_promotion<Type>::type conv_type;
304 return do_conv<conv_type>(typeid(Type).name());
305 }
306
307 #if defined(MYSQLPP_PLATFORM_VISUAL_CPP)
308 # pragma warning(default: 4244)
309 #endif
310
317 template <class T, class B>
318 Null<T, B> conv(Null<T, B>) const
319 {
320 if (is_null()) {
321 return Null<T, B>(null);
322 }
323 else {
324 return Null<T, B>(conv(T()));
325 }
326 }
327
333 int compare(const String& other) const;
334
340 int compare(const std::string& other) const;
341
350 int compare(size_type pos, size_type num, std::string& other) const;
351
357 int compare(const char* other) const;
358
369 int compare(size_type pos, size_type num, const char* other) const;
370
373 const char* data() const;
374
376 bool empty() const { return size() == 0; }
377
380 const_iterator end() const;
381
384 bool escape_q() const;
385
387 bool is_null() const;
388
390 void it_is_null();
391
400 size_type length() const;
401
407 size_type max_size() const { return size(); }
408
411 bool quote_q() const;
412
417 size_type size() const { return length(); }
418
421 void strip_leading_blanks(std::string& s) const
422 {
423 const char* pc = data();
424 if (pc) {
425 size_type n = length();
426 while (n && (*pc == ' ')) {
427 ++pc;
428 --n;
429 }
430
431 s.assign(pc, n);
432 }
433 else {
434 s.clear();
435 }
436 }
437
445 void to_string(std::string& s) const;
446
448 mysql_type_info type() const
449 {
450 return buffer_ ? buffer_->type() : mysql_type_info::string_type;
451 }
452
454 String& operator =(const std::string& rhs)
455 {
456 buffer_ = new SQLBuffer(rhs.data(),
457 static_cast<size_type>(rhs.length()),
458 mysql_type_info::string_type, false);
459
460 return *this;
461 }
462
467 String& operator =(const char* str)
468 {
469 buffer_ = new SQLBuffer(str,
470 static_cast<size_type>(strlen(str)),
471 mysql_type_info::string_type, false);
472
473 return *this;
474 }
475
481 String& operator =(const String& other)
482 {
483 buffer_ = other.buffer_;
484
485 return *this;
486 }
487
492 template <typename T>
493 bool operator ==(const T& rhs) const
494 {
495 return compare(rhs) == 0;
496 }
497
501 bool operator ==(const mysqlpp::null_type&) const
502 {
503 return is_null();
504 }
505
510 template <typename T>
511 bool operator !=(const T& rhs) const
512 {
513 return compare(rhs) != 0;
514 }
515
519 bool operator !=(const mysqlpp::null_type&) const
520 {
521 return !is_null();
522 }
523
530 char operator [](size_type pos) const { return at(pos); }
531
533 operator const char*() const { return data(); }
534
536 operator signed char() const
537 { return conv(static_cast<signed char>(0)); }
538
540 operator unsigned char() const
541 { return conv(static_cast<unsigned char>(0)); }
542
544 operator int() const
545 { return conv(static_cast<int>(0)); }
546
548 operator unsigned int() const
549 { return conv(static_cast<unsigned int>(0)); }
550
552 operator short int() const
553 { return conv(static_cast<short int>(0)); }
554
557 operator unsigned short int() const
558 { return conv(static_cast<unsigned short int>(0)); }
559
561 operator long int() const
562 { return conv(static_cast<long int>(0)); }
563
566 operator unsigned long int() const
567 { return conv(static_cast<unsigned long int>(0)); }
568
569 #if !defined(NO_LONG_LONGS)
570 operator longlong() const
573 { return conv(static_cast<longlong>(0)); }
574
577 operator ulonglong() const
578 { return conv(static_cast<ulonglong>(0)); }
579 #endif
580
582 operator float() const
583 { return conv(static_cast<float>(0)); }
584
586 operator double() const
587 { return conv(static_cast<double>(0)); }
588
590 operator bool() const { return buffer_ ? atoi(c_str()) : false; }
591
593 operator Date() const { return buffer_ ? Date(*this) : Date(); }
594
596 operator DateTime() const
597 { return buffer_ ? DateTime(*this) : DateTime(); }
598
600 operator Time() const { return buffer_ ? Time(*this) : Time(); }
601
605 template <class T, class B>
606 operator Null<T, B>() const { return conv(Null<T, B>()); }
607
608 private:
610 template <class Type>
611 Type do_conv(const char* type_name) const
612 {
613 if (buffer_) {
614 std::stringstream buf;
615 buf.write(data(), static_cast<std::streamsize>(length()));
616 buf.imbue(std::locale::classic()); // "C" locale
617 Type num = Type();
618
619 if (buf >> num) {
620 char c;
621 if (!(buf >> c)) {
622 // Nothing left in buffer, so conversion complete,
623 // and thus successful.
624 return num;
625 }
626
627 if (c == '.' &&
628 (typeid(Type) != typeid(float)) &&
629 (typeid(Type) != typeid(double))) {
630 // Conversion stopped on a decimal point -- locale
631 // doesn't matter to MySQL -- so only way to succeed
632 // is if it's an integer and everything following
633 // the decimal is inconsequential.
634 c = '0'; // handles '.' at end of string
635 while (buf >> c && c == '0') /* spin */ ;
636 if (buf.eof() && c == '0') {
637 return num; // only zeros after decimal point
638 }
639 }
640 }
641 else if (buf.eof()) {
642 return num; // nothing to convert, return default value
643 }
644
645 throw BadConversion(type_name, data(), 0, length());
646 }
647 else {
648 return 0;
649 }
650 }
651
652 RefCountedBuffer buffer_;
653
654 friend class SQLTypeAdapter;
655 };
656
657 MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& o,
658 const String& in);
659
660
661 #if !defined(MYSQLPP_NO_BINARY_OPERS) && !defined(DOXYGEN_IGNORE)
662 // Ignore this section is MYSQLPP_NO_BINARY_OPERS is defined, or if this
663 // section is being parsed by Doxygen. In the latter case, it's ignored
664 // because Doxygen doesn't understand it correctly, and we can't be
665 // bothered to explain it to Doxygen.
666
667 #define oprsw(opr, other, conv) \
668 inline other operator opr (String x, other y) \
669 { return static_cast<conv>(x) opr y; } \
670 inline other operator opr (other x, String y) \
671 { return x opr static_cast<conv>(y); }
672
673 #define operator_binary(other, conv) \
674 oprsw(+, other, conv) \
675 oprsw(-, other, conv) \
676 oprsw(*, other, conv) \
677 oprsw(/, other, conv)
678
679 #define operator_binary_int(other, conv) \
680 operator_binary(other, conv) \
681 oprsw(%, other, conv) \
682 oprsw(&, other, conv) \
683 oprsw(^, other, conv) \
684 oprsw(|, other, conv) \
685 oprsw(<<, other, conv) \
686 oprsw(>>, other, conv)
687
688 // Squish more complaints about possible loss of data
689 #if defined(MYSQLPP_PLATFORM_VISUAL_CPP)
690 # pragma warning(disable: 4244)
691 #endif
692
693 operator_binary(float, double)
694 operator_binary(double, double)
695
696 operator_binary_int(char, long int)
697 operator_binary_int(int, long int)
698 operator_binary_int(short int, long int)
699 operator_binary_int(long int, long int)
700
701 operator_binary_int(unsigned char, unsigned long int)
702 operator_binary_int(unsigned int, unsigned long int)
703 operator_binary_int(unsigned short int, unsigned long int)
704 operator_binary_int(unsigned long int, unsigned long int)
705
706 #if defined(MYSQLPP_PLATFORM_VISUAL_CPP)
707 # pragma warning(default: 4244)
708 #endif
709
710 #if !defined(NO_LONG_LONGS)
711 operator_binary_int(longlong, longlong)
712 operator_binary_int(ulonglong, ulonglong)
713 #endif // !defined(NO_LONG_LONGS)
714 #endif // !defined(MYSQLPP_NO_BINARY_OPERS) && !defined(DOXYGEN_IGNORE)
715
716
717 #if !defined(DOXYGEN_IGNORE)
718 // Doxygen isn't smart enough to recognize these template
719 // specializations. Maybe it's the MYSQLPP_EXPORT tags?
720
726 template <> MYSQLPP_EXPORT bool String::conv(bool) const;
727
740 template <> MYSQLPP_EXPORT String String::conv(String) const;
741
743 template <> MYSQLPP_EXPORT std::string String::conv(std::string) const;
744
750 template <> MYSQLPP_EXPORT Date String::conv(Date) const;
751
757 template <> MYSQLPP_EXPORT DateTime String::conv(DateTime) const;
758
764 template <> MYSQLPP_EXPORT Time String::conv(Time) const;
765
766 #endif // !defined(DOXYGEN_IGNORE)
767
768 } // end namespace mysqlpp
769
770 #endif // !defined(MYSQLPP_MYSTRING_H)
mysqlpp::String::iterator
const_iterator iterator
Same as const_iterator because the data cannot be changed.
Definition: mystring.h:154
null.h
Declares classes that implement SQL &quot;null&quot; semantics within C++&#39;s type system.
mysqlpp::String::conv
Type conv(Type) const
Template for converting the column data to most any numeric data type.
Definition: mystring.h:298
mysqlpp::String::size_type
size_t size_type
Type of &quot;size&quot; integers.
Definition: mystring.h:147
mysqlpp::String::assign
void assign(const char *str, mysql_type_info type=mysql_type_info::string_type, bool is_null=false)
Assign a C string to this object.
Definition: mystring.h:269
mysqlpp::SQLBuffer
Holds SQL data in string form plus type information for use in converting the string to compatible C+...
Definition: sql_buffer.h:41
mysqlpp::Time
C++ form of SQL&#39;s TIME type.
Definition: datetime.h:347
mysqlpp::DateTime
C++ form of SQL&#39;s DATETIME type.
Definition: datetime.h:48
datetime.h
Declares classes to add SQL-compatible date and time types to C++&#39;s type system.
mysqlpp::mysql_type_info
SQL field type information.
Definition: type_info.h:148
mysqlpp::String::value_type
const char value_type
Type of the data stored in this object, when it is not equal to SQL null.
Definition: mystring.h:144
mysqlpp::String::conv
Null< T, B > conv(Null< T, B >) const
Overload of conv() for types wrapped with Null&lt;&gt;
Definition: mystring.h:318
mysqlpp::mysql_type_info::string_type
static const enum_field_types string_type
The internal constant we use for our string type.
Definition: type_info.h:270
mysqlpp::String::String
String(const char *str, size_type len, mysql_type_info type=mysql_type_info::string_type, bool is_null=false)
Full constructor.
Definition: mystring.h:196
mysqlpp::String::String
String(const String &other)
Copy ctor.
Definition: mystring.h:179
mysqlpp::null_type
The type of the global mysqlpp::null object.
Definition: null.h:49
exceptions.h
Declares the MySQL++-specific exception classes.
mysqlpp::String::c_str
const char * c_str() const
Return a const pointer to the string data.
Definition: mystring.h:288
mysqlpp::String::type
mysql_type_info type() const
Get this object&#39;s current MySQL type.
Definition: mystring.h:448
mysqlpp::String::strip_leading_blanks
void strip_leading_blanks(std::string &s) const
Returns a copy of our internal string without leading blanks.
Definition: mystring.h:421
mysqlpp::Date
C++ form of SQL&#39;s DATE type.
Definition: datetime.h:225
mysqlpp::String::begin
const_iterator begin() const
Return iterator pointing to the first character of the string.
Definition: mystring.h:285
mysqlpp::String::String
String(const std::string &str, mysql_type_info type=mysql_type_info::string_type, bool is_null=false)
C++ string version of full ctor.
Definition: mystring.h:210
mysqlpp::String::const_iterator
const char * const_iterator
Type of iterators.
Definition: mystring.h:150
mysqlpp::String::empty
bool empty() const
Returns true if size() == 0.
Definition: mystring.h:376
mysqlpp::String::max_size
size_type max_size() const
Return the maximum number of characters in the string.
Definition: mystring.h:407
mysqlpp::String::String
String()
Default constructor.
Definition: mystring.h:167
common.h
This file includes top-level definitions for use both internal to the library, and outside it...
mysqlpp::String::assign
void assign(const std::string &str, mysql_type_info type=mysql_type_info::string_type, bool is_null=false)
Assign a C++ string to this object.
Definition: mystring.h:255
mysqlpp::String::~String
~String()
Destroy string.
Definition: mystring.h:234
sql_buffer.h
Declares the SQLBuffer class.
mysqlpp::Null
Class for holding data from a SQL column with the NULL attribute.
Definition: null.h:170
mysqlpp::String::assign
void assign(const char *str, size_type len, mysql_type_info type=mysql_type_info::string_type, bool is_null=false)
Assign raw data to this object.
Definition: mystring.h:242
mysqlpp::String::size
size_type size() const
Return number of bytes in string.
Definition: mystring.h:417
mysqlpp::String
A std::string work-alike that can convert itself from SQL text data formats to C++ data types...
Definition: mystring.h:139
mysqlpp::String::String
String(const char *str, mysql_type_info type=mysql_type_info::string_type, bool is_null=false)
Null-terminated C string version of full ctor.
Definition: mystring.h:225