1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
|
/// \file stadapter.h
/// \brief Declares the SQLTypeAdapter class
/***********************************************************************
Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and
(c) 2004-2008 by Educational Technology Resources, Inc. Others may
also hold copyrights on code in this file. See the CREDITS.txt file
in the top directory of the distribution for details.
This file is part of MySQL++.
MySQL++ is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
License along with MySQL++; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
***********************************************************************/
#if !defined(MYSQLPP_SQL_TYPE_ADAPTER_H)
#define MYSQLPP_SQL_TYPE_ADAPTER_H
#include "common.h"
#include "datetime.h"
#include "null.h"
#include "sql_buffer.h"
#include "sql_types.h"
#include <stdexcept>
#include <string>
namespace mysqlpp {
#if !defined(DOXYGEN_IGNORE)
class MYSQLPP_EXPORT String;
#endif
/// \brief Converts many different data types to strings suitable for
/// use in SQL queries.
///
/// This class provides implicit conversion between many C++ types and
/// SQL-formatted string representations of that data without losing
/// important type information. This class is not for direct use
/// outside MySQL++ itself. It exists for those interfaces in MySQL++
/// that need to accept a value of any reasonable data type which it
/// will use in building a query string.
///
/// One major use for this is in the Query class interfaces for building
/// template queries: they have to be generic with respect to argument
/// type, but because we know we want the data in some kind of string
/// form eventually, we don't need to templatize it. The interface can
/// just use SQLTypeAdapter, which lets callers pass any reasonable data
/// type. The adapter converts the passed value implicitly.
///
/// The other major use for this type is the quoting and escaping logic
/// in Query's stream interface: rather than overload the << operators
/// and the manipulators for every single type we know the rules for \e a
/// \e priori, we just specialize the manipulators for SQLTypeAdapter.
/// The conversion to SQLTypeAdapter stringizes the data, which we needed
/// anyway for stream insertion, and holds enough type information so
/// that the manipulator can decide whether to do automatic quoting
/// and/or escaping.
class MYSQLPP_EXPORT SQLTypeAdapter
{
public:
typedef size_t size_type; ///< size of length values
/// \brief Default constructor; empty string
SQLTypeAdapter();
/// \brief Copy ctor
///
/// \param other the other SQLTypeAdapter object
///
/// This ctor only copies the pointer to the other SQLTypeAdapter's
/// data buffer and increments its reference counter. If you need a
/// deep copy, use one of the ctors that takes a string.
SQLTypeAdapter(const SQLTypeAdapter& other);
/// \brief Create a copy of a MySQL++ string
///
/// This does reference-counted buffer sharing with the other
/// object. If you need a deep copy, pass the result of
/// either String::c_str() or String::conv() instead, which will
/// call one of the other string ctors.
SQLTypeAdapter(const String& str, bool processed = false);
/// \brief Create a copy of a C++ string
SQLTypeAdapter(const std::string& str, bool processed = false);
/// \brief Create a copy of a null-terminated C string
SQLTypeAdapter(const char* str, bool processed = false);
/// \brief Create a copy of an arbitrary block of data
SQLTypeAdapter(const char* str, int len, bool processed = false);
/// \brief Create a single-character string
///
/// If you mean for \c c to be treated as a small integer, you
/// should be using mysqlpp::tiny_int instead. It avoids the
/// confusion in C++ between integer and character. See the
/// documentation for tiny_int.h for details.
SQLTypeAdapter(char c);
/// \brief Create a string representation of SQL \c TINYINT
SQLTypeAdapter(sql_tinyint i);
/// \brief Create a string representation of SQL \c TINYINT
/// \c UNSIGNED
SQLTypeAdapter(sql_tinyint_unsigned i);
/// \brief Create a string representation of a \c short \c int value
SQLTypeAdapter(short i);
/// \brief Create a string representation of an \c unsigned
/// \c short \c int value
SQLTypeAdapter(unsigned short i);
/// \brief Create a string representation of an \c int value
SQLTypeAdapter(int i);
/// \brief Create a string representation of an \c unsigned \c int
/// value
SQLTypeAdapter(unsigned i);
/// \brief Create a string representation of a \c long \c int value
SQLTypeAdapter(long i);
/// \brief Create a string representation of an \c unsigned
/// \c long \c int value
SQLTypeAdapter(unsigned long i);
/// \brief Create a string representation of a \c longlong value
SQLTypeAdapter(longlong i);
/// \brief Create a string representation of an \c unsigned
/// \c longlong value
SQLTypeAdapter(ulonglong i);
/// \brief Create a string representation of a \c float value
SQLTypeAdapter(float i);
/// \brief Create a string representation of a \c double value
SQLTypeAdapter(double i);
/// \brief Create a SQL string representation of a date
SQLTypeAdapter(const Date& d);
/// \brief Create a SQL string representation of a date and time
SQLTypeAdapter(const DateTime& dt);
/// \brief Create a SQL string representation of a time
SQLTypeAdapter(const Time& t);
/// \brief Create object representing SQL NULL
SQLTypeAdapter(const null_type& i);
/// \brief Standard assignment operator
///
/// \see assign(const SQLTypeAdapter&) for details
SQLTypeAdapter& operator =(const SQLTypeAdapter& rhs);
/// \brief Replace contents of object with a SQL null
///
/// \see assign(const null_type&) for details
SQLTypeAdapter& operator =(const null_type& n);
/// \brief Returns a const char pointer to the object's raw data
operator const char*() const { return data(); }
/// \brief Copies another SQLTypeAdapter's data buffer into this
/// object.
///
/// \param sta Other object to copy
///
/// \retval *this
///
/// Detaches this object from its internal buffer and attaches
/// itself to the other object's buffer, with reference counting
/// on each side. If you need a deep copy, call one of the
/// assign() overloads taking a C or C++ string instead.
SQLTypeAdapter& assign(const SQLTypeAdapter& sta);
/// \brief Copies a C string or a raw buffer into this object.
///
/// \param pc Pointer to char buffer to copy
/// \param len Number of characters to copy; default tells function
/// to use the return value of strlen() instead.
///
/// \retval *this
///
/// If you give the len parameter, this function will treat pc as a
/// pointer to an array of char, not as a C string. It only treats
/// null characters as special when you leave len at its default.
SQLTypeAdapter& assign(const char* pc, int len = -1);
/// \brief Replaces contents of object with a SQL null
///
/// \param n typically, the MySQL++ global object mysqlpp::null
///
/// \retval *this
SQLTypeAdapter& assign(const null_type& n);
/// \brief Returns the character at a given position within the
/// string buffer.
///
/// \throw mysqlpp::BadIndex if the internal buffer is not
/// initialized (default ctor called, and no subsequent assignment)
/// or if there are not at least i + 1 characters in the buffer.
///
/// WARNING: The throw-spec is incorrect, but it can't be changed
/// until v4, where we can break the ABI. Throw-specs shouldn't be
/// relied on anyway.
char at(size_type i) const throw(std::out_of_range);
/// \brief Compare the internal buffer to the given string
///
/// Works just like string::compare(const std::string&).
int compare(const SQLTypeAdapter& other) const;
/// \brief Compare the internal buffer to the given string
///
/// Works just like string::compare(const std::string&).
int compare(const std::string& other) const;
/// \brief Compare the internal buffer to the given string
///
/// Works just like string::compare(size_type, size_type,
/// std::string&).
int compare(size_type pos, size_type num, std::string& other) const;
/// \brief Compare the internal buffer to the given string
///
/// Works just like string::compare(const char*).
int compare(const char* other) const;
/// \brief Compare the internal buffer to the given string
///
/// Works just like string::compare(size_type, size_type,
/// const char*).
int compare(size_type pos, size_type num, const char* other) const;
/// \brief Return pointer to raw data buffer
const char* data() const;
/// \brief Returns true if we were initialized with a data type
/// that must be escaped when used in a SQL query
bool escape_q() const;
/// \brief Returns true if the internal 'processed' flag is set.
///
/// This is an implementation detail of template queries, used to
/// prevent repeated processing of values.
bool is_processed() const { return is_processed_; }
/// \brief Return number of bytes in data buffer
size_type length() const;
size_type size() const { return length(); } ///< alias for length()
/// \brief Returns true if we were initialized with a data type
/// that must be quoted when used in a SQL query
bool quote_q() const;
/// \brief Returns the type ID of the buffer's data
///
/// Values from type_info.h. At the moment, these are the same as
/// the underlying MySQL C API type IDs, but it's not a good idea
/// to count on this remaining the case.
int type_id() const;
/// \brief Turns on the internal 'is_processed_' flag.
///
/// This is an implementation detail of template queries, used to
/// prevent repeated processing of values.
void set_processed() { is_processed_ = true; }
#if !defined(DOXYGEN_IGNORE)
// Parallel interface for Null<>-wrapped versions of types we
// support above. No need for parallel documentation.
SQLTypeAdapter(const Null<std::string>& str, bool processed = false);
SQLTypeAdapter(const Null<String>& str, bool processed = false);
SQLTypeAdapter(Null<char> c);
SQLTypeAdapter(Null<sql_tinyint> i);
SQLTypeAdapter(Null<sql_tinyint_unsigned> i);
SQLTypeAdapter(Null<short> i);
SQLTypeAdapter(Null<unsigned short> i);
SQLTypeAdapter(Null<int> i);
SQLTypeAdapter(Null<unsigned> i);
SQLTypeAdapter(Null<long> i);
SQLTypeAdapter(Null<unsigned long> i);
SQLTypeAdapter(Null<longlong> i);
SQLTypeAdapter(Null<ulonglong> i);
SQLTypeAdapter(Null<float> i);
SQLTypeAdapter(Null<double> i);
SQLTypeAdapter(const Null<Date>& d);
SQLTypeAdapter(const Null<DateTime>& dt);
SQLTypeAdapter(const Null<Time>& t);
SQLTypeAdapter& operator =(const Null<std::string>& str);
#endif // !defined(DOXYGEN_IGNORE)
private:
/// \brief Our internal string buffer
RefCountedBuffer buffer_;
/// \brief If true, one of the MySQL++ manipulators has processed
/// the string data.
///
/// "Processing" is escaping special SQL characters, and/or adding
/// quotes. See the documentation for manip.h for details.
///
/// This flag is used by the template query mechanism, to prevent a
/// string from being re-escaped or re-quoted each time that query
/// is reused. The flag is reset by operator=, to force the new
/// parameter value to be re-processed.
bool is_processed_;
};
} // end namespace mysqlpp
#endif // !defined(MYSQLPP_SQL_TYPE_ADAPTER_H)
|