mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Merge commit 'caab155a00ca0158dcb16844bea5326e2a2c2562' into dn
This commit is contained in:
5
src/soci/include/private/README.md
Normal file
5
src/soci/include/private/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# soci/include/private
|
||||
|
||||
Private headers do not define any parts of public interface,
|
||||
are not installed in user's filesystem.
|
||||
Private headers only define common features used internally.
|
||||
271
src/soci/include/private/firebird/common.h
Normal file
271
src/soci/include/private/firebird/common.h
Normal file
@@ -0,0 +1,271 @@
|
||||
//
|
||||
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, Rafal Bobrowski
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_FIREBIRD_COMMON_H_INCLUDED
|
||||
#define SOCI_FIREBIRD_COMMON_H_INCLUDED
|
||||
|
||||
#include "soci/firebird/soci-firebird.h"
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
namespace firebird
|
||||
{
|
||||
|
||||
char * allocBuffer(XSQLVAR* var);
|
||||
|
||||
void tmEncode(short type, std::tm * src, void * dst);
|
||||
|
||||
void tmDecode(short type, void * src, std::tm * dst);
|
||||
|
||||
void setTextParam(char const * s, std::size_t size, char * buf_,
|
||||
XSQLVAR * var);
|
||||
|
||||
std::string getTextParam(XSQLVAR const *var);
|
||||
|
||||
template <typename IntType>
|
||||
const char *str2dec(const char * s, IntType &out, short &scale)
|
||||
{
|
||||
int sign = 1;
|
||||
if ('+' == *s)
|
||||
++s;
|
||||
else if ('-' == *s)
|
||||
{
|
||||
sign = -1;
|
||||
++s;
|
||||
}
|
||||
scale = 0;
|
||||
bool period = false;
|
||||
IntType res = 0;
|
||||
for (out = 0; *s; ++s, out = res)
|
||||
{
|
||||
if (*s == '.')
|
||||
{
|
||||
if (period)
|
||||
return s;
|
||||
period = true;
|
||||
continue;
|
||||
}
|
||||
int d = *s - '0';
|
||||
if (d < 0 || d > 9)
|
||||
return s;
|
||||
res = res * 10 + static_cast<IntType>(d * sign);
|
||||
if (1 == sign)
|
||||
{
|
||||
if (res < out)
|
||||
return s;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (res > out)
|
||||
return s;
|
||||
}
|
||||
if (period)
|
||||
++scale;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline
|
||||
T round_for_isc(T value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
inline
|
||||
double round_for_isc(double value)
|
||||
{
|
||||
// Unfortunately all the rounding functions are C99 and so are not supported
|
||||
// by MSVC, so do it manually.
|
||||
return value < 0 ? value - 0.5 : value + 0.5;
|
||||
}
|
||||
|
||||
//helper template to generate proper code based on compile time type check
|
||||
template<bool cond> struct cond_to_isc {};
|
||||
template<> struct cond_to_isc<false>
|
||||
{
|
||||
static void checkInteger(short scale, short type)
|
||||
{
|
||||
if( scale >= 0 && (type == SQL_SHORT || type == SQL_LONG || type == SQL_INT64) )
|
||||
throw soci_error("Can't convert non-integral value to integral column type");
|
||||
}
|
||||
};
|
||||
template<> struct cond_to_isc<true>
|
||||
{
|
||||
static void checkInteger(short scale,short type) { SOCI_UNUSED(scale) SOCI_UNUSED(type) }
|
||||
};
|
||||
|
||||
template<typename T1>
|
||||
void to_isc(void * val, XSQLVAR * var, short x_scale = 0)
|
||||
{
|
||||
T1 value = *reinterpret_cast<T1*>(val);
|
||||
short scale = var->sqlscale + x_scale;
|
||||
short type = var->sqltype & ~1;
|
||||
long long divisor = 1, multiplier = 1;
|
||||
|
||||
cond_to_isc<std::numeric_limits<T1>::is_integer>::checkInteger(scale,type);
|
||||
|
||||
for (int i = 0; i > scale; --i)
|
||||
multiplier *= 10;
|
||||
for (int i = 0; i < scale; ++i)
|
||||
divisor *= 10;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case SQL_SHORT:
|
||||
{
|
||||
short tmp = static_cast<short>(round_for_isc(value*multiplier)/divisor);
|
||||
std::memcpy(var->sqldata, &tmp, sizeof(short));
|
||||
}
|
||||
break;
|
||||
case SQL_LONG:
|
||||
{
|
||||
int tmp = static_cast<int>(round_for_isc(value*multiplier)/divisor);
|
||||
std::memcpy(var->sqldata, &tmp, sizeof(int));
|
||||
}
|
||||
break;
|
||||
case SQL_INT64:
|
||||
{
|
||||
long long tmp = static_cast<long long>(round_for_isc(value*multiplier)/divisor);
|
||||
std::memcpy(var->sqldata, &tmp, sizeof(long long));
|
||||
}
|
||||
break;
|
||||
case SQL_FLOAT:
|
||||
{
|
||||
float sql_value = static_cast<float>(value);
|
||||
std::memcpy(var->sqldata, &sql_value, sizeof(float));
|
||||
}
|
||||
break;
|
||||
case SQL_DOUBLE:
|
||||
{
|
||||
double sql_value = static_cast<double>(value);
|
||||
std::memcpy(var->sqldata, &sql_value, sizeof(double));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw soci_error("Incorrect data type for numeric conversion");
|
||||
}
|
||||
}
|
||||
|
||||
template<typename IntType, typename UIntType>
|
||||
void parse_decimal(void * val, XSQLVAR * var, const char * s)
|
||||
{
|
||||
short scale;
|
||||
UIntType t1;
|
||||
IntType t2;
|
||||
if (!*str2dec(s, t1, scale))
|
||||
std::memcpy(val, &t1, sizeof(t1));
|
||||
else if (!*str2dec(s, t2, scale))
|
||||
std::memcpy(val, &t2, sizeof(t2));
|
||||
else
|
||||
throw soci_error("Could not parse decimal value.");
|
||||
to_isc<IntType>(val, var, scale);
|
||||
}
|
||||
|
||||
template<typename IntType>
|
||||
std::string format_decimal(const void *sqldata, int sqlscale)
|
||||
{
|
||||
IntType x = *reinterpret_cast<const IntType *>(sqldata);
|
||||
std::stringstream out;
|
||||
out << x;
|
||||
std::string r = out.str();
|
||||
if (sqlscale < 0)
|
||||
{
|
||||
if (static_cast<int>(r.size()) - (x < 0) <= -sqlscale)
|
||||
{
|
||||
r = std::string(size_t(x < 0), '-') +
|
||||
std::string(-sqlscale - (r.size() - (x < 0)) + 1, '0') +
|
||||
r.substr(size_t(x < 0), std::string::npos);
|
||||
}
|
||||
return r.substr(0, r.size() + sqlscale) + '.' +
|
||||
r.substr(r.size() + sqlscale, std::string::npos);
|
||||
}
|
||||
return r + std::string(sqlscale, '0');
|
||||
}
|
||||
|
||||
|
||||
template<bool cond> struct cond_from_isc {};
|
||||
template<> struct cond_from_isc<true> {
|
||||
static void checkInteger(short scale)
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg << "Can't convert value with scale " << -scale
|
||||
<< " to integral type";
|
||||
throw soci_error(msg.str());
|
||||
}
|
||||
};
|
||||
template<> struct cond_from_isc<false>
|
||||
{
|
||||
static void checkInteger(short scale) { SOCI_UNUSED(scale) }
|
||||
};
|
||||
|
||||
template<typename T1>
|
||||
T1 from_isc(XSQLVAR * var)
|
||||
{
|
||||
short scale = var->sqlscale;
|
||||
T1 tens = 1;
|
||||
|
||||
if (scale < 0)
|
||||
{
|
||||
cond_from_isc<std::numeric_limits<T1>::is_integer>::checkInteger(scale);
|
||||
for (int i = 0; i > scale; --i)
|
||||
{
|
||||
tens *= 10;
|
||||
}
|
||||
}
|
||||
|
||||
switch (var->sqltype & ~1)
|
||||
{
|
||||
case SQL_SHORT:
|
||||
return static_cast<T1>(*reinterpret_cast<short*>(var->sqldata)/tens);
|
||||
case SQL_LONG:
|
||||
return static_cast<T1>(*reinterpret_cast<int*>(var->sqldata)/tens);
|
||||
case SQL_INT64:
|
||||
return static_cast<T1>(*reinterpret_cast<long long*>(var->sqldata)/tens);
|
||||
case SQL_FLOAT:
|
||||
return static_cast<T1>(*reinterpret_cast<float*>(var->sqldata));
|
||||
case SQL_DOUBLE:
|
||||
return static_cast<T1>(*reinterpret_cast<double*>(var->sqldata));
|
||||
default:
|
||||
throw soci_error("Incorrect data type for numeric conversion");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::size_t getVectorSize(void *p)
|
||||
{
|
||||
std::vector<T> *v = static_cast<std::vector<T> *>(p);
|
||||
return v->size();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void resizeVector(void *p, std::size_t sz)
|
||||
{
|
||||
std::vector<T> *v = static_cast<std::vector<T> *>(p);
|
||||
v->resize(sz);
|
||||
}
|
||||
|
||||
} // namespace firebird
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_FIREBIRD_COMMON_H_INCLUDED
|
||||
35
src/soci/include/private/firebird/error-firebird.h
Normal file
35
src/soci/include/private/firebird/error-firebird.h
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, Rafal Bobrowski
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_FIREBIRD_ERROR_H_INCLUDED
|
||||
#define SOCI_FIREBIRD_ERROR_H_INCLUDED
|
||||
|
||||
#include "soci/firebird/soci-firebird.h"
|
||||
#include <string>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
namespace firebird
|
||||
{
|
||||
|
||||
void SOCI_FIREBIRD_DECL get_iscerror_details(ISC_STATUS * status_vector, std::string &msg);
|
||||
|
||||
bool SOCI_FIREBIRD_DECL check_iscerror(ISC_STATUS const * status_vector, long errNum);
|
||||
|
||||
void SOCI_FIREBIRD_DECL throw_iscerror(ISC_STATUS * status_vector);
|
||||
|
||||
} // namespace firebird
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_FIREBIRD_ERROR_H_INCLUDED
|
||||
39
src/soci/include/private/soci-compiler.h
Normal file
39
src/soci/include/private/soci-compiler.h
Normal file
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// Copyright (C) 2015 Vadim Zeitlin
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_PRIVATE_SOCI_COMPILER_H_INCLUDED
|
||||
#define SOCI_PRIVATE_SOCI_COMPILER_H_INCLUDED
|
||||
|
||||
#include "soci-cpp.h"
|
||||
|
||||
// CHECK_GCC(major,minor) evaluates to 1 when using g++ of at least this
|
||||
// version or 0 when using g++ of lesser version or not using g++ at all.
|
||||
#if defined(__GNUC__) && defined(__GNUC_MINOR__)
|
||||
# define CHECK_GCC(major, minor) \
|
||||
((__GNUC__ > (major)) \
|
||||
|| (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
|
||||
#else
|
||||
# define CHECK_GCC(major, minor) 0
|
||||
#endif
|
||||
|
||||
// GCC_WARNING_{SUPPRESS,RESTORE} macros can be used to bracket the code
|
||||
// producing a specific warning to disable it.
|
||||
//
|
||||
// They only work with g++ 4.6+ or clang, warnings are not disabled for earlier
|
||||
// g++ versions.
|
||||
#if defined(__clang__) || CHECK_GCC(4, 6)
|
||||
# define GCC_WARNING_SUPPRESS(x) \
|
||||
_Pragma (SOCI_STRINGIZE(GCC diagnostic push)) \
|
||||
_Pragma (SOCI_STRINGIZE(GCC diagnostic ignored SOCI_STRINGIZE(SOCI_CONCAT(-W,x))))
|
||||
# define GCC_WARNING_RESTORE(x) \
|
||||
_Pragma (SOCI_STRINGIZE(GCC diagnostic pop))
|
||||
#else /* gcc < 4.6 or not gcc and not clang at all */
|
||||
# define GCC_WARNING_SUPPRESS(x)
|
||||
# define GCC_WARNING_RESTORE(x)
|
||||
#endif
|
||||
|
||||
#endif // SOCI_PRIVATE_SOCI_COMPILER_H_INCLUDED
|
||||
30
src/soci/include/private/soci-cpp.h
Normal file
30
src/soci/include/private/soci-cpp.h
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// Copyright (C) 2015 Vadim Zeitlin
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_PRIVATE_SOCI_CPP_H_INCLUDED
|
||||
#define SOCI_PRIVATE_SOCI_CPP_H_INCLUDED
|
||||
|
||||
// Some very common preprocessor helpers.
|
||||
|
||||
// SOCI_CONCAT() pastes together two tokens after expanding them.
|
||||
#define SOCI_CONCAT_IMPL(x, y) x ## y
|
||||
#define SOCI_CONCAT(x, y) SOCI_CONCAT_IMPL(x, y)
|
||||
|
||||
// SOCI_STRINGIZE() makes a string of its argument after expanding it.
|
||||
#define SOCI_STRINGIZE_IMPL(x) #x
|
||||
#define SOCI_STRINGIZE(x) SOCI_STRINGIZE_IMPL(x)
|
||||
|
||||
// SOCI_MAKE_UNIQUE_NAME() creates a uniquely named identifier with the given
|
||||
// prefix.
|
||||
//
|
||||
// It uses __COUNTER__ macro to avoid problems with broken __LINE__ in MSVC
|
||||
// when using "Edit and Continue" (/ZI) option as there are no compilers known
|
||||
// to work with SOCI and not support it. If one such is ever discovered, we
|
||||
// should use __LINE__ for it instead.
|
||||
#define SOCI_MAKE_UNIQUE_NAME(name) SOCI_CONCAT(name, __COUNTER__)
|
||||
|
||||
#endif // SOCI_PRIVATE_SOCI_CPP_H_INCLUDED
|
||||
80
src/soci/include/private/soci-cstrtod.h
Normal file
80
src/soci/include/private/soci-cstrtod.h
Normal file
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// Copyright (C) 2014 Vadim Zeitlin.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_PRIVATE_SOCI_CSTRTOD_H_INCLUDED
|
||||
#define SOCI_PRIVATE_SOCI_CSTRTOD_H_INCLUDED
|
||||
|
||||
#include "soci/error.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
// Locale-independent, i.e. always using "C" locale, function for converting
|
||||
// strings to numbers.
|
||||
//
|
||||
// The string must contain a floating point number in "C" locale, i.e. using
|
||||
// point as decimal separator, and nothing but it. If it does, the converted
|
||||
// number is returned, otherwise an exception is thrown.
|
||||
inline
|
||||
double cstring_to_double(char const* s)
|
||||
{
|
||||
// Unfortunately there is no clean way to parse a number in C locale
|
||||
// without this hack: normally, using std::istringstream with classic
|
||||
// locale should work, but some standard library implementations are buggy
|
||||
// and handle non-default locale in thread-unsafe way, by changing the
|
||||
// global C locale which is unacceptable as it introduces subtle bugs in
|
||||
// multi-thread programs. So we rely on just the standard C functions and
|
||||
// try to make them work by tweaking the input into the form appropriate
|
||||
// for the current locale.
|
||||
|
||||
// First try with the original input.
|
||||
char* end;
|
||||
double d = strtod(s, &end);
|
||||
|
||||
bool parsedOK;
|
||||
if (*end == '.')
|
||||
{
|
||||
// Parsing may have stopped because the current locale uses something
|
||||
// different from the point as decimal separator, retry with a comma.
|
||||
//
|
||||
// In principle, values other than point or comma are possible but they
|
||||
// don't seem to be used in practice, so for now keep things simple.
|
||||
size_t const bufSize = strlen(s) + 1;
|
||||
char* const buf = new char[bufSize];
|
||||
strcpy(buf, s);
|
||||
buf[end - s] = ',';
|
||||
d = strtod(buf, &end);
|
||||
parsedOK = end != buf && *end == '\0';
|
||||
delete [] buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Notice that we must detect false positives as well: parsing a string
|
||||
// using decimal comma should fail when using this function.
|
||||
parsedOK = end != s && *end == '\0' && !strchr(s, ',');
|
||||
}
|
||||
|
||||
if (!parsedOK)
|
||||
{
|
||||
throw soci_error(std::string("Cannot convert data: string \"") + s + "\" "
|
||||
"is not a number.");
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_PRIVATE_SOCI_CSTRTOD_H_INCLUDED
|
||||
58
src/soci/include/private/soci-dtocstr.h
Normal file
58
src/soci/include/private/soci-dtocstr.h
Normal file
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// Copyright (C) 2014 Vadim Zeitlin.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_PRIVATE_SOCI_DTOCSTR_H_INCLUDED
|
||||
#define SOCI_PRIVATE_SOCI_DTOCSTR_H_INCLUDED
|
||||
|
||||
#include "soci/soci-platform.h"
|
||||
#include "soci/error.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
// Locale-independent, i.e. always using "C" locale, function for converting
|
||||
// floating point number to string.
|
||||
//
|
||||
// The resulting string will contain the floating point number in "C" locale,
|
||||
// i.e. will always use point as decimal separator independently of the current
|
||||
// locale.
|
||||
inline
|
||||
std::string double_to_cstring(double d)
|
||||
{
|
||||
// See comments in cstring_to_double() in soci-cstrtod.h, we're dealing
|
||||
// with the same issues here.
|
||||
|
||||
static size_t const bufSize = 32;
|
||||
char buf[bufSize];
|
||||
snprintf(buf, bufSize, "%.20g", d);
|
||||
|
||||
// Replace any commas which can be used as decimal separator with points.
|
||||
for (char* p = buf; *p != '\0'; p++ )
|
||||
{
|
||||
if (*p == ',')
|
||||
{
|
||||
*p = '.';
|
||||
|
||||
// There can be at most one comma in this string anyhow.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_PRIVATE_SOCI_DTOCSTR_H_INCLUDED
|
||||
84
src/soci/include/private/soci-exchange-cast.h
Normal file
84
src/soci/include/private/soci-exchange-cast.h
Normal file
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// Copyright (C) 2015 Vadim Zeitlin
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_EXCHANGE_CAST_H_INCLUDED
|
||||
#define SOCI_EXCHANGE_CAST_H_INCLUDED
|
||||
|
||||
#include "soci/soci-backend.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
// cast the given non-null untyped pointer to its corresponding type
|
||||
template <exchange_type e> struct exchange_type_traits;
|
||||
|
||||
template <>
|
||||
struct exchange_type_traits<x_char>
|
||||
{
|
||||
typedef char value_type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_type_traits<x_stdstring>
|
||||
{
|
||||
typedef std::string value_type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_type_traits<x_short>
|
||||
{
|
||||
typedef short value_type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_type_traits<x_integer>
|
||||
{
|
||||
typedef int value_type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_type_traits<x_long_long>
|
||||
{
|
||||
typedef long long value_type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_type_traits<x_unsigned_long_long>
|
||||
{
|
||||
typedef unsigned long long value_type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_type_traits<x_double>
|
||||
{
|
||||
typedef double value_type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_type_traits<x_stdtm>
|
||||
{
|
||||
typedef std::tm value_type;
|
||||
};
|
||||
|
||||
// exchange_type_traits not defined for x_statement, x_rowid and x_blob here.
|
||||
|
||||
template <exchange_type e>
|
||||
typename exchange_type_traits<e>::value_type& exchange_type_cast(void *data)
|
||||
{
|
||||
return *static_cast<typename exchange_type_traits<e>::value_type*>(data);
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_EXCHANGE_CAST_H_INCLUDED
|
||||
46
src/soci/include/private/soci-mktime.h
Normal file
46
src/soci/include/private/soci-mktime.h
Normal file
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// Copyright (C) 2015 Vadim Zeitlin.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_PRIVATE_SOCI_MKTIME_H_INCLUDED
|
||||
#define SOCI_PRIVATE_SOCI_MKTIME_H_INCLUDED
|
||||
|
||||
// Not <ctime> because we also want to get timegm() if available.
|
||||
#include <time.h>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
// Fill the provided struct tm with the values corresponding to the given date
|
||||
// in UTC.
|
||||
//
|
||||
// Notice that both years and months are normal human 1-based values here and
|
||||
// not 1900 or 0-based as in struct tm itself.
|
||||
inline
|
||||
void
|
||||
mktime_from_ymdhms(tm& t,
|
||||
int year, int month, int day,
|
||||
int hour, int minute, int second)
|
||||
{
|
||||
t.tm_isdst = -1;
|
||||
t.tm_year = year - 1900;
|
||||
t.tm_mon = month - 1;
|
||||
t.tm_mday = day;
|
||||
t.tm_hour = hour;
|
||||
t.tm_min = minute;
|
||||
t.tm_sec = second;
|
||||
|
||||
mktime(&t);
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_PRIVATE_SOCI_MKTIME_H_INCLUDED
|
||||
19
src/soci/include/private/soci-static-assert.h
Normal file
19
src/soci/include/private/soci-static-assert.h
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright (C) 2015 Vadim Zeitlin.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_PRIVATE_STATIC_ASSERT_H_INCLUDED
|
||||
#define SOCI_PRIVATE_STATIC_ASSERT_H_INCLUDED
|
||||
|
||||
#include "soci-cpp.h"
|
||||
|
||||
// This is a simple approximation for C++11 static_assert: generate a
|
||||
// compile-time error if the given expression evaluates to 0 and make the
|
||||
// identifier (not string!) msg appear in the error message.
|
||||
#define SOCI_STATIC_ASSERT(expr) \
|
||||
struct SOCI_MAKE_UNIQUE_NAME(SociAssert) { unsigned msg: expr; }
|
||||
|
||||
#endif // SOCI_PRIVATE_STATIC_ASSERT_H_INCLUDED
|
||||
37
src/soci/include/soci/backend-loader.h
Normal file
37
src/soci/include/soci/backend-loader.h
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// Copyright (C) 2008 Maciej Sobczak with contributions from Artyom Tonkikh
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_BACKEND_LOADER_H_INCLUDED
|
||||
#define SOCI_BACKEND_LOADER_H_INCLUDED
|
||||
|
||||
#include "soci/soci-backend.h"
|
||||
// std
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace dynamic_backends
|
||||
{
|
||||
|
||||
// used internally by session
|
||||
backend_factory const & get(std::string const & name);
|
||||
|
||||
// provided for advanced user-level management
|
||||
SOCI_DECL std::vector<std::string> & search_paths();
|
||||
SOCI_DECL void register_backend(std::string const & name, std::string const & shared_object = std::string());
|
||||
SOCI_DECL void register_backend(std::string const & name, backend_factory const & factory);
|
||||
SOCI_DECL std::vector<std::string> list_all();
|
||||
SOCI_DECL void unload(std::string const & name);
|
||||
SOCI_DECL void unload_all();
|
||||
|
||||
} // namespace dynamic_backends
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_BACKEND_LOADER_H_INCLUDED
|
||||
196
src/soci/include/soci/bind-values.h
Normal file
196
src/soci/include/soci/bind-values.h
Normal file
@@ -0,0 +1,196 @@
|
||||
#ifndef SOCI_BIND_VALUES_H_INCLUDED
|
||||
#define SOCI_BIND_VALUES_H_INCLUDED
|
||||
|
||||
#include "exchange-traits.h"
|
||||
#include "into-type.h"
|
||||
#include "into.h"
|
||||
#include "soci-backend.h"
|
||||
#include "use-type.h"
|
||||
#include "use.h"
|
||||
|
||||
|
||||
#ifdef HAVE_BOOST
|
||||
# include <boost/fusion/algorithm/iteration/for_each.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
#endif // HAVE_BOOST
|
||||
#include <vector>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
|
||||
class use_type_vector: public std::vector<use_type_base *>
|
||||
{
|
||||
public:
|
||||
~use_type_vector()
|
||||
{
|
||||
for(iterator iter = begin(), _end = end();
|
||||
iter != _end; iter++)
|
||||
delete *iter;
|
||||
}
|
||||
|
||||
void exchange(use_type_ptr const& u) { push_back(u.get()); u.release(); }
|
||||
|
||||
template <typename T, typename Indicator>
|
||||
void exchange(use_container<T, Indicator> const &uc)
|
||||
{
|
||||
#ifdef HAVE_BOOST
|
||||
exchange_(uc, (typename boost::fusion::traits::is_sequence<T>::type *)NULL);
|
||||
#else
|
||||
exchange_(uc, NULL);
|
||||
#endif // HAVE_BOOST
|
||||
}
|
||||
|
||||
private:
|
||||
#ifdef HAVE_BOOST
|
||||
template <typename T, typename Indicator>
|
||||
struct use_sequence
|
||||
{
|
||||
use_sequence(use_type_vector &_p, Indicator &_ind)
|
||||
:p(_p), ind(_ind) {}
|
||||
|
||||
template <typename T2>
|
||||
void operator()(T2 &t2) const
|
||||
{
|
||||
p.exchange(use(t2, ind));
|
||||
}
|
||||
|
||||
use_type_vector &p;
|
||||
Indicator &ind;
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(use_sequence)
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct use_sequence<T, details::no_indicator>
|
||||
{
|
||||
use_sequence(use_type_vector &_p)
|
||||
:p(_p) {}
|
||||
|
||||
template <typename T2>
|
||||
void operator()(T2 &t2) const
|
||||
{
|
||||
p.exchange(use(t2));
|
||||
}
|
||||
|
||||
use_type_vector &p;
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(use_sequence)
|
||||
};
|
||||
|
||||
template <typename T, typename Indicator>
|
||||
void exchange_(use_container<T, Indicator> const &uc, boost::mpl::true_ * /* fusion sequence */)
|
||||
{
|
||||
boost::fusion::for_each(uc.t, use_sequence<T, Indicator>(*this, uc.ind));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void exchange_(use_container<T, details::no_indicator> const &uc, boost::mpl::true_ * /* fusion sequence */)
|
||||
{
|
||||
boost::fusion::for_each(uc.t, use_sequence<T, details::no_indicator>(*this));
|
||||
}
|
||||
|
||||
#endif // HAVE_BOOST
|
||||
|
||||
template <typename T, typename Indicator>
|
||||
void exchange_(use_container<T, Indicator> const &uc, ...)
|
||||
{ exchange(do_use(uc.t, uc.ind, uc.name, typename details::exchange_traits<T>::type_family())); }
|
||||
|
||||
template <typename T>
|
||||
void exchange_(use_container<T, details::no_indicator> const &uc, ...)
|
||||
{ exchange(do_use(uc.t, uc.name, typename details::exchange_traits<T>::type_family())); }
|
||||
|
||||
template <typename T, typename Indicator>
|
||||
void exchange_(use_container<const T, Indicator> const &uc, ...)
|
||||
{ exchange(do_use(uc.t, uc.ind, uc.name, typename details::exchange_traits<T>::type_family())); }
|
||||
|
||||
template <typename T>
|
||||
void exchange_(use_container<const T, details::no_indicator> const &uc, ...)
|
||||
{ exchange(do_use(uc.t, uc.name, typename details::exchange_traits<T>::type_family())); }
|
||||
};
|
||||
|
||||
class into_type_vector: public std::vector<details::into_type_base *>
|
||||
{
|
||||
public:
|
||||
~into_type_vector()
|
||||
{
|
||||
for(iterator iter = begin(), _end = end();
|
||||
iter != _end; iter++)
|
||||
delete *iter;
|
||||
}
|
||||
|
||||
void exchange(into_type_ptr const& i) { push_back(i.get()); i.release(); }
|
||||
|
||||
template <typename T, typename Indicator>
|
||||
void exchange(into_container<T, Indicator> const &ic)
|
||||
{
|
||||
#ifdef HAVE_BOOST
|
||||
exchange_(ic, (typename boost::fusion::traits::is_sequence<T>::type *)NULL);
|
||||
#else
|
||||
exchange_(ic, NULL);
|
||||
#endif // HAVE_BOOST
|
||||
}
|
||||
|
||||
private:
|
||||
#ifdef HAVE_BOOST
|
||||
template <typename T, typename Indicator>
|
||||
struct into_sequence
|
||||
{
|
||||
into_sequence(into_type_vector &_p, Indicator &_ind)
|
||||
:p(_p), ind(_ind) {}
|
||||
|
||||
template <typename T2>
|
||||
void operator()(T2 &t2) const
|
||||
{
|
||||
p.exchange(into(t2, ind));
|
||||
}
|
||||
|
||||
into_type_vector &p;
|
||||
Indicator &ind;
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(into_sequence)
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct into_sequence<T, details::no_indicator>
|
||||
{
|
||||
into_sequence(into_type_vector &_p)
|
||||
:p(_p) {}
|
||||
|
||||
template <typename T2>
|
||||
void operator()(T2 &t2) const
|
||||
{
|
||||
p.exchange(into(t2));
|
||||
}
|
||||
|
||||
into_type_vector &p;
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(into_sequence)
|
||||
};
|
||||
|
||||
template <typename T, typename Indicator>
|
||||
void exchange_(into_container<T, Indicator> const &ic, boost::mpl::true_ * /* fusion sequence */)
|
||||
{
|
||||
boost::fusion::for_each(ic.t, into_sequence<T, Indicator>(*this, ic.ind));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void exchange_(into_container<T, details::no_indicator> const &ic, boost::mpl::true_ * /* fusion sequence */)
|
||||
{
|
||||
boost::fusion::for_each(ic.t, into_sequence<T, details::no_indicator>(*this));
|
||||
}
|
||||
#endif // HAVE_BOOST
|
||||
|
||||
template <typename T, typename Indicator>
|
||||
void exchange_(into_container<T, Indicator> const &ic, ...)
|
||||
{ exchange(do_into(ic.t, ic.ind, typename details::exchange_traits<T>::type_family())); }
|
||||
|
||||
template <typename T>
|
||||
void exchange_(into_container<T, details::no_indicator> const &ic, ...)
|
||||
{ exchange(do_into(ic.t, typename details::exchange_traits<T>::type_family())); }
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
}// namespace soci
|
||||
#endif // SOCI_BIND_VALUES_H_INCLUDED
|
||||
59
src/soci/include/soci/blob-exchange.h
Normal file
59
src/soci/include/soci/blob-exchange.h
Normal file
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_BLOB_EXCHANGE_H_INCLUDED
|
||||
#define SOCI_BLOB_EXCHANGE_H_INCLUDED
|
||||
|
||||
#include "soci/blob.h"
|
||||
#include "soci/into-type.h"
|
||||
#include "soci/use-type.h"
|
||||
// std
|
||||
#include <string>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
template <>
|
||||
class into_type<blob> : public standard_into_type
|
||||
{
|
||||
public:
|
||||
into_type(blob & b) : standard_into_type(&b, x_blob) {}
|
||||
into_type(blob & b, indicator & ind)
|
||||
: standard_into_type(&b, x_blob, ind) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
class use_type<blob> : public standard_use_type
|
||||
{
|
||||
public:
|
||||
use_type(blob & b, std::string const & name = std::string())
|
||||
: standard_use_type(&b, x_blob, false, name) {}
|
||||
use_type(blob const & b, std::string const & name = std::string())
|
||||
: standard_use_type(const_cast<blob *>(&b), x_blob, true, name) {}
|
||||
use_type(blob & b, indicator & ind,
|
||||
std::string const & name = std::string())
|
||||
: standard_use_type(&b, x_blob, ind, false, name) {}
|
||||
use_type(blob const & b, indicator & ind,
|
||||
std::string const & name = std::string())
|
||||
: standard_use_type(const_cast<blob *>(&b), x_blob, ind, true, name) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_traits<soci::blob>
|
||||
{
|
||||
typedef basic_type_tag type_family;
|
||||
enum { x_type = x_blob };
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_BLOB_EXCHANGE_H_INCLUDED
|
||||
47
src/soci/include/soci/blob.h
Normal file
47
src/soci/include/soci/blob.h
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_BLOB_H_INCLUDED
|
||||
#define SOCI_BLOB_H_INCLUDED
|
||||
|
||||
#include "soci/soci-platform.h"
|
||||
// std
|
||||
#include <cstddef>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
// basic blob operations
|
||||
|
||||
class session;
|
||||
|
||||
namespace details
|
||||
{
|
||||
class blob_backend;
|
||||
} // namespace details
|
||||
|
||||
class SOCI_DECL blob
|
||||
{
|
||||
public:
|
||||
explicit blob(session & s);
|
||||
~blob();
|
||||
|
||||
std::size_t get_len();
|
||||
std::size_t read(std::size_t offset, char * buf, std::size_t toRead);
|
||||
std::size_t write(std::size_t offset, char const * buf,
|
||||
std::size_t toWrite);
|
||||
std::size_t append(char const * buf, std::size_t toWrite);
|
||||
void trim(std::size_t newLen);
|
||||
|
||||
details::blob_backend * get_backend() { return backEnd_; }
|
||||
|
||||
private:
|
||||
details::blob_backend * backEnd_;
|
||||
};
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif
|
||||
28
src/soci/include/soci/boost-fusion.h
Normal file
28
src/soci/include/soci/boost-fusion.h
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_BOOST_FUSION_H_INCLUDED
|
||||
#define SOCI_BOOST_FUSION_H_INCLUDED
|
||||
|
||||
#ifndef SOCI_MAX_FUSION_SEQUENCE_LENGTH
|
||||
#define SOCI_MAX_FUSION_SEQUENCE_LENGTH 10
|
||||
#endif
|
||||
|
||||
#include "values.h"
|
||||
#include "type-conversion-traits.h"
|
||||
// boost
|
||||
#include <boost/fusion/container/vector.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/at.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/size.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#include <boost/fusion/support/is_sequence.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
|
||||
#endif // SOCI_BOOST_FUSION_H_INCLUDED
|
||||
47
src/soci/include/soci/boost-gregorian-date.h
Normal file
47
src/soci/include/soci/boost-gregorian-date.h
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// Copyright (C) 2008 Maciej Sobczak
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_BOOST_GREGORIAN_DATE_H_INCLUDED
|
||||
#define SOCI_BOOST_GREGORIAN_DATE_H_INCLUDED
|
||||
|
||||
#include "soci/type-conversion-traits.h"
|
||||
// boost
|
||||
#include <boost/date_time/gregorian/gregorian_types.hpp>
|
||||
#include <boost/date_time/gregorian/conversion.hpp>
|
||||
// std
|
||||
#include <ctime>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
template<>
|
||||
struct type_conversion<boost::gregorian::date>
|
||||
{
|
||||
typedef std::tm base_type;
|
||||
|
||||
static void from_base(
|
||||
base_type const & in, indicator ind, boost::gregorian::date & out)
|
||||
{
|
||||
if (ind == i_null)
|
||||
{
|
||||
throw soci_error("Null value not allowed for this type");
|
||||
}
|
||||
|
||||
out = boost::gregorian::date_from_tm(in);
|
||||
}
|
||||
|
||||
static void to_base(
|
||||
boost::gregorian::date const & in, base_type & out, indicator & ind)
|
||||
{
|
||||
out = boost::gregorian::to_tm(in);
|
||||
ind = i_ok;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_BOOST_GREGORIAN_DATE_H_INCLUDED
|
||||
65
src/soci/include/soci/boost-optional.h
Normal file
65
src/soci/include/soci/boost-optional.h
Normal file
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_BOOST_OPTIONAL_H_INCLUDED
|
||||
#define SOCI_BOOST_OPTIONAL_H_INCLUDED
|
||||
|
||||
#include "soci/type-conversion-traits.h"
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
// tmp is uninitialized
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ > 6)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
|
||||
// simple fall-back for boost::optional
|
||||
template <typename T>
|
||||
struct type_conversion<boost::optional<T> >
|
||||
{
|
||||
typedef typename type_conversion<T>::base_type base_type;
|
||||
|
||||
static void from_base(base_type const & in, indicator ind,
|
||||
boost::optional<T> & out)
|
||||
{
|
||||
if (ind == i_null)
|
||||
{
|
||||
out.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
T tmp;
|
||||
type_conversion<T>::from_base(in, ind, tmp);
|
||||
out = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
static void to_base(boost::optional<T> const & in,
|
||||
base_type & out, indicator & ind)
|
||||
{
|
||||
if (in.is_initialized())
|
||||
{
|
||||
type_conversion<T>::to_base(in.get(), out, ind);
|
||||
}
|
||||
else
|
||||
{
|
||||
ind = i_null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ > 6)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // SOCI_BOOST_OPTIONAL_H_INCLUDED
|
||||
18
src/soci/include/soci/boost-tuple.h
Normal file
18
src/soci/include/soci/boost-tuple.h
Normal file
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_BOOST_TUPLE_H_INCLUDED
|
||||
#define SOCI_BOOST_TUPLE_H_INCLUDED
|
||||
|
||||
#include "values.h"
|
||||
#include "type-conversion-traits.h"
|
||||
|
||||
// boost
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/fusion/adapted/boost_tuple.hpp>
|
||||
|
||||
#endif // SOCI_BOOST_TUPLE_H_INCLUDED
|
||||
68
src/soci/include/soci/connection-parameters.h
Normal file
68
src/soci/include/soci/connection-parameters.h
Normal file
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// Copyright (C) 2013 Vadim Zeitlin
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_CONNECTION_PARAMETERS_H_INCLUDED
|
||||
#define SOCI_CONNECTION_PARAMETERS_H_INCLUDED
|
||||
|
||||
#include "soci/soci-platform.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
class backend_factory;
|
||||
|
||||
// Simple container for the information used when opening a session.
|
||||
class SOCI_DECL connection_parameters
|
||||
{
|
||||
public:
|
||||
connection_parameters();
|
||||
connection_parameters(backend_factory const & factory, std::string const & connectString);
|
||||
connection_parameters(std::string const & backendName, std::string const & connectString);
|
||||
explicit connection_parameters(std::string const & fullConnectString);
|
||||
|
||||
// Default copy ctor, assignment operator and dtor are all OK for us.
|
||||
|
||||
|
||||
// Retrieve the backend and the connection strings specified in the ctor.
|
||||
backend_factory const * get_factory() const { return factory_; }
|
||||
std::string const & get_connect_string() const { return connectString_; }
|
||||
|
||||
// Set the value of the given option, overwriting any previous value.
|
||||
void set_option(const char * name, std::string const & value)
|
||||
{
|
||||
options_[name] = value;
|
||||
}
|
||||
|
||||
// Return true if the option with the given name was found and fill the
|
||||
// provided parameter with its value.
|
||||
bool get_option(const char * name, std::string & value) const
|
||||
{
|
||||
Options::const_iterator const it = options_.find(name);
|
||||
if (it == options_.end())
|
||||
return false;
|
||||
|
||||
value = it->second;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
// The backend and connection string specified in our ctor.
|
||||
backend_factory const * factory_;
|
||||
std::string connectString_;
|
||||
|
||||
// We store all the values as strings for simplicity.
|
||||
typedef std::map<std::string, std::string> Options;
|
||||
Options options_;
|
||||
};
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_CONNECTION_PARAMETERS_H_INCLUDED
|
||||
39
src/soci/include/soci/connection-pool.h
Normal file
39
src/soci/include/soci/connection-pool.h
Normal file
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// Copyright (C) 2008 Maciej Sobczak
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_CONNECTION_POOL_H_INCLUDED
|
||||
#define SOCI_CONNECTION_POOL_H_INCLUDED
|
||||
|
||||
#include "soci/soci-platform.h"
|
||||
// std
|
||||
#include <cstddef>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
class session;
|
||||
|
||||
class SOCI_DECL connection_pool
|
||||
{
|
||||
public:
|
||||
explicit connection_pool(std::size_t size);
|
||||
~connection_pool();
|
||||
|
||||
session & at(std::size_t pos);
|
||||
|
||||
std::size_t lease();
|
||||
bool try_lease(std::size_t & pos, int timeout);
|
||||
void give_back(std::size_t pos);
|
||||
|
||||
private:
|
||||
struct connection_pool_impl;
|
||||
connection_pool_impl * pimpl_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SOCI_CONNECTION_POOL_H_INCLUDED
|
||||
294
src/soci/include/soci/db2/soci-db2.h
Normal file
294
src/soci/include/soci/db2/soci-db2.h
Normal file
@@ -0,0 +1,294 @@
|
||||
//
|
||||
// Copyright (C) 2011-2013 Denis Chapligin
|
||||
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_DB2_H_INCLUDED
|
||||
#define SOCI_DB2_H_INCLUDED
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef SOCI_DLL
|
||||
# ifdef SOCI_DB2_SOURCE
|
||||
# define SOCI_DB2_DECL __declspec(dllexport)
|
||||
# else
|
||||
# define SOCI_DB2_DECL __declspec(dllimport)
|
||||
# endif // SOCI_DB2_SOURCE
|
||||
# endif // SOCI_DLL
|
||||
#endif // _WIN32
|
||||
//
|
||||
// If SOCI_DB2_DECL isn't defined yet define it now
|
||||
#ifndef SOCI_DB2_DECL
|
||||
# define SOCI_DB2_DECL
|
||||
#endif
|
||||
|
||||
#include <soci/soci-backend.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#include <sqlcli1.h>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
namespace details { namespace db2
|
||||
{
|
||||
enum binding_method
|
||||
{
|
||||
BOUND_BY_NONE,
|
||||
BOUND_BY_NAME,
|
||||
BOUND_BY_POSITION
|
||||
};
|
||||
|
||||
inline SQLPOINTER int_as_ptr(int n)
|
||||
{
|
||||
union
|
||||
{
|
||||
SQLPOINTER p;
|
||||
int n;
|
||||
} u;
|
||||
u.n = n;
|
||||
return u.p;
|
||||
}
|
||||
}}
|
||||
|
||||
static const std::size_t maxBuffer = 1024 * 1024 * 1024; //CLI limit is about 3 GB, but 1GB should be enough
|
||||
|
||||
class db2_soci_error : public soci_error {
|
||||
public:
|
||||
db2_soci_error(std::string const & msg, SQLRETURN rc) : soci_error(msg),errorCode(rc) {};
|
||||
~db2_soci_error() throw() { };
|
||||
|
||||
//We have to extract error information before exception throwing, cause CLI handles could be broken at the construction time
|
||||
static const std::string sqlState(std::string const & msg,const SQLSMALLINT htype,const SQLHANDLE hndl);
|
||||
|
||||
SQLRETURN errorCode;
|
||||
};
|
||||
|
||||
struct db2_statement_backend;
|
||||
|
||||
struct SOCI_DB2_DECL db2_standard_into_type_backend : details::standard_into_type_backend
|
||||
{
|
||||
db2_standard_into_type_backend(db2_statement_backend &st)
|
||||
: statement_(st),buf(NULL)
|
||||
{}
|
||||
|
||||
void define_by_pos(int& position, void* data, details::exchange_type type);
|
||||
|
||||
void pre_fetch();
|
||||
void post_fetch(bool gotData, bool calledFromFetch, indicator* ind);
|
||||
|
||||
void clean_up();
|
||||
|
||||
db2_statement_backend& statement_;
|
||||
|
||||
char* buf;
|
||||
void *data;
|
||||
details::exchange_type type;
|
||||
int position;
|
||||
SQLSMALLINT cType;
|
||||
SQLLEN valueLen;
|
||||
};
|
||||
|
||||
struct SOCI_DB2_DECL db2_vector_into_type_backend : details::vector_into_type_backend
|
||||
{
|
||||
db2_vector_into_type_backend(db2_statement_backend &st)
|
||||
: statement_(st),buf(NULL)
|
||||
{}
|
||||
|
||||
void define_by_pos(int& position, void* data, details::exchange_type type);
|
||||
|
||||
void pre_fetch();
|
||||
void post_fetch(bool gotData, indicator* ind);
|
||||
|
||||
void resize(std::size_t sz);
|
||||
std::size_t size();
|
||||
|
||||
void clean_up();
|
||||
|
||||
db2_statement_backend& statement_;
|
||||
|
||||
void prepare_indicators(std::size_t size);
|
||||
|
||||
SQLLEN *indptr;
|
||||
std::vector<SQLLEN> indVec;
|
||||
void *data;
|
||||
char *buf;
|
||||
int position_;
|
||||
details::exchange_type type;
|
||||
SQLSMALLINT cType;
|
||||
std::size_t colSize;
|
||||
};
|
||||
|
||||
struct SOCI_DB2_DECL db2_standard_use_type_backend : details::standard_use_type_backend
|
||||
{
|
||||
db2_standard_use_type_backend(db2_statement_backend &st)
|
||||
: statement_(st),buf(NULL),ind(0)
|
||||
{}
|
||||
|
||||
void bind_by_pos(int& position, void* data, details::exchange_type type, bool readOnly);
|
||||
void bind_by_name(std::string const& name, void* data, details::exchange_type type, bool readOnly);
|
||||
|
||||
void pre_use(indicator const* ind);
|
||||
void post_use(bool gotData, indicator* ind);
|
||||
|
||||
void clean_up();
|
||||
|
||||
db2_statement_backend& statement_;
|
||||
|
||||
void *prepare_for_bind(void *data, SQLLEN &size, SQLSMALLINT &sqlType, SQLSMALLINT &cType);
|
||||
|
||||
void *data;
|
||||
details::exchange_type type;
|
||||
int position;
|
||||
std::string name;
|
||||
char* buf;
|
||||
SQLLEN ind;
|
||||
};
|
||||
|
||||
struct SOCI_DB2_DECL db2_vector_use_type_backend : details::vector_use_type_backend
|
||||
{
|
||||
db2_vector_use_type_backend(db2_statement_backend &st)
|
||||
: statement_(st),buf(NULL) {}
|
||||
|
||||
void bind_by_pos(int& position, void* data, details::exchange_type type);
|
||||
void bind_by_name(std::string const& name, void* data, details::exchange_type type);
|
||||
|
||||
void pre_use(indicator const* ind);
|
||||
|
||||
std::size_t size();
|
||||
|
||||
void clean_up();
|
||||
|
||||
db2_statement_backend& statement_;
|
||||
|
||||
void prepare_indicators(std::size_t size);
|
||||
void prepare_for_bind(void *&data, SQLUINTEGER &size,SQLSMALLINT &sqlType, SQLSMALLINT &cType);
|
||||
void bind_helper(int &position, void *data, details::exchange_type type);
|
||||
|
||||
SQLLEN *indptr;
|
||||
std::vector<SQLLEN> indVec;
|
||||
void *data;
|
||||
char *buf;
|
||||
details::exchange_type type;
|
||||
std::size_t colSize;
|
||||
};
|
||||
|
||||
struct db2_session_backend;
|
||||
struct SOCI_DB2_DECL db2_statement_backend : details::statement_backend
|
||||
{
|
||||
db2_statement_backend(db2_session_backend &session);
|
||||
|
||||
void alloc();
|
||||
void clean_up();
|
||||
void prepare(std::string const& query, details::statement_type eType);
|
||||
|
||||
exec_fetch_result execute(int number);
|
||||
exec_fetch_result fetch(int number);
|
||||
|
||||
long long get_affected_rows();
|
||||
int get_number_of_rows();
|
||||
std::string get_parameter_name(int index) const;
|
||||
|
||||
std::string rewrite_for_procedure_call(std::string const& query);
|
||||
|
||||
int prepare_for_describe();
|
||||
void describe_column(int colNum, data_type& dtype, std::string& columnName);
|
||||
size_t column_size(int col);
|
||||
|
||||
db2_standard_into_type_backend* make_into_type_backend();
|
||||
db2_standard_use_type_backend* make_use_type_backend();
|
||||
db2_vector_into_type_backend* make_vector_into_type_backend();
|
||||
db2_vector_use_type_backend* make_vector_use_type_backend();
|
||||
|
||||
db2_session_backend& session_;
|
||||
|
||||
SQLHANDLE hStmt;
|
||||
std::string query_;
|
||||
std::vector<std::string> names_;
|
||||
bool hasVectorUseElements;
|
||||
SQLUINTEGER numRowsFetched;
|
||||
details::db2::binding_method use_binding_method_;
|
||||
};
|
||||
|
||||
struct db2_rowid_backend : details::rowid_backend
|
||||
{
|
||||
db2_rowid_backend(db2_session_backend &session);
|
||||
|
||||
~db2_rowid_backend();
|
||||
};
|
||||
|
||||
struct db2_blob_backend : details::blob_backend
|
||||
{
|
||||
db2_blob_backend(db2_session_backend& session);
|
||||
|
||||
~db2_blob_backend();
|
||||
|
||||
std::size_t get_len();
|
||||
std::size_t read(std::size_t offset, char* buf, std::size_t toRead);
|
||||
std::size_t write(std::size_t offset, char const* buf, std::size_t toWrite);
|
||||
std::size_t append(char const* buf, std::size_t toWrite);
|
||||
void trim(std::size_t newLen);
|
||||
|
||||
db2_session_backend& session_;
|
||||
};
|
||||
|
||||
struct db2_session_backend : details::session_backend
|
||||
{
|
||||
db2_session_backend(connection_parameters const& parameters);
|
||||
|
||||
~db2_session_backend();
|
||||
|
||||
void begin();
|
||||
void commit();
|
||||
void rollback();
|
||||
|
||||
std::string get_backend_name() const { return "DB2"; }
|
||||
|
||||
void clean_up();
|
||||
|
||||
db2_statement_backend* make_statement_backend();
|
||||
db2_rowid_backend* make_rowid_backend();
|
||||
db2_blob_backend* make_blob_backend();
|
||||
|
||||
void parseConnectString(std::string const &);
|
||||
void parseKeyVal(std::string const &);
|
||||
|
||||
std::string dsn;
|
||||
std::string username;
|
||||
std::string password;
|
||||
bool autocommit;
|
||||
bool in_transaction;
|
||||
|
||||
SQLHANDLE hEnv; /* Environment handle */
|
||||
SQLHANDLE hDbc; /* Connection handle */
|
||||
};
|
||||
|
||||
struct SOCI_DB2_DECL db2_backend_factory : backend_factory
|
||||
{
|
||||
db2_backend_factory() {}
|
||||
db2_session_backend* make_session(
|
||||
connection_parameters const & parameters) const;
|
||||
};
|
||||
|
||||
extern SOCI_DB2_DECL db2_backend_factory const db2;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// for dynamic backend loading
|
||||
SOCI_DB2_DECL backend_factory const* factory_db2();
|
||||
SOCI_DB2_DECL void register_factory_db2();
|
||||
|
||||
} // extern "C"
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_DB2_H_INCLUDED
|
||||
194
src/soci/include/soci/empty/soci-empty.h
Normal file
194
src/soci/include/soci/empty/soci-empty.h
Normal file
@@ -0,0 +1,194 @@
|
||||
//
|
||||
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_EMPTY_H_INCLUDED
|
||||
#define SOCI_EMPTY_H_INCLUDED
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef SOCI_DLL
|
||||
# ifdef SOCI_EMPTY_SOURCE
|
||||
# define SOCI_EMPTY_DECL __declspec(dllexport)
|
||||
# else
|
||||
# define SOCI_EMPTY_DECL __declspec(dllimport)
|
||||
# endif // SOCI_EMPTY_SOURCE
|
||||
# endif // SOCI_DLL
|
||||
#endif // _WIN32
|
||||
//
|
||||
// If SOCI_EMPTY_DECL isn't defined yet define it now
|
||||
#ifndef SOCI_EMPTY_DECL
|
||||
# define SOCI_EMPTY_DECL
|
||||
#endif
|
||||
|
||||
#include <soci/soci-backend.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
struct empty_statement_backend;
|
||||
|
||||
struct SOCI_EMPTY_DECL empty_standard_into_type_backend : details::standard_into_type_backend
|
||||
{
|
||||
empty_standard_into_type_backend(empty_statement_backend &st)
|
||||
: statement_(st)
|
||||
{}
|
||||
|
||||
void define_by_pos(int& position, void* data, details::exchange_type type);
|
||||
|
||||
void pre_fetch();
|
||||
void post_fetch(bool gotData, bool calledFromFetch, indicator* ind);
|
||||
|
||||
void clean_up();
|
||||
|
||||
empty_statement_backend& statement_;
|
||||
};
|
||||
|
||||
struct SOCI_EMPTY_DECL empty_vector_into_type_backend : details::vector_into_type_backend
|
||||
{
|
||||
empty_vector_into_type_backend(empty_statement_backend &st)
|
||||
: statement_(st)
|
||||
{}
|
||||
|
||||
void define_by_pos(int& position, void* data, details::exchange_type type);
|
||||
|
||||
void pre_fetch();
|
||||
void post_fetch(bool gotData, indicator* ind);
|
||||
|
||||
void resize(std::size_t sz);
|
||||
std::size_t size();
|
||||
|
||||
void clean_up();
|
||||
|
||||
empty_statement_backend& statement_;
|
||||
};
|
||||
|
||||
struct SOCI_EMPTY_DECL empty_standard_use_type_backend : details::standard_use_type_backend
|
||||
{
|
||||
empty_standard_use_type_backend(empty_statement_backend &st)
|
||||
: statement_(st)
|
||||
{}
|
||||
|
||||
void bind_by_pos(int& position, void* data, details::exchange_type type, bool readOnly);
|
||||
void bind_by_name(std::string const& name, void* data, details::exchange_type type, bool readOnly);
|
||||
|
||||
void pre_use(indicator const* ind);
|
||||
void post_use(bool gotData, indicator* ind);
|
||||
|
||||
void clean_up();
|
||||
|
||||
empty_statement_backend& statement_;
|
||||
};
|
||||
|
||||
struct SOCI_EMPTY_DECL empty_vector_use_type_backend : details::vector_use_type_backend
|
||||
{
|
||||
empty_vector_use_type_backend(empty_statement_backend &st)
|
||||
: statement_(st) {}
|
||||
|
||||
void bind_by_pos(int& position, void* data, details::exchange_type type);
|
||||
void bind_by_name(std::string const& name, void* data, details::exchange_type type);
|
||||
|
||||
void pre_use(indicator const* ind);
|
||||
|
||||
std::size_t size();
|
||||
|
||||
void clean_up();
|
||||
|
||||
empty_statement_backend& statement_;
|
||||
};
|
||||
|
||||
struct empty_session_backend;
|
||||
struct SOCI_EMPTY_DECL empty_statement_backend : details::statement_backend
|
||||
{
|
||||
empty_statement_backend(empty_session_backend &session);
|
||||
|
||||
void alloc();
|
||||
void clean_up();
|
||||
void prepare(std::string const& query, details::statement_type eType);
|
||||
|
||||
exec_fetch_result execute(int number);
|
||||
exec_fetch_result fetch(int number);
|
||||
|
||||
long long get_affected_rows();
|
||||
int get_number_of_rows();
|
||||
std::string get_parameter_name(int index) const;
|
||||
|
||||
std::string rewrite_for_procedure_call(std::string const& query);
|
||||
|
||||
int prepare_for_describe();
|
||||
void describe_column(int colNum, data_type& dtype, std::string& columnName);
|
||||
|
||||
empty_standard_into_type_backend* make_into_type_backend();
|
||||
empty_standard_use_type_backend* make_use_type_backend();
|
||||
empty_vector_into_type_backend* make_vector_into_type_backend();
|
||||
empty_vector_use_type_backend* make_vector_use_type_backend();
|
||||
|
||||
empty_session_backend& session_;
|
||||
};
|
||||
|
||||
struct empty_rowid_backend : details::rowid_backend
|
||||
{
|
||||
empty_rowid_backend(empty_session_backend &session);
|
||||
|
||||
~empty_rowid_backend();
|
||||
};
|
||||
|
||||
struct empty_blob_backend : details::blob_backend
|
||||
{
|
||||
empty_blob_backend(empty_session_backend& session);
|
||||
|
||||
~empty_blob_backend();
|
||||
|
||||
std::size_t get_len();
|
||||
std::size_t read(std::size_t offset, char* buf, std::size_t toRead);
|
||||
std::size_t write(std::size_t offset, char const* buf, std::size_t toWrite);
|
||||
std::size_t append(char const* buf, std::size_t toWrite);
|
||||
void trim(std::size_t newLen);
|
||||
|
||||
empty_session_backend& session_;
|
||||
};
|
||||
|
||||
struct empty_session_backend : details::session_backend
|
||||
{
|
||||
empty_session_backend(connection_parameters const& parameters);
|
||||
|
||||
~empty_session_backend();
|
||||
|
||||
void begin();
|
||||
void commit();
|
||||
void rollback();
|
||||
|
||||
std::string get_backend_name() const { return "empty"; }
|
||||
|
||||
void clean_up();
|
||||
|
||||
empty_statement_backend* make_statement_backend();
|
||||
empty_rowid_backend* make_rowid_backend();
|
||||
empty_blob_backend* make_blob_backend();
|
||||
};
|
||||
|
||||
struct SOCI_EMPTY_DECL empty_backend_factory : backend_factory
|
||||
{
|
||||
empty_backend_factory() {}
|
||||
empty_session_backend* make_session(connection_parameters const& parameters) const;
|
||||
};
|
||||
|
||||
extern SOCI_EMPTY_DECL empty_backend_factory const empty;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// for dynamic backend loading
|
||||
SOCI_EMPTY_DECL backend_factory const* factory_empty();
|
||||
SOCI_EMPTY_DECL void register_factory_empty();
|
||||
|
||||
} // extern "C"
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_EMPTY_H_INCLUDED
|
||||
50
src/soci/include/soci/error.h
Normal file
50
src/soci/include/soci/error.h
Normal file
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak
|
||||
// Copyright (C) 2015 Vadim Zeitlin
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_ERROR_H_INCLUDED
|
||||
#define SOCI_ERROR_H_INCLUDED
|
||||
|
||||
#include "soci/soci-platform.h"
|
||||
// std
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
class SOCI_DECL soci_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit soci_error(std::string const & msg);
|
||||
|
||||
soci_error(soci_error const& e);
|
||||
soci_error& operator=(soci_error const& e);
|
||||
|
||||
virtual ~soci_error() throw();
|
||||
|
||||
// Returns just the error message itself, without the context.
|
||||
std::string get_error_message() const;
|
||||
|
||||
// Returns the full error message combining the message given to the ctor
|
||||
// with all the available context records.
|
||||
virtual char const* what() const throw();
|
||||
|
||||
// This is used only by SOCI itself to provide more information about the
|
||||
// exception as it bubbles up. It can be called multiple times, with the
|
||||
// first call adding the lowest level context and the last one -- the
|
||||
// highest level context.
|
||||
void add_context(std::string const& context);
|
||||
|
||||
private:
|
||||
// Optional extra information (currently just the context data).
|
||||
class soci_error_extra_info* info_;
|
||||
};
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_ERROR_H_INCLUDED
|
||||
138
src/soci/include/soci/exchange-traits.h
Normal file
138
src/soci/include/soci/exchange-traits.h
Normal file
@@ -0,0 +1,138 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_EXCHANGE_TRAITS_H_INCLUDED
|
||||
#define SOCI_EXCHANGE_TRAITS_H_INCLUDED
|
||||
|
||||
#include "soci/type-conversion-traits.h"
|
||||
#include "soci/soci-backend.h"
|
||||
// std
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
struct basic_type_tag {};
|
||||
struct user_type_tag {};
|
||||
|
||||
template <typename T>
|
||||
struct exchange_traits
|
||||
{
|
||||
// this is used for tag-dispatch between implementations for basic types
|
||||
// and user-defined types
|
||||
typedef user_type_tag type_family;
|
||||
|
||||
enum // anonymous
|
||||
{
|
||||
x_type =
|
||||
exchange_traits
|
||||
<
|
||||
typename type_conversion<T>::base_type
|
||||
>::x_type
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_traits<short>
|
||||
{
|
||||
typedef basic_type_tag type_family;
|
||||
enum { x_type = x_short };
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_traits<unsigned short> : exchange_traits<short>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_traits<int>
|
||||
{
|
||||
typedef basic_type_tag type_family;
|
||||
enum { x_type = x_integer };
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_traits<unsigned int> : exchange_traits<int>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_traits<char>
|
||||
{
|
||||
typedef basic_type_tag type_family;
|
||||
enum { x_type = x_char };
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_traits<long long>
|
||||
{
|
||||
typedef basic_type_tag type_family;
|
||||
enum { x_type = x_long_long };
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_traits<unsigned long long>
|
||||
{
|
||||
typedef basic_type_tag type_family;
|
||||
enum { x_type = x_unsigned_long_long };
|
||||
};
|
||||
|
||||
// long must be mapped either to x_integer or x_long_long:
|
||||
template<int long_size> struct long_traits_helper;
|
||||
template<> struct long_traits_helper<4> { enum { x_type = x_integer }; };
|
||||
template<> struct long_traits_helper<8> { enum { x_type = x_long_long }; };
|
||||
|
||||
template <>
|
||||
struct exchange_traits<long int>
|
||||
{
|
||||
typedef basic_type_tag type_family;
|
||||
enum { x_type = long_traits_helper<sizeof(long int)>::x_type };
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_traits<unsigned long> : exchange_traits<long>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_traits<double>
|
||||
{
|
||||
typedef basic_type_tag type_family;
|
||||
enum { x_type = x_double };
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_traits<std::string>
|
||||
{
|
||||
typedef basic_type_tag type_family;
|
||||
enum { x_type = x_stdstring };
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_traits<std::tm>
|
||||
{
|
||||
typedef basic_type_tag type_family;
|
||||
enum { x_type = x_stdtm };
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct exchange_traits<std::vector<T> >
|
||||
{
|
||||
typedef typename exchange_traits<T>::type_family type_family;
|
||||
enum { x_type = exchange_traits<T>::x_type };
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_EXCHANGE_TRAITS_H_INCLUDED
|
||||
348
src/soci/include/soci/firebird/soci-firebird.h
Normal file
348
src/soci/include/soci/firebird/soci-firebird.h
Normal file
@@ -0,0 +1,348 @@
|
||||
//
|
||||
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, Rafal Bobrowski
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef SOCI_FIREBIRD_H_INCLUDED
|
||||
#define SOCI_FIREBIRD_H_INCLUDED
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef SOCI_DLL
|
||||
# ifdef SOCI_FIREBIRD_SOURCE
|
||||
# define SOCI_FIREBIRD_DECL __declspec(dllexport)
|
||||
# else
|
||||
# define SOCI_FIREBIRD_DECL __declspec(dllimport)
|
||||
# endif // SOCI_DLL
|
||||
# endif // SOCI_FIREBIRD_SOURCE
|
||||
#endif // _WIN32
|
||||
|
||||
//
|
||||
// If SOCI_FIREBIRD_DECL isn't defined yet define it now
|
||||
#ifndef SOCI_FIREBIRD_DECL
|
||||
# define SOCI_FIREBIRD_DECL
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <ciso646> // To understand and/or/not on MSVC9
|
||||
#endif
|
||||
#include <soci/soci-backend.h>
|
||||
#include <ibase.h> // FireBird
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
std::size_t const stat_size = 20;
|
||||
|
||||
// size of buffer for error messages. All examples use this value.
|
||||
// Anyone knows, where it is stated that 512 bytes is enough ?
|
||||
std::size_t const SOCI_FIREBIRD_ERRMSG = 512;
|
||||
|
||||
class SOCI_FIREBIRD_DECL firebird_soci_error : public soci_error
|
||||
{
|
||||
public:
|
||||
firebird_soci_error(std::string const & msg,
|
||||
ISC_STATUS const * status = 0);
|
||||
|
||||
~firebird_soci_error() throw() {};
|
||||
|
||||
std::vector<ISC_STATUS> status_;
|
||||
};
|
||||
|
||||
enum BuffersType
|
||||
{
|
||||
eStandard, eVector
|
||||
};
|
||||
|
||||
struct firebird_statement_backend;
|
||||
struct firebird_standard_into_type_backend : details::standard_into_type_backend
|
||||
{
|
||||
firebird_standard_into_type_backend(firebird_statement_backend &st)
|
||||
: statement_(st), buf_(NULL)
|
||||
{}
|
||||
|
||||
virtual void define_by_pos(int &position,
|
||||
void *data, details::exchange_type type);
|
||||
|
||||
virtual void pre_fetch();
|
||||
virtual void post_fetch(bool gotData, bool calledFromFetch,
|
||||
indicator *ind);
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
firebird_statement_backend &statement_;
|
||||
virtual void exchangeData();
|
||||
|
||||
void *data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
|
||||
char *buf_;
|
||||
short indISCHolder_;
|
||||
};
|
||||
|
||||
struct firebird_vector_into_type_backend : details::vector_into_type_backend
|
||||
{
|
||||
firebird_vector_into_type_backend(firebird_statement_backend &st)
|
||||
: statement_(st), buf_(NULL)
|
||||
{}
|
||||
|
||||
virtual void define_by_pos(int &position,
|
||||
void *data, details::exchange_type type);
|
||||
|
||||
virtual void pre_fetch();
|
||||
virtual void post_fetch(bool gotData, indicator *ind);
|
||||
|
||||
virtual void resize(std::size_t sz);
|
||||
virtual std::size_t size();
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
firebird_statement_backend &statement_;
|
||||
virtual void exchangeData(std::size_t row);
|
||||
|
||||
void *data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
|
||||
char *buf_;
|
||||
short indISCHolder_;
|
||||
};
|
||||
|
||||
struct firebird_standard_use_type_backend : details::standard_use_type_backend
|
||||
{
|
||||
firebird_standard_use_type_backend(firebird_statement_backend &st)
|
||||
: statement_(st), buf_(NULL), indISCHolder_(0)
|
||||
{}
|
||||
|
||||
virtual void bind_by_pos(int &position,
|
||||
void *data, details::exchange_type type, bool readOnly);
|
||||
virtual void bind_by_name(std::string const &name,
|
||||
void *data, details::exchange_type type, bool readOnly);
|
||||
|
||||
virtual void pre_use(indicator const *ind);
|
||||
virtual void post_use(bool gotData, indicator *ind);
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
firebird_statement_backend &statement_;
|
||||
virtual void exchangeData();
|
||||
|
||||
void *data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
|
||||
char *buf_;
|
||||
short indISCHolder_;
|
||||
};
|
||||
|
||||
struct firebird_vector_use_type_backend : details::vector_use_type_backend
|
||||
{
|
||||
firebird_vector_use_type_backend(firebird_statement_backend &st)
|
||||
: statement_(st), inds_(NULL), buf_(NULL), indISCHolder_(0)
|
||||
{}
|
||||
|
||||
virtual void bind_by_pos(int &position,
|
||||
void *data, details::exchange_type type);
|
||||
virtual void bind_by_name(std::string const &name,
|
||||
void *data, details::exchange_type type);
|
||||
|
||||
virtual void pre_use(indicator const *ind);
|
||||
|
||||
virtual std::size_t size();
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
firebird_statement_backend &statement_;
|
||||
virtual void exchangeData(std::size_t row);
|
||||
|
||||
void *data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
indicator const *inds_;
|
||||
|
||||
char *buf_;
|
||||
short indISCHolder_;
|
||||
};
|
||||
|
||||
struct firebird_session_backend;
|
||||
struct firebird_statement_backend : details::statement_backend
|
||||
{
|
||||
firebird_statement_backend(firebird_session_backend &session);
|
||||
|
||||
virtual void alloc();
|
||||
virtual void clean_up();
|
||||
virtual void prepare(std::string const &query,
|
||||
details::statement_type eType);
|
||||
|
||||
virtual exec_fetch_result execute(int number);
|
||||
virtual exec_fetch_result fetch(int number);
|
||||
|
||||
virtual long long get_affected_rows();
|
||||
virtual int get_number_of_rows();
|
||||
virtual std::string get_parameter_name(int index) const;
|
||||
|
||||
virtual std::string rewrite_for_procedure_call(std::string const &query);
|
||||
|
||||
virtual int prepare_for_describe();
|
||||
virtual void describe_column(int colNum, data_type &dtype,
|
||||
std::string &columnName);
|
||||
|
||||
virtual firebird_standard_into_type_backend * make_into_type_backend();
|
||||
virtual firebird_standard_use_type_backend * make_use_type_backend();
|
||||
virtual firebird_vector_into_type_backend * make_vector_into_type_backend();
|
||||
virtual firebird_vector_use_type_backend * make_vector_use_type_backend();
|
||||
|
||||
firebird_session_backend &session_;
|
||||
|
||||
isc_stmt_handle stmtp_;
|
||||
XSQLDA * sqldap_;
|
||||
XSQLDA * sqlda2p_;
|
||||
|
||||
bool boundByName_;
|
||||
bool boundByPos_;
|
||||
|
||||
friend struct firebird_vector_into_type_backend;
|
||||
friend struct firebird_standard_into_type_backend;
|
||||
friend struct firebird_vector_use_type_backend;
|
||||
friend struct firebird_standard_use_type_backend;
|
||||
|
||||
protected:
|
||||
int rowsFetched_;
|
||||
bool endOfRowSet_;
|
||||
|
||||
long long rowsAffectedBulk_; // number of rows affected by the last bulk operation
|
||||
|
||||
virtual void exchangeData(bool gotData, int row);
|
||||
virtual void prepareSQLDA(XSQLDA ** sqldap, short size = 10);
|
||||
virtual void rewriteQuery(std::string const & query,
|
||||
std::vector<char> & buffer);
|
||||
virtual void rewriteParameters(std::string const & src,
|
||||
std::vector<char> & dst);
|
||||
|
||||
BuffersType intoType_;
|
||||
BuffersType useType_;
|
||||
|
||||
std::vector<std::vector<indicator> > inds_;
|
||||
std::vector<void*> intos_;
|
||||
std::vector<void*> uses_;
|
||||
|
||||
// named parameters
|
||||
std::map <std::string, int> names_;
|
||||
|
||||
bool procedure_;
|
||||
};
|
||||
|
||||
struct firebird_blob_backend : details::blob_backend
|
||||
{
|
||||
firebird_blob_backend(firebird_session_backend &session);
|
||||
|
||||
~firebird_blob_backend();
|
||||
|
||||
virtual std::size_t get_len();
|
||||
virtual std::size_t read(std::size_t offset, char *buf,
|
||||
std::size_t toRead);
|
||||
virtual std::size_t write(std::size_t offset, char const *buf,
|
||||
std::size_t toWrite);
|
||||
virtual std::size_t append(char const *buf, std::size_t toWrite);
|
||||
virtual void trim(std::size_t newLen);
|
||||
|
||||
firebird_session_backend &session_;
|
||||
|
||||
virtual void save();
|
||||
virtual void assign(ISC_QUAD const & bid)
|
||||
{
|
||||
cleanUp();
|
||||
|
||||
bid_ = bid;
|
||||
from_db_ = true;
|
||||
}
|
||||
|
||||
// BLOB id from in database
|
||||
ISC_QUAD bid_;
|
||||
|
||||
// BLOB id was fetched from database (true)
|
||||
// or this is new BLOB
|
||||
bool from_db_;
|
||||
|
||||
// BLOB handle
|
||||
isc_blob_handle bhp_;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void open();
|
||||
virtual long getBLOBInfo();
|
||||
virtual void load();
|
||||
virtual void writeBuffer(std::size_t offset, char const * buf,
|
||||
std::size_t toWrite);
|
||||
virtual void cleanUp();
|
||||
|
||||
// buffer for BLOB data
|
||||
std::vector<char> data_;
|
||||
|
||||
bool loaded_;
|
||||
long max_seg_size_;
|
||||
};
|
||||
|
||||
struct firebird_session_backend : details::session_backend
|
||||
{
|
||||
firebird_session_backend(connection_parameters const & parameters);
|
||||
|
||||
~firebird_session_backend();
|
||||
|
||||
virtual void begin();
|
||||
virtual void commit();
|
||||
virtual void rollback();
|
||||
|
||||
virtual bool get_next_sequence_value(session & s,
|
||||
std::string const & sequence, long & value);
|
||||
|
||||
virtual std::string get_backend_name() const { return "firebird"; }
|
||||
|
||||
void cleanUp();
|
||||
|
||||
virtual firebird_statement_backend * make_statement_backend();
|
||||
virtual details::rowid_backend* make_rowid_backend();
|
||||
virtual firebird_blob_backend * make_blob_backend();
|
||||
|
||||
bool get_option_decimals_as_strings() { return decimals_as_strings_; }
|
||||
|
||||
// Returns the pointer to the current transaction handle, starting a new
|
||||
// transaction if necessary.
|
||||
//
|
||||
// The returned pointer should
|
||||
isc_tr_handle* current_transaction();
|
||||
|
||||
isc_db_handle dbhp_;
|
||||
|
||||
private:
|
||||
isc_tr_handle trhp_;
|
||||
bool decimals_as_strings_;
|
||||
};
|
||||
|
||||
struct firebird_backend_factory : backend_factory
|
||||
{
|
||||
firebird_backend_factory() {}
|
||||
virtual firebird_session_backend * make_session(
|
||||
connection_parameters const & parameters) const;
|
||||
};
|
||||
|
||||
extern SOCI_FIREBIRD_DECL firebird_backend_factory const firebird;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// for dynamic backend loading
|
||||
SOCI_FIREBIRD_DECL backend_factory const * factory_firebird();
|
||||
SOCI_FIREBIRD_DECL void register_factory_firebird();
|
||||
|
||||
} // extern "C"
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_FIREBIRD_H_INCLUDED
|
||||
164
src/soci/include/soci/into-type.h
Normal file
164
src/soci/include/soci/into-type.h
Normal file
@@ -0,0 +1,164 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_INTO_TYPE_H_INCLUDED
|
||||
#define SOCI_INTO_TYPE_H_INCLUDED
|
||||
|
||||
#include "soci/soci-backend.h"
|
||||
#include "soci/type-ptr.h"
|
||||
#include "soci/exchange-traits.h"
|
||||
// std
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
class session;
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
class prepare_temp_type;
|
||||
class standard_into_type_backend;
|
||||
class vector_into_type_backend;
|
||||
class statement_impl;
|
||||
|
||||
// this is intended to be a base class for all classes that deal with
|
||||
// defining output data
|
||||
class into_type_base
|
||||
{
|
||||
public:
|
||||
virtual ~into_type_base() {}
|
||||
|
||||
virtual void define(statement_impl & st, int & position) = 0;
|
||||
virtual void pre_fetch() = 0;
|
||||
virtual void post_fetch(bool gotData, bool calledFromFetch) = 0;
|
||||
virtual void clean_up() = 0;
|
||||
|
||||
virtual std::size_t size() const = 0; // returns the number of elements
|
||||
virtual void resize(std::size_t /* sz */) {} // used for vectors only
|
||||
};
|
||||
|
||||
typedef type_ptr<into_type_base> into_type_ptr;
|
||||
|
||||
// standard types
|
||||
|
||||
class SOCI_DECL standard_into_type : public into_type_base
|
||||
{
|
||||
public:
|
||||
standard_into_type(void * data, exchange_type type)
|
||||
: data_(data), type_(type), ind_(NULL), backEnd_(NULL) {}
|
||||
standard_into_type(void * data, exchange_type type, indicator & ind)
|
||||
: data_(data), type_(type), ind_(&ind), backEnd_(NULL) {}
|
||||
|
||||
virtual ~standard_into_type();
|
||||
|
||||
protected:
|
||||
virtual void post_fetch(bool gotData, bool calledFromFetch);
|
||||
|
||||
private:
|
||||
virtual void define(statement_impl & st, int & position);
|
||||
virtual void pre_fetch();
|
||||
virtual void clean_up();
|
||||
|
||||
virtual std::size_t size() const { return 1; }
|
||||
|
||||
// conversion hook (from base type to arbitrary user type)
|
||||
virtual void convert_from_base() {}
|
||||
|
||||
void * data_;
|
||||
exchange_type type_;
|
||||
indicator * ind_;
|
||||
|
||||
standard_into_type_backend * backEnd_;
|
||||
};
|
||||
|
||||
// into type base class for vectors
|
||||
class SOCI_DECL vector_into_type : public into_type_base
|
||||
{
|
||||
public:
|
||||
vector_into_type(void * data, exchange_type type)
|
||||
: data_(data), type_(type), indVec_(NULL), backEnd_(NULL) {}
|
||||
|
||||
vector_into_type(void * data, exchange_type type,
|
||||
std::vector<indicator> & ind)
|
||||
: data_(data), type_(type), indVec_(&ind), backEnd_(NULL) {}
|
||||
|
||||
~vector_into_type();
|
||||
|
||||
protected:
|
||||
virtual void post_fetch(bool gotData, bool calledFromFetch);
|
||||
|
||||
private:
|
||||
virtual void define(statement_impl & st, int & position);
|
||||
virtual void pre_fetch();
|
||||
virtual void clean_up();
|
||||
virtual void resize(std::size_t sz);
|
||||
virtual std::size_t size() const;
|
||||
|
||||
void * data_;
|
||||
exchange_type type_;
|
||||
std::vector<indicator> * indVec_;
|
||||
|
||||
vector_into_type_backend * backEnd_;
|
||||
|
||||
virtual void convert_from_base() {}
|
||||
};
|
||||
|
||||
// implementation for the basic types (those which are supported by the library
|
||||
// out of the box without user-provided conversions)
|
||||
|
||||
template <typename T>
|
||||
class into_type : public standard_into_type
|
||||
{
|
||||
public:
|
||||
into_type(T & t)
|
||||
: standard_into_type(&t,
|
||||
static_cast<exchange_type>(exchange_traits<T>::x_type)) {}
|
||||
into_type(T & t, indicator & ind)
|
||||
: standard_into_type(&t,
|
||||
static_cast<exchange_type>(exchange_traits<T>::x_type), ind) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class into_type<std::vector<T> > : public vector_into_type
|
||||
{
|
||||
public:
|
||||
into_type(std::vector<T> & v)
|
||||
: vector_into_type(&v,
|
||||
static_cast<exchange_type>(exchange_traits<T>::x_type)) {}
|
||||
into_type(std::vector<T> & v, std::vector<indicator> & ind)
|
||||
: vector_into_type(&v,
|
||||
static_cast<exchange_type>(exchange_traits<T>::x_type), ind) {}
|
||||
};
|
||||
|
||||
// helper dispatchers for basic types
|
||||
|
||||
template <typename T>
|
||||
into_type_ptr do_into(T & t, basic_type_tag)
|
||||
{
|
||||
return into_type_ptr(new into_type<T>(t));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
into_type_ptr do_into(T & t, indicator & ind, basic_type_tag)
|
||||
{
|
||||
return into_type_ptr(new into_type<T>(t, ind));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
into_type_ptr do_into(T & t, std::vector<indicator> & ind, basic_type_tag)
|
||||
{
|
||||
return into_type_ptr(new into_type<T>(t, ind));
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_INTO_TYPE_H_INCLUDED
|
||||
72
src/soci/include/soci/into.h
Normal file
72
src/soci/include/soci/into.h
Normal file
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_INTO_H_INCLUDED
|
||||
#define SOCI_INTO_H_INCLUDED
|
||||
|
||||
#include "soci/into-type.h"
|
||||
#include "soci/exchange-traits.h"
|
||||
#include "soci/type-conversion.h"
|
||||
// std
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
// the into function is a helper for defining output variables
|
||||
// these helpers work with both basic and user-defined types thanks to
|
||||
// the tag-dispatching, as defined in exchange_traits template
|
||||
|
||||
namespace details
|
||||
{
|
||||
template <typename T, typename Indicator>
|
||||
struct into_container
|
||||
{
|
||||
into_container(T &_t, Indicator &_ind)
|
||||
: t(_t), ind(_ind) {}
|
||||
|
||||
T &t;
|
||||
Indicator &ind;
|
||||
private:
|
||||
SOCI_NOT_ASSIGNABLE(into_container)
|
||||
};
|
||||
|
||||
typedef void no_indicator;
|
||||
template <typename T>
|
||||
struct into_container<T, no_indicator>
|
||||
{
|
||||
into_container(T &_t)
|
||||
: t(_t) {}
|
||||
|
||||
T &t;
|
||||
private:
|
||||
SOCI_NOT_ASSIGNABLE(into_container)
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
template <typename T>
|
||||
details::into_container<T, details::no_indicator>
|
||||
into(T &t)
|
||||
{ return details::into_container<T, details::no_indicator>(t); }
|
||||
|
||||
template <typename T, typename Indicator>
|
||||
details::into_container<T, Indicator>
|
||||
into(T &t, Indicator &ind)
|
||||
{ return details::into_container<T, Indicator>(t, ind); }
|
||||
|
||||
// for char buffer with run-time size information
|
||||
template <typename T>
|
||||
details::into_type_ptr into(T & t, std::size_t bufSize)
|
||||
{
|
||||
return details::into_type_ptr(new details::into_type<T>(t, bufSize));
|
||||
}
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_INTO_H_INCLUDED
|
||||
276
src/soci/include/soci/mysql/soci-mysql.h
Normal file
276
src/soci/include/soci/mysql/soci-mysql.h
Normal file
@@ -0,0 +1,276 @@
|
||||
//
|
||||
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton
|
||||
// MySQL backend copyright (C) 2006 Pawel Aleksander Fedorynski
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_MYSQL_H_INCLUDED
|
||||
#define SOCI_MYSQL_H_INCLUDED
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef SOCI_DLL
|
||||
# ifdef SOCI_MYSQL_SOURCE
|
||||
# define SOCI_MYSQL_DECL __declspec(dllexport)
|
||||
# else
|
||||
# define SOCI_MYSQL_DECL __declspec(dllimport)
|
||||
# endif // SOCI_DLL
|
||||
# endif // SOCI_MYSQL_SOURCE
|
||||
#endif // _WIN32
|
||||
//
|
||||
// If SOCI_MYSQL_DECL isn't defined yet define it now
|
||||
#ifndef SOCI_MYSQL_DECL
|
||||
# define SOCI_MYSQL_DECL
|
||||
#endif
|
||||
|
||||
#include <soci/soci-backend.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock.h> // SOCKET
|
||||
#endif // _WIN32
|
||||
#include <mysql.h> // MySQL Client
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
class mysql_soci_error : public soci_error
|
||||
{
|
||||
public:
|
||||
mysql_soci_error(std::string const & msg, int errNum)
|
||||
: soci_error(msg), err_num_(errNum) {}
|
||||
|
||||
unsigned int err_num_;
|
||||
};
|
||||
|
||||
struct mysql_statement_backend;
|
||||
struct mysql_standard_into_type_backend : details::standard_into_type_backend
|
||||
{
|
||||
mysql_standard_into_type_backend(mysql_statement_backend &st)
|
||||
: statement_(st) {}
|
||||
|
||||
virtual void define_by_pos(int &position,
|
||||
void *data, details::exchange_type type);
|
||||
|
||||
virtual void pre_fetch();
|
||||
virtual void post_fetch(bool gotData, bool calledFromFetch,
|
||||
indicator *ind);
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
mysql_statement_backend &statement_;
|
||||
|
||||
void *data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
};
|
||||
|
||||
struct mysql_vector_into_type_backend : details::vector_into_type_backend
|
||||
{
|
||||
mysql_vector_into_type_backend(mysql_statement_backend &st)
|
||||
: statement_(st) {}
|
||||
|
||||
virtual void define_by_pos(int &position,
|
||||
void *data, details::exchange_type type);
|
||||
|
||||
virtual void pre_fetch();
|
||||
virtual void post_fetch(bool gotData, indicator *ind);
|
||||
|
||||
virtual void resize(std::size_t sz);
|
||||
virtual std::size_t size();
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
mysql_statement_backend &statement_;
|
||||
|
||||
void *data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
};
|
||||
|
||||
struct mysql_standard_use_type_backend : details::standard_use_type_backend
|
||||
{
|
||||
mysql_standard_use_type_backend(mysql_statement_backend &st)
|
||||
: statement_(st), position_(0), buf_(NULL) {}
|
||||
|
||||
virtual void bind_by_pos(int &position,
|
||||
void *data, details::exchange_type type, bool readOnly);
|
||||
virtual void bind_by_name(std::string const &name,
|
||||
void *data, details::exchange_type type, bool readOnly);
|
||||
|
||||
virtual void pre_use(indicator const *ind);
|
||||
virtual void post_use(bool gotData, indicator *ind);
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
mysql_statement_backend &statement_;
|
||||
|
||||
void *data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
std::string name_;
|
||||
char *buf_;
|
||||
};
|
||||
|
||||
struct mysql_vector_use_type_backend : details::vector_use_type_backend
|
||||
{
|
||||
mysql_vector_use_type_backend(mysql_statement_backend &st)
|
||||
: statement_(st), position_(0) {}
|
||||
|
||||
virtual void bind_by_pos(int &position,
|
||||
void *data, details::exchange_type type);
|
||||
virtual void bind_by_name(std::string const &name,
|
||||
void *data, details::exchange_type type);
|
||||
|
||||
virtual void pre_use(indicator const *ind);
|
||||
|
||||
virtual std::size_t size();
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
mysql_statement_backend &statement_;
|
||||
|
||||
void *data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
std::string name_;
|
||||
std::vector<char *> buffers_;
|
||||
};
|
||||
|
||||
struct mysql_session_backend;
|
||||
struct mysql_statement_backend : details::statement_backend
|
||||
{
|
||||
mysql_statement_backend(mysql_session_backend &session);
|
||||
|
||||
virtual void alloc();
|
||||
virtual void clean_up();
|
||||
virtual void prepare(std::string const &query,
|
||||
details::statement_type eType);
|
||||
|
||||
virtual exec_fetch_result execute(int number);
|
||||
virtual exec_fetch_result fetch(int number);
|
||||
|
||||
virtual long long get_affected_rows();
|
||||
virtual int get_number_of_rows();
|
||||
virtual std::string get_parameter_name(int index) const;
|
||||
|
||||
virtual std::string rewrite_for_procedure_call(std::string const &query);
|
||||
|
||||
virtual int prepare_for_describe();
|
||||
virtual void describe_column(int colNum, data_type &dtype,
|
||||
std::string &columnName);
|
||||
|
||||
virtual mysql_standard_into_type_backend * make_into_type_backend();
|
||||
virtual mysql_standard_use_type_backend * make_use_type_backend();
|
||||
virtual mysql_vector_into_type_backend * make_vector_into_type_backend();
|
||||
virtual mysql_vector_use_type_backend * make_vector_use_type_backend();
|
||||
|
||||
mysql_session_backend &session_;
|
||||
|
||||
MYSQL_RES *result_;
|
||||
|
||||
// The query is split into chunks, separated by the named parameters;
|
||||
// e.g. for "SELECT id FROM ttt WHERE name = :foo AND gender = :bar"
|
||||
// we will have query chunks "SELECT id FROM ttt WHERE name = ",
|
||||
// "AND gender = " and names "foo", "bar".
|
||||
std::vector<std::string> queryChunks_;
|
||||
std::vector<std::string> names_; // list of names for named binds
|
||||
|
||||
long long rowsAffectedBulk_; // number of rows affected by the last bulk operation
|
||||
|
||||
int numberOfRows_; // number of rows retrieved from the server
|
||||
int currentRow_; // "current" row number to consume in postFetch
|
||||
int rowsToConsume_; // number of rows to be consumed in postFetch
|
||||
|
||||
bool justDescribed_; // to optimize row description with immediately
|
||||
// following actual statement execution
|
||||
|
||||
// Prefetch the row offsets in order to use mysql_row_seek() for
|
||||
// random access to rows, since mysql_data_seek() is expensive.
|
||||
std::vector<MYSQL_ROW_OFFSET> resultRowOffsets_;
|
||||
|
||||
bool hasIntoElements_;
|
||||
bool hasVectorIntoElements_;
|
||||
bool hasUseElements_;
|
||||
bool hasVectorUseElements_;
|
||||
|
||||
// the following maps are used for finding data buffers according to
|
||||
// use elements specified by the user
|
||||
|
||||
typedef std::map<int, char **> UseByPosBuffersMap;
|
||||
UseByPosBuffersMap useByPosBuffers_;
|
||||
|
||||
typedef std::map<std::string, char **> UseByNameBuffersMap;
|
||||
UseByNameBuffersMap useByNameBuffers_;
|
||||
};
|
||||
|
||||
struct mysql_rowid_backend : details::rowid_backend
|
||||
{
|
||||
mysql_rowid_backend(mysql_session_backend &session);
|
||||
|
||||
~mysql_rowid_backend();
|
||||
};
|
||||
|
||||
struct mysql_blob_backend : details::blob_backend
|
||||
{
|
||||
mysql_blob_backend(mysql_session_backend &session);
|
||||
|
||||
~mysql_blob_backend();
|
||||
|
||||
virtual std::size_t get_len();
|
||||
virtual std::size_t read(std::size_t offset, char *buf,
|
||||
std::size_t toRead);
|
||||
virtual std::size_t write(std::size_t offset, char const *buf,
|
||||
std::size_t toWrite);
|
||||
virtual std::size_t append(char const *buf, std::size_t toWrite);
|
||||
virtual void trim(std::size_t newLen);
|
||||
|
||||
mysql_session_backend &session_;
|
||||
};
|
||||
|
||||
struct mysql_session_backend : details::session_backend
|
||||
{
|
||||
mysql_session_backend(connection_parameters const & parameters);
|
||||
|
||||
~mysql_session_backend();
|
||||
|
||||
virtual void begin();
|
||||
virtual void commit();
|
||||
virtual void rollback();
|
||||
|
||||
virtual bool get_last_insert_id(session&, std::string const&, long&);
|
||||
|
||||
virtual std::string get_backend_name() const { return "mysql"; }
|
||||
|
||||
void clean_up();
|
||||
|
||||
virtual mysql_statement_backend * make_statement_backend();
|
||||
virtual mysql_rowid_backend * make_rowid_backend();
|
||||
virtual mysql_blob_backend * make_blob_backend();
|
||||
|
||||
MYSQL *conn_;
|
||||
};
|
||||
|
||||
|
||||
struct mysql_backend_factory : backend_factory
|
||||
{
|
||||
mysql_backend_factory() {}
|
||||
virtual mysql_session_backend * make_session(
|
||||
connection_parameters const & parameters) const;
|
||||
};
|
||||
|
||||
extern SOCI_MYSQL_DECL mysql_backend_factory const mysql;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// for dynamic backend loading
|
||||
SOCI_MYSQL_DECL backend_factory const * factory_mysql();
|
||||
SOCI_MYSQL_DECL void register_factory_mysql();
|
||||
|
||||
} // extern "C"
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_MYSQL_H_INCLUDED
|
||||
22
src/soci/include/soci/noreturn.h
Normal file
22
src/soci/include/soci/noreturn.h
Normal file
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// Copyright (C) 2015 Vadim Zeitlin
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_NORETURN_H_INCLUDED
|
||||
#define SOCI_NORETURN_H_INCLUDED
|
||||
|
||||
// Define a portable SOCI_NORETURN macro.
|
||||
//
|
||||
// TODO-C++11: Use [[noreturn]] attribute.
|
||||
#if defined(__GNUC__)
|
||||
# define SOCI_NORETURN __attribute__((noreturn)) void
|
||||
#elif defined(_MSC_VER)
|
||||
# define SOCI_NORETURN __declspec(noreturn) void
|
||||
#else
|
||||
# define SOCI_NORETURN void
|
||||
#endif
|
||||
|
||||
#endif // SOCI_NORETURN_H_INCLUDED
|
||||
455
src/soci/include/soci/odbc/soci-odbc.h
Normal file
455
src/soci/include/soci/odbc/soci-odbc.h
Normal file
@@ -0,0 +1,455 @@
|
||||
//
|
||||
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, David Courtney
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_ODBC_H_INCLUDED
|
||||
#define SOCI_ODBC_H_INCLUDED
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef SOCI_DLL
|
||||
# ifdef SOCI_ODBC_SOURCE
|
||||
# define SOCI_ODBC_DECL __declspec(dllexport)
|
||||
# else
|
||||
# define SOCI_ODBC_DECL __declspec(dllimport)
|
||||
# endif // SOCI_ODBC_SOURCE
|
||||
# endif // SOCI_DLL
|
||||
#endif // _WIN32
|
||||
//
|
||||
// If SOCI_ODBC_DECL isn't defined yet define it now
|
||||
#ifndef SOCI_ODBC_DECL
|
||||
# define SOCI_ODBC_DECL
|
||||
#endif
|
||||
|
||||
#include "soci/soci-platform.h"
|
||||
#include <vector>
|
||||
#include <soci/soci-backend.h>
|
||||
#include <sstream>
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <sqlext.h> // ODBC
|
||||
#include <string.h> // strcpy()
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
// TODO: Do we want to make it a part of public interface? --mloskot
|
||||
std::size_t const odbc_max_buffer_length = 100 * 1024 * 1024;
|
||||
|
||||
// This cast is only used to avoid compiler warnings when passing strings
|
||||
// to ODBC functions, the returned string may *not* be really modified.
|
||||
inline SQLCHAR* sqlchar_cast(std::string const& s)
|
||||
{
|
||||
return reinterpret_cast<SQLCHAR*>(const_cast<char*>(s.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
// Option allowing to specify the "driver completion" parameter of
|
||||
// SQLDriverConnect(). Its possible values are the same as the allowed values
|
||||
// for this parameter in the official ODBC, i.e. one of SQL_DRIVER_XXX (in
|
||||
// string form as all options are strings currently).
|
||||
extern SOCI_ODBC_DECL char const * odbc_option_driver_complete;
|
||||
|
||||
struct odbc_statement_backend;
|
||||
|
||||
// Helper of into and use backends.
|
||||
class odbc_standard_type_backend_base
|
||||
{
|
||||
protected:
|
||||
odbc_standard_type_backend_base(odbc_statement_backend &st)
|
||||
: statement_(st) {}
|
||||
|
||||
// Check if we need to pass 64 bit integers as strings to the database as
|
||||
// some drivers don't support them directly.
|
||||
inline bool use_string_for_bigint() const;
|
||||
|
||||
// If we do need to use strings for 64 bit integers, this constant defines
|
||||
// the maximal string length needed.
|
||||
enum
|
||||
{
|
||||
// This is the length of decimal representation of UINT64_MAX + 1.
|
||||
max_bigint_length = 21
|
||||
};
|
||||
|
||||
odbc_statement_backend &statement_;
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(odbc_standard_type_backend_base)
|
||||
};
|
||||
|
||||
struct odbc_standard_into_type_backend : details::standard_into_type_backend,
|
||||
private odbc_standard_type_backend_base
|
||||
{
|
||||
odbc_standard_into_type_backend(odbc_statement_backend &st)
|
||||
: odbc_standard_type_backend_base(st), buf_(0)
|
||||
{}
|
||||
|
||||
virtual void define_by_pos(int &position,
|
||||
void *data, details::exchange_type type);
|
||||
|
||||
virtual void pre_fetch();
|
||||
virtual void post_fetch(bool gotData, bool calledFromFetch,
|
||||
indicator *ind);
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
char *buf_; // generic buffer
|
||||
void *data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
SQLSMALLINT odbcType_;
|
||||
SQLLEN valueLen_;
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(odbc_standard_into_type_backend)
|
||||
};
|
||||
|
||||
struct odbc_vector_into_type_backend : details::vector_into_type_backend,
|
||||
private odbc_standard_type_backend_base
|
||||
{
|
||||
odbc_vector_into_type_backend(odbc_statement_backend &st)
|
||||
: odbc_standard_type_backend_base(st), indHolders_(NULL),
|
||||
data_(NULL), buf_(NULL) {}
|
||||
|
||||
virtual void define_by_pos(int &position,
|
||||
void *data, details::exchange_type type);
|
||||
|
||||
virtual void pre_fetch();
|
||||
virtual void post_fetch(bool gotData, indicator *ind);
|
||||
|
||||
virtual void resize(std::size_t sz);
|
||||
virtual std::size_t size();
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
// helper function for preparing indicators
|
||||
// (as part of the define_by_pos)
|
||||
void prepare_indicators(std::size_t size);
|
||||
|
||||
|
||||
SQLLEN *indHolders_;
|
||||
std::vector<SQLLEN> indHolderVec_;
|
||||
void *data_;
|
||||
char *buf_; // generic buffer
|
||||
details::exchange_type type_;
|
||||
std::size_t colSize_; // size of the string column (used for strings)
|
||||
SQLSMALLINT odbcType_;
|
||||
};
|
||||
|
||||
struct odbc_standard_use_type_backend : details::standard_use_type_backend,
|
||||
private odbc_standard_type_backend_base
|
||||
{
|
||||
odbc_standard_use_type_backend(odbc_statement_backend &st)
|
||||
: odbc_standard_type_backend_base(st),
|
||||
position_(-1), data_(0), buf_(0), indHolder_(0) {}
|
||||
|
||||
virtual void bind_by_pos(int &position,
|
||||
void *data, details::exchange_type type, bool readOnly);
|
||||
virtual void bind_by_name(std::string const &name,
|
||||
void *data, details::exchange_type type, bool readOnly);
|
||||
|
||||
virtual void pre_use(indicator const *ind);
|
||||
virtual void post_use(bool gotData, indicator *ind);
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
// Return the pointer to the buffer containing data to be used by ODBC.
|
||||
// This can be either data_ itself or buf_, that is allocated by this
|
||||
// function if necessary.
|
||||
//
|
||||
// Also fill in the size of the data and SQL and C types of it.
|
||||
void* prepare_for_bind(SQLLEN &size,
|
||||
SQLSMALLINT &sqlType, SQLSMALLINT &cType);
|
||||
|
||||
int position_;
|
||||
void *data_;
|
||||
details::exchange_type type_;
|
||||
char *buf_;
|
||||
SQLLEN indHolder_;
|
||||
};
|
||||
|
||||
struct odbc_vector_use_type_backend : details::vector_use_type_backend,
|
||||
private odbc_standard_type_backend_base
|
||||
{
|
||||
odbc_vector_use_type_backend(odbc_statement_backend &st)
|
||||
: odbc_standard_type_backend_base(st), indHolders_(NULL),
|
||||
data_(NULL), buf_(NULL) {}
|
||||
|
||||
// helper function for preparing indicators
|
||||
// (as part of the define_by_pos)
|
||||
void prepare_indicators(std::size_t size);
|
||||
|
||||
// common part for bind_by_pos and bind_by_name
|
||||
void prepare_for_bind(void *&data, SQLUINTEGER &size, SQLSMALLINT &sqlType, SQLSMALLINT &cType);
|
||||
void bind_helper(int &position,
|
||||
void *data, details::exchange_type type);
|
||||
|
||||
virtual void bind_by_pos(int &position,
|
||||
void *data, details::exchange_type type);
|
||||
virtual void bind_by_name(std::string const &name,
|
||||
void *data, details::exchange_type type);
|
||||
|
||||
virtual void pre_use(indicator const *ind);
|
||||
|
||||
virtual std::size_t size();
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
|
||||
SQLLEN *indHolders_;
|
||||
std::vector<SQLLEN> indHolderVec_;
|
||||
void *data_;
|
||||
details::exchange_type type_;
|
||||
char *buf_; // generic buffer
|
||||
std::size_t colSize_; // size of the string column (used for strings)
|
||||
// used for strings only
|
||||
std::size_t maxSize_;
|
||||
};
|
||||
|
||||
struct odbc_session_backend;
|
||||
struct odbc_statement_backend : details::statement_backend
|
||||
{
|
||||
odbc_statement_backend(odbc_session_backend &session);
|
||||
|
||||
virtual void alloc();
|
||||
virtual void clean_up();
|
||||
virtual void prepare(std::string const &query,
|
||||
details::statement_type eType);
|
||||
|
||||
virtual exec_fetch_result execute(int number);
|
||||
virtual exec_fetch_result fetch(int number);
|
||||
|
||||
virtual long long get_affected_rows();
|
||||
virtual int get_number_of_rows();
|
||||
virtual std::string get_parameter_name(int index) const;
|
||||
|
||||
virtual std::string rewrite_for_procedure_call(std::string const &query);
|
||||
|
||||
virtual int prepare_for_describe();
|
||||
virtual void describe_column(int colNum, data_type &dtype,
|
||||
std::string &columnName);
|
||||
|
||||
// helper for defining into vector<string>
|
||||
std::size_t column_size(int position);
|
||||
|
||||
virtual odbc_standard_into_type_backend * make_into_type_backend();
|
||||
virtual odbc_standard_use_type_backend * make_use_type_backend();
|
||||
virtual odbc_vector_into_type_backend * make_vector_into_type_backend();
|
||||
virtual odbc_vector_use_type_backend * make_vector_use_type_backend();
|
||||
|
||||
odbc_session_backend &session_;
|
||||
SQLHSTMT hstmt_;
|
||||
SQLULEN numRowsFetched_;
|
||||
bool hasVectorUseElements_;
|
||||
bool boundByName_;
|
||||
bool boundByPos_;
|
||||
|
||||
long long rowsAffected_; // number of rows affected by the last operation
|
||||
|
||||
std::string query_;
|
||||
std::vector<std::string> names_; // list of names for named binds
|
||||
|
||||
};
|
||||
|
||||
struct odbc_rowid_backend : details::rowid_backend
|
||||
{
|
||||
odbc_rowid_backend(odbc_session_backend &session);
|
||||
|
||||
~odbc_rowid_backend();
|
||||
};
|
||||
|
||||
struct odbc_blob_backend : details::blob_backend
|
||||
{
|
||||
odbc_blob_backend(odbc_session_backend &session);
|
||||
|
||||
~odbc_blob_backend();
|
||||
|
||||
virtual std::size_t get_len();
|
||||
virtual std::size_t read(std::size_t offset, char *buf,
|
||||
std::size_t toRead);
|
||||
virtual std::size_t write(std::size_t offset, char const *buf,
|
||||
std::size_t toWrite);
|
||||
virtual std::size_t append(char const *buf, std::size_t toWrite);
|
||||
virtual void trim(std::size_t newLen);
|
||||
|
||||
odbc_session_backend &session_;
|
||||
};
|
||||
|
||||
struct odbc_session_backend : details::session_backend
|
||||
{
|
||||
odbc_session_backend(connection_parameters const & parameters);
|
||||
|
||||
~odbc_session_backend();
|
||||
|
||||
virtual void begin();
|
||||
virtual void commit();
|
||||
virtual void rollback();
|
||||
|
||||
virtual bool get_next_sequence_value(session & s,
|
||||
std::string const & sequence, long & value);
|
||||
virtual bool get_last_insert_id(session & s,
|
||||
std::string const & table, long & value);
|
||||
|
||||
virtual std::string get_backend_name() const { return "odbc"; }
|
||||
|
||||
void configure_connection();
|
||||
void reset_transaction();
|
||||
|
||||
void clean_up();
|
||||
|
||||
virtual odbc_statement_backend * make_statement_backend();
|
||||
virtual odbc_rowid_backend * make_rowid_backend();
|
||||
virtual odbc_blob_backend * make_blob_backend();
|
||||
|
||||
enum database_product
|
||||
{
|
||||
prod_uninitialized, // Never returned by get_database_product().
|
||||
prod_firebird,
|
||||
prod_mssql,
|
||||
prod_mysql,
|
||||
prod_oracle,
|
||||
prod_postgresql,
|
||||
prod_sqlite,
|
||||
prod_unknown = -1
|
||||
};
|
||||
|
||||
// Determine the type of the database we're connected to.
|
||||
database_product get_database_product();
|
||||
|
||||
// Return full ODBC connection string.
|
||||
std::string get_connection_string() const { return connection_string_; }
|
||||
|
||||
SQLHENV henv_;
|
||||
SQLHDBC hdbc_;
|
||||
|
||||
std::string connection_string_;
|
||||
database_product product_;
|
||||
};
|
||||
|
||||
class SOCI_ODBC_DECL odbc_soci_error : public soci_error
|
||||
{
|
||||
SQLCHAR message_[SQL_MAX_MESSAGE_LENGTH + 1];
|
||||
SQLCHAR sqlstate_[SQL_SQLSTATE_SIZE + 1];
|
||||
SQLINTEGER sqlcode_;
|
||||
|
||||
public:
|
||||
odbc_soci_error(SQLSMALLINT htype,
|
||||
SQLHANDLE hndl,
|
||||
std::string const & msg)
|
||||
: soci_error(interpret_odbc_error(htype, hndl, msg))
|
||||
{
|
||||
}
|
||||
|
||||
SQLCHAR const * odbc_error_code() const
|
||||
{
|
||||
return sqlstate_;
|
||||
}
|
||||
SQLINTEGER native_error_code() const
|
||||
{
|
||||
return sqlcode_;
|
||||
}
|
||||
SQLCHAR const * odbc_error_message() const
|
||||
{
|
||||
return message_;
|
||||
}
|
||||
private:
|
||||
std::string interpret_odbc_error(SQLSMALLINT htype, SQLHANDLE hndl, std::string const& msg)
|
||||
{
|
||||
const char* socierror = NULL;
|
||||
|
||||
SQLSMALLINT length, i = 1;
|
||||
switch ( SQLGetDiagRecA(htype, hndl, i, sqlstate_, &sqlcode_,
|
||||
message_, SQL_MAX_MESSAGE_LENGTH + 1,
|
||||
&length) )
|
||||
{
|
||||
case SQL_SUCCESS:
|
||||
// The error message was successfully retrieved.
|
||||
break;
|
||||
|
||||
case SQL_INVALID_HANDLE:
|
||||
socierror = "[SOCI]: Invalid handle.";
|
||||
break;
|
||||
|
||||
case SQL_ERROR:
|
||||
socierror = "[SOCI]: SQLGetDiagRec() error.";
|
||||
break;
|
||||
|
||||
case SQL_SUCCESS_WITH_INFO:
|
||||
socierror = "[SOCI]: Error message too long.";
|
||||
break;
|
||||
|
||||
case SQL_NO_DATA:
|
||||
socierror = "[SOCI]: No error.";
|
||||
break;
|
||||
|
||||
default:
|
||||
socierror = "[SOCI]: Unexpected SQLGetDiagRec() return value.";
|
||||
break;
|
||||
}
|
||||
|
||||
if (socierror)
|
||||
{
|
||||
// Use our own error message if we failed to retrieve the ODBC one.
|
||||
strcpy(reinterpret_cast<char*>(message_), socierror);
|
||||
|
||||
// Use "General warning" SQLSTATE code.
|
||||
strcpy(reinterpret_cast<char*>(sqlstate_), "01000");
|
||||
|
||||
sqlcode_ = 0;
|
||||
}
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << "Error " << msg << ": " << message_ << " (SQL state " << sqlstate_ << ")";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
inline bool is_odbc_error(SQLRETURN rc)
|
||||
{
|
||||
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO && rc != SQL_NO_DATA)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool odbc_standard_type_backend_base::use_string_for_bigint() const
|
||||
{
|
||||
// Oracle ODBC driver doesn't support SQL_C_[SU]BIGINT data types
|
||||
// (see appendix G.1 of Oracle Database Administrator's reference at
|
||||
// http://docs.oracle.com/cd/B19306_01/server.102/b15658/app_odbc.htm),
|
||||
// so we need a special workaround for this case and we represent 64
|
||||
// bit integers as strings and rely on ODBC driver for transforming
|
||||
// them to SQL_NUMERIC.
|
||||
return statement_.session_.get_database_product()
|
||||
== odbc_session_backend::prod_oracle;
|
||||
}
|
||||
|
||||
struct odbc_backend_factory : backend_factory
|
||||
{
|
||||
odbc_backend_factory() {}
|
||||
virtual odbc_session_backend * make_session(
|
||||
connection_parameters const & parameters) const;
|
||||
};
|
||||
|
||||
extern SOCI_ODBC_DECL odbc_backend_factory const odbc;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// for dynamic backend loading
|
||||
SOCI_ODBC_DECL backend_factory const * factory_odbc();
|
||||
SOCI_ODBC_DECL void register_factory_odbc();
|
||||
|
||||
} // extern "C"
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_EMPTY_H_INCLUDED
|
||||
119
src/soci/include/soci/once-temp-type.h
Normal file
119
src/soci/include/soci/once-temp-type.h
Normal file
@@ -0,0 +1,119 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_ONCE_TEMP_TYPE_H_INCLUDED
|
||||
#define SOCI_ONCE_TEMP_TYPE_H_INCLUDED
|
||||
|
||||
#include "soci/ref-counted-statement.h"
|
||||
#include "soci/prepare-temp-type.h"
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#define SOCI_ONCE_TEMP_TYPE_NOEXCEPT noexcept(false)
|
||||
#else
|
||||
#define SOCI_ONCE_TEMP_TYPE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
class session;
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
class ref_counted_statement;
|
||||
|
||||
// this needs to be lightweight and copyable
|
||||
class SOCI_DECL once_temp_type
|
||||
{
|
||||
public:
|
||||
|
||||
once_temp_type(session & s);
|
||||
once_temp_type(once_temp_type const & o);
|
||||
once_temp_type & operator=(once_temp_type const & o);
|
||||
|
||||
~once_temp_type() SOCI_ONCE_TEMP_TYPE_NOEXCEPT;
|
||||
|
||||
template <typename T>
|
||||
once_temp_type & operator<<(T const & t)
|
||||
{
|
||||
rcst_->accumulate(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
once_temp_type & operator,(into_type_ptr const &);
|
||||
template <typename T, typename Indicator>
|
||||
once_temp_type &operator,(into_container<T, Indicator> const &ic)
|
||||
{
|
||||
rcst_->exchange(ic);
|
||||
return *this;
|
||||
}
|
||||
template <typename T, typename Indicator>
|
||||
once_temp_type &operator,(use_container<T, Indicator> const &uc)
|
||||
{
|
||||
rcst_->exchange(uc);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
ref_counted_statement * rcst_;
|
||||
};
|
||||
|
||||
// this needs to be lightweight and copyable
|
||||
class once_type
|
||||
{
|
||||
public:
|
||||
once_type() : session_(NULL) {}
|
||||
once_type(session * s) : session_(s) {}
|
||||
|
||||
void set_session(session * s)
|
||||
{
|
||||
session_ = s;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
once_temp_type operator<<(T const & t)
|
||||
{
|
||||
once_temp_type o(*session_);
|
||||
o << t;
|
||||
return o;
|
||||
}
|
||||
|
||||
private:
|
||||
session * session_;
|
||||
};
|
||||
|
||||
|
||||
// this needs to be lightweight and copyable
|
||||
class prepare_type
|
||||
{
|
||||
public:
|
||||
prepare_type() : session_(NULL) {}
|
||||
prepare_type(session * s) : session_(s) {}
|
||||
|
||||
void set_session(session * s)
|
||||
{
|
||||
session_ = s;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
prepare_temp_type operator<<(T const & t)
|
||||
{
|
||||
prepare_temp_type p(*session_);
|
||||
p << t;
|
||||
return p;
|
||||
}
|
||||
|
||||
private:
|
||||
session * session_;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif
|
||||
301
src/soci/include/soci/oracle/soci-oracle.h
Normal file
301
src/soci/include/soci/oracle/soci-oracle.h
Normal file
@@ -0,0 +1,301 @@
|
||||
//
|
||||
// Copyright (C) 2004-2007 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_ORACLE_H_INCLUDED
|
||||
#define SOCI_ORACLE_H_INCLUDED
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef SOCI_DLL
|
||||
# ifdef SOCI_ORACLE_SOURCE
|
||||
# define SOCI_ORACLE_DECL __declspec(dllexport)
|
||||
# else
|
||||
# define SOCI_ORACLE_DECL __declspec(dllimport)
|
||||
# endif // SOCI_ORACLE_SOURCE
|
||||
# endif // SOCI_DLL
|
||||
#endif // _WIN32
|
||||
//
|
||||
// If SOCI_ORACLE_DECL isn't defined yet define it now
|
||||
#ifndef SOCI_ORACLE_DECL
|
||||
# define SOCI_ORACLE_DECL
|
||||
#endif
|
||||
|
||||
#include <soci/soci-backend.h>
|
||||
#include <oci.h> // OCI
|
||||
#include <vector>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4512 4511)
|
||||
#endif
|
||||
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
class SOCI_ORACLE_DECL oracle_soci_error : public soci_error
|
||||
{
|
||||
public:
|
||||
oracle_soci_error(std::string const & msg, int errNum = 0);
|
||||
|
||||
int err_num_;
|
||||
};
|
||||
|
||||
|
||||
struct oracle_statement_backend;
|
||||
struct oracle_standard_into_type_backend : details::standard_into_type_backend
|
||||
{
|
||||
oracle_standard_into_type_backend(oracle_statement_backend &st)
|
||||
: statement_(st), defnp_(NULL), indOCIHolder_(0),
|
||||
data_(NULL), buf_(NULL) {}
|
||||
|
||||
virtual void define_by_pos(int &position,
|
||||
void *data, details::exchange_type type);
|
||||
|
||||
virtual void pre_fetch();
|
||||
virtual void post_fetch(bool gotData, bool calledFromFetch,
|
||||
indicator *ind);
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
oracle_statement_backend &statement_;
|
||||
|
||||
OCIDefine *defnp_;
|
||||
sb2 indOCIHolder_;
|
||||
void *data_;
|
||||
char *buf_; // generic buffer
|
||||
details::exchange_type type_;
|
||||
|
||||
ub2 rCode_;
|
||||
};
|
||||
|
||||
struct oracle_vector_into_type_backend : details::vector_into_type_backend
|
||||
{
|
||||
oracle_vector_into_type_backend(oracle_statement_backend &st)
|
||||
: statement_(st), defnp_(NULL), indOCIHolders_(NULL),
|
||||
data_(NULL), buf_(NULL) {}
|
||||
|
||||
virtual void define_by_pos(int &position,
|
||||
void *data, details::exchange_type type);
|
||||
|
||||
virtual void pre_fetch();
|
||||
virtual void post_fetch(bool gotData, indicator *ind);
|
||||
|
||||
virtual void resize(std::size_t sz);
|
||||
virtual std::size_t size();
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
// helper function for preparing indicators and sizes_ vectors
|
||||
// (as part of the define_by_pos)
|
||||
void prepare_indicators(std::size_t size);
|
||||
|
||||
oracle_statement_backend &statement_;
|
||||
|
||||
OCIDefine *defnp_;
|
||||
sb2 *indOCIHolders_;
|
||||
std::vector<sb2> indOCIHolderVec_;
|
||||
void *data_;
|
||||
char *buf_; // generic buffer
|
||||
details::exchange_type type_;
|
||||
std::size_t colSize_; // size of the string column (used for strings)
|
||||
std::vector<ub2> sizes_; // sizes of data fetched (used for strings)
|
||||
|
||||
std::vector<ub2> rCodes_;
|
||||
};
|
||||
|
||||
struct oracle_standard_use_type_backend : details::standard_use_type_backend
|
||||
{
|
||||
oracle_standard_use_type_backend(oracle_statement_backend &st)
|
||||
: statement_(st), bindp_(NULL), indOCIHolder_(0),
|
||||
data_(NULL), buf_(NULL) {}
|
||||
|
||||
virtual void bind_by_pos(int &position,
|
||||
void *data, details::exchange_type type, bool readOnly);
|
||||
virtual void bind_by_name(std::string const &name,
|
||||
void *data, details::exchange_type type, bool readOnly);
|
||||
|
||||
// common part for bind_by_pos and bind_by_name
|
||||
void prepare_for_bind(void *&data, sb4 &size, ub2 &oracleType, bool readOnly);
|
||||
|
||||
virtual void pre_use(indicator const *ind);
|
||||
virtual void post_use(bool gotData, indicator *ind);
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
oracle_statement_backend &statement_;
|
||||
|
||||
OCIBind *bindp_;
|
||||
sb2 indOCIHolder_;
|
||||
void *data_;
|
||||
bool readOnly_;
|
||||
char *buf_; // generic buffer
|
||||
details::exchange_type type_;
|
||||
};
|
||||
|
||||
struct oracle_vector_use_type_backend : details::vector_use_type_backend
|
||||
{
|
||||
oracle_vector_use_type_backend(oracle_statement_backend &st)
|
||||
: statement_(st), bindp_(NULL), indOCIHolders_(NULL),
|
||||
data_(NULL), buf_(NULL) {}
|
||||
|
||||
virtual void bind_by_pos(int &position,
|
||||
void *data, details::exchange_type type);
|
||||
virtual void bind_by_name(std::string const &name,
|
||||
void *data, details::exchange_type type);
|
||||
|
||||
// common part for bind_by_pos and bind_by_name
|
||||
void prepare_for_bind(void *&data, sb4 &size, ub2 &oracleType);
|
||||
|
||||
// helper function for preparing indicators and sizes_ vectors
|
||||
// (as part of the bind_by_pos and bind_by_name)
|
||||
void prepare_indicators(std::size_t size);
|
||||
|
||||
virtual void pre_use(indicator const *ind);
|
||||
|
||||
virtual std::size_t size();
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
oracle_statement_backend &statement_;
|
||||
|
||||
OCIBind *bindp_;
|
||||
std::vector<sb2> indOCIHolderVec_;
|
||||
sb2 *indOCIHolders_;
|
||||
void *data_;
|
||||
char *buf_; // generic buffer
|
||||
details::exchange_type type_;
|
||||
|
||||
// used for strings only
|
||||
std::vector<ub2> sizes_;
|
||||
std::size_t maxSize_;
|
||||
};
|
||||
|
||||
struct oracle_session_backend;
|
||||
struct oracle_statement_backend : details::statement_backend
|
||||
{
|
||||
oracle_statement_backend(oracle_session_backend &session);
|
||||
|
||||
virtual void alloc();
|
||||
virtual void clean_up();
|
||||
virtual void prepare(std::string const &query,
|
||||
details::statement_type eType);
|
||||
|
||||
virtual exec_fetch_result execute(int number);
|
||||
virtual exec_fetch_result fetch(int number);
|
||||
|
||||
virtual long long get_affected_rows();
|
||||
virtual int get_number_of_rows();
|
||||
virtual std::string get_parameter_name(int index) const;
|
||||
|
||||
virtual std::string rewrite_for_procedure_call(std::string const &query);
|
||||
|
||||
virtual int prepare_for_describe();
|
||||
virtual void describe_column(int colNum, data_type &dtype,
|
||||
std::string &columnName);
|
||||
|
||||
// helper for defining into vector<string>
|
||||
std::size_t column_size(int position);
|
||||
|
||||
virtual oracle_standard_into_type_backend * make_into_type_backend();
|
||||
virtual oracle_standard_use_type_backend * make_use_type_backend();
|
||||
virtual oracle_vector_into_type_backend * make_vector_into_type_backend();
|
||||
virtual oracle_vector_use_type_backend * make_vector_use_type_backend();
|
||||
|
||||
oracle_session_backend &session_;
|
||||
|
||||
OCIStmt *stmtp_;
|
||||
|
||||
bool boundByName_;
|
||||
bool boundByPos_;
|
||||
bool noData_;
|
||||
};
|
||||
|
||||
struct oracle_rowid_backend : details::rowid_backend
|
||||
{
|
||||
oracle_rowid_backend(oracle_session_backend &session);
|
||||
|
||||
~oracle_rowid_backend();
|
||||
|
||||
OCIRowid *rowidp_;
|
||||
};
|
||||
|
||||
struct oracle_blob_backend : details::blob_backend
|
||||
{
|
||||
oracle_blob_backend(oracle_session_backend &session);
|
||||
|
||||
~oracle_blob_backend();
|
||||
|
||||
virtual std::size_t get_len();
|
||||
virtual std::size_t read(std::size_t offset, char *buf,
|
||||
std::size_t toRead);
|
||||
virtual std::size_t write(std::size_t offset, char const *buf,
|
||||
std::size_t toWrite);
|
||||
virtual std::size_t append(char const *buf, std::size_t toWrite);
|
||||
virtual void trim(std::size_t newLen);
|
||||
|
||||
oracle_session_backend &session_;
|
||||
|
||||
OCILobLocator *lobp_;
|
||||
};
|
||||
|
||||
struct oracle_session_backend : details::session_backend
|
||||
{
|
||||
oracle_session_backend(std::string const & serviceName,
|
||||
std::string const & userName,
|
||||
std::string const & password,
|
||||
int mode,
|
||||
bool decimals_as_strings = false);
|
||||
|
||||
~oracle_session_backend();
|
||||
|
||||
virtual void begin();
|
||||
virtual void commit();
|
||||
virtual void rollback();
|
||||
|
||||
virtual std::string get_backend_name() const { return "oracle"; }
|
||||
|
||||
void clean_up();
|
||||
|
||||
virtual oracle_statement_backend * make_statement_backend();
|
||||
virtual oracle_rowid_backend * make_rowid_backend();
|
||||
virtual oracle_blob_backend * make_blob_backend();
|
||||
|
||||
bool get_option_decimals_as_strings() { return decimals_as_strings_; }
|
||||
|
||||
// Return either SQLT_FLT or SQLT_BDOUBLE as the type to use when binding
|
||||
// values of C type "double" (the latter is preferable but might not be
|
||||
// always available).
|
||||
ub2 get_double_sql_type() const;
|
||||
|
||||
OCIEnv *envhp_;
|
||||
OCIServer *srvhp_;
|
||||
OCIError *errhp_;
|
||||
OCISvcCtx *svchp_;
|
||||
OCISession *usrhp_;
|
||||
bool decimals_as_strings_;
|
||||
};
|
||||
|
||||
struct oracle_backend_factory : backend_factory
|
||||
{
|
||||
oracle_backend_factory() {}
|
||||
virtual oracle_session_backend * make_session(
|
||||
connection_parameters const & parameters) const;
|
||||
};
|
||||
|
||||
extern SOCI_ORACLE_DECL oracle_backend_factory const oracle;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// for dynamic backend loading
|
||||
SOCI_ORACLE_DECL backend_factory const * factory_oracle();
|
||||
SOCI_ORACLE_DECL void register_factory_oracle();
|
||||
|
||||
} // extern "C"
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif
|
||||
352
src/soci/include/soci/postgresql/soci-postgresql.h
Normal file
352
src/soci/include/soci/postgresql/soci-postgresql.h
Normal file
@@ -0,0 +1,352 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Copyright (C) 2011 Gevorg Voskanyan
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_POSTGRESQL_H_INCLUDED
|
||||
#define SOCI_POSTGRESQL_H_INCLUDED
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef SOCI_DLL
|
||||
# ifdef SOCI_POSTGRESQL_SOURCE
|
||||
# define SOCI_POSTGRESQL_DECL __declspec(dllexport)
|
||||
# else
|
||||
# define SOCI_POSTGRESQL_DECL __declspec(dllimport)
|
||||
# endif // SOCI_POSTGRESQL_SOURCE
|
||||
# endif // SOCI_DLL
|
||||
#endif // _WIN32
|
||||
//
|
||||
// If SOCI_POSTGRESQL_DECL isn't defined yet define it now
|
||||
#ifndef SOCI_POSTGRESQL_DECL
|
||||
# define SOCI_POSTGRESQL_DECL
|
||||
#endif
|
||||
|
||||
#include <soci/soci-backend.h>
|
||||
#include <libpq-fe.h>
|
||||
#include <vector>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
class postgresql_soci_error : public soci_error
|
||||
{
|
||||
public:
|
||||
postgresql_soci_error(std::string const & msg, char const * sqlst);
|
||||
|
||||
std::string sqlstate() const;
|
||||
|
||||
private:
|
||||
char sqlstate_[ 5 ]; // not std::string to keep copy-constructor no-throw
|
||||
};
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
// A class thinly encapsulating PGresult. Its main purpose is to ensure that
|
||||
// PQclear() is always called, avoiding result memory leaks.
|
||||
class postgresql_result
|
||||
{
|
||||
public:
|
||||
// Creates a wrapper for the given, possibly NULL, result. The wrapper
|
||||
// object takes ownership of the object and will call PQclear() on it.
|
||||
explicit postgresql_result(PGresult* result = NULL)
|
||||
{
|
||||
init(result);
|
||||
}
|
||||
|
||||
// Frees any currently stored result pointer and takes ownership of the
|
||||
// given one.
|
||||
void reset(PGresult* result = NULL)
|
||||
{
|
||||
free();
|
||||
init(result);
|
||||
}
|
||||
|
||||
// Check whether the status is PGRES_COMMAND_OK and throw an exception if
|
||||
// it is different. Notice that if the query can return any results,
|
||||
// check_for_data() below should be used instead to verify whether anything
|
||||
// was returned or not.
|
||||
//
|
||||
// The provided error message is used only for the exception being thrown
|
||||
// and should describe the operation which yielded this result.
|
||||
void check_for_errors(char const* errMsg) const;
|
||||
|
||||
// Check whether the status indicates successful query completion, either
|
||||
// with the return results (in which case true is returned) or without them
|
||||
// (then false is returned). If the status corresponds to an error, throws
|
||||
// an exception, just as check_for_errors().
|
||||
bool check_for_data(char const* errMsg) const;
|
||||
|
||||
// Implicit conversion to const PGresult: this is somewhat dangerous but
|
||||
// allows us to avoid changing the existing code that uses PGresult and
|
||||
// avoids the really bad problem with calling PQclear() twice accidentally
|
||||
// as this would require a conversion to non-const pointer that we do not
|
||||
// provide.
|
||||
operator const PGresult*() const { return result_; }
|
||||
|
||||
// Get the associated result (which may be NULL). Unlike the implicit
|
||||
// conversion above, this one returns a non-const pointer, so you should be
|
||||
// careful to avoid really modifying it.
|
||||
PGresult* get_result() const { return result_; }
|
||||
|
||||
// Dtor frees the result.
|
||||
~postgresql_result() { free(); }
|
||||
|
||||
private:
|
||||
void init(PGresult* result)
|
||||
{
|
||||
result_ = result;
|
||||
}
|
||||
|
||||
void free()
|
||||
{
|
||||
// Notice that it is safe to call PQclear() with NULL pointer, it
|
||||
// simply does nothing in this case.
|
||||
PQclear(result_);
|
||||
}
|
||||
|
||||
PGresult* result_;
|
||||
|
||||
SOCI_NOT_COPYABLE(postgresql_result)
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
struct postgresql_statement_backend;
|
||||
struct postgresql_standard_into_type_backend : details::standard_into_type_backend
|
||||
{
|
||||
postgresql_standard_into_type_backend(postgresql_statement_backend & st)
|
||||
: statement_(st) {}
|
||||
|
||||
virtual void define_by_pos(int & position,
|
||||
void * data, details::exchange_type type);
|
||||
|
||||
virtual void pre_fetch();
|
||||
virtual void post_fetch(bool gotData, bool calledFromFetch,
|
||||
indicator * ind);
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
postgresql_statement_backend & statement_;
|
||||
|
||||
void * data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
};
|
||||
|
||||
struct postgresql_vector_into_type_backend : details::vector_into_type_backend
|
||||
{
|
||||
postgresql_vector_into_type_backend(postgresql_statement_backend & st)
|
||||
: statement_(st) {}
|
||||
|
||||
virtual void define_by_pos(int & position,
|
||||
void * data, details::exchange_type type);
|
||||
|
||||
virtual void pre_fetch();
|
||||
virtual void post_fetch(bool gotData, indicator * ind);
|
||||
|
||||
virtual void resize(std::size_t sz);
|
||||
virtual std::size_t size();
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
postgresql_statement_backend & statement_;
|
||||
|
||||
void * data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
};
|
||||
|
||||
struct postgresql_standard_use_type_backend : details::standard_use_type_backend
|
||||
{
|
||||
postgresql_standard_use_type_backend(postgresql_statement_backend & st)
|
||||
: statement_(st), position_(0), buf_(NULL) {}
|
||||
|
||||
virtual void bind_by_pos(int & position,
|
||||
void * data, details::exchange_type type, bool readOnly);
|
||||
virtual void bind_by_name(std::string const & name,
|
||||
void * data, details::exchange_type type, bool readOnly);
|
||||
|
||||
virtual void pre_use(indicator const * ind);
|
||||
virtual void post_use(bool gotData, indicator * ind);
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
postgresql_statement_backend & statement_;
|
||||
|
||||
void * data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
std::string name_;
|
||||
char * buf_;
|
||||
};
|
||||
|
||||
struct postgresql_vector_use_type_backend : details::vector_use_type_backend
|
||||
{
|
||||
postgresql_vector_use_type_backend(postgresql_statement_backend & st)
|
||||
: statement_(st), position_(0) {}
|
||||
|
||||
virtual void bind_by_pos(int & position,
|
||||
void * data, details::exchange_type type);
|
||||
virtual void bind_by_name(std::string const & name,
|
||||
void * data, details::exchange_type type);
|
||||
|
||||
virtual void pre_use(indicator const * ind);
|
||||
|
||||
virtual std::size_t size();
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
postgresql_statement_backend & statement_;
|
||||
|
||||
void * data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
std::string name_;
|
||||
std::vector<char *> buffers_;
|
||||
};
|
||||
|
||||
struct postgresql_session_backend;
|
||||
struct postgresql_statement_backend : details::statement_backend
|
||||
{
|
||||
postgresql_statement_backend(postgresql_session_backend & session);
|
||||
~postgresql_statement_backend();
|
||||
|
||||
virtual void alloc();
|
||||
virtual void clean_up();
|
||||
virtual void prepare(std::string const & query,
|
||||
details::statement_type stType);
|
||||
|
||||
virtual exec_fetch_result execute(int number);
|
||||
virtual exec_fetch_result fetch(int number);
|
||||
|
||||
virtual long long get_affected_rows();
|
||||
virtual int get_number_of_rows();
|
||||
virtual std::string get_parameter_name(int index) const;
|
||||
|
||||
virtual std::string rewrite_for_procedure_call(std::string const & query);
|
||||
|
||||
virtual int prepare_for_describe();
|
||||
virtual void describe_column(int colNum, data_type & dtype,
|
||||
std::string & columnName);
|
||||
|
||||
virtual postgresql_standard_into_type_backend * make_into_type_backend();
|
||||
virtual postgresql_standard_use_type_backend * make_use_type_backend();
|
||||
virtual postgresql_vector_into_type_backend * make_vector_into_type_backend();
|
||||
virtual postgresql_vector_use_type_backend * make_vector_use_type_backend();
|
||||
|
||||
postgresql_session_backend & session_;
|
||||
|
||||
details::postgresql_result result_;
|
||||
std::string query_;
|
||||
details::statement_type stType_;
|
||||
std::string statementName_;
|
||||
std::vector<std::string> names_; // list of names for named binds
|
||||
|
||||
long long rowsAffectedBulk_; // number of rows affected by the last bulk operation
|
||||
|
||||
int numberOfRows_; // number of rows retrieved from the server
|
||||
int currentRow_; // "current" row number to consume in postFetch
|
||||
int rowsToConsume_; // number of rows to be consumed in postFetch
|
||||
|
||||
bool justDescribed_; // to optimize row description with immediately
|
||||
// following actual statement execution
|
||||
|
||||
bool hasIntoElements_;
|
||||
bool hasVectorIntoElements_;
|
||||
bool hasUseElements_;
|
||||
bool hasVectorUseElements_;
|
||||
|
||||
// the following maps are used for finding data buffers according to
|
||||
// use elements specified by the user
|
||||
|
||||
typedef std::map<int, char **> UseByPosBuffersMap;
|
||||
UseByPosBuffersMap useByPosBuffers_;
|
||||
|
||||
typedef std::map<std::string, char **> UseByNameBuffersMap;
|
||||
UseByNameBuffersMap useByNameBuffers_;
|
||||
};
|
||||
|
||||
struct postgresql_rowid_backend : details::rowid_backend
|
||||
{
|
||||
postgresql_rowid_backend(postgresql_session_backend & session);
|
||||
|
||||
~postgresql_rowid_backend();
|
||||
|
||||
unsigned long value_;
|
||||
};
|
||||
|
||||
struct postgresql_blob_backend : details::blob_backend
|
||||
{
|
||||
postgresql_blob_backend(postgresql_session_backend & session);
|
||||
|
||||
~postgresql_blob_backend();
|
||||
|
||||
virtual std::size_t get_len();
|
||||
virtual std::size_t read(std::size_t offset, char * buf,
|
||||
std::size_t toRead);
|
||||
virtual std::size_t write(std::size_t offset, char const * buf,
|
||||
std::size_t toWrite);
|
||||
virtual std::size_t append(char const * buf, std::size_t toWrite);
|
||||
virtual void trim(std::size_t newLen);
|
||||
|
||||
postgresql_session_backend & session_;
|
||||
|
||||
unsigned long oid_; // oid of the large object
|
||||
int fd_; // descriptor of the large object
|
||||
};
|
||||
|
||||
struct postgresql_session_backend : details::session_backend
|
||||
{
|
||||
postgresql_session_backend(connection_parameters const & parameters);
|
||||
|
||||
~postgresql_session_backend();
|
||||
|
||||
virtual void begin();
|
||||
virtual void commit();
|
||||
virtual void rollback();
|
||||
|
||||
void deallocate_prepared_statement(const std::string & statementName);
|
||||
|
||||
virtual bool get_next_sequence_value(session & s,
|
||||
std::string const & sequence, long & value);
|
||||
|
||||
virtual std::string get_backend_name() const { return "postgresql"; }
|
||||
|
||||
void clean_up();
|
||||
|
||||
virtual postgresql_statement_backend * make_statement_backend();
|
||||
virtual postgresql_rowid_backend * make_rowid_backend();
|
||||
virtual postgresql_blob_backend * make_blob_backend();
|
||||
|
||||
std::string get_next_statement_name();
|
||||
|
||||
int statementCount_;
|
||||
PGconn * conn_;
|
||||
};
|
||||
|
||||
|
||||
struct postgresql_backend_factory : backend_factory
|
||||
{
|
||||
postgresql_backend_factory() {}
|
||||
virtual postgresql_session_backend * make_session(
|
||||
connection_parameters const & parameters) const;
|
||||
};
|
||||
|
||||
extern SOCI_POSTGRESQL_DECL postgresql_backend_factory const postgresql;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// for dynamic backend loading
|
||||
SOCI_POSTGRESQL_DECL backend_factory const * factory_postgresql();
|
||||
SOCI_POSTGRESQL_DECL void register_factory_postgresql();
|
||||
|
||||
} // extern "C"
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_POSTGRESQL_H_INCLUDED
|
||||
65
src/soci/include/soci/prepare-temp-type.h
Normal file
65
src/soci/include/soci/prepare-temp-type.h
Normal file
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_PREPARE_TEMP_TYPE_INCLUDED
|
||||
#define SOCI_PREPARE_TEMP_TYPE_INCLUDED
|
||||
|
||||
#include "soci/into-type.h"
|
||||
#include "soci/use-type.h"
|
||||
#include "soci/use.h"
|
||||
#include "soci/ref-counted-prepare-info.h"
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
// this needs to be lightweight and copyable
|
||||
class SOCI_DECL prepare_temp_type
|
||||
{
|
||||
public:
|
||||
prepare_temp_type(session &);
|
||||
prepare_temp_type(prepare_temp_type const &);
|
||||
prepare_temp_type & operator=(prepare_temp_type const &);
|
||||
|
||||
~prepare_temp_type();
|
||||
|
||||
template <typename T>
|
||||
prepare_temp_type & operator<<(T const & t)
|
||||
{
|
||||
rcpi_->accumulate(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
prepare_temp_type & operator,(into_type_ptr const & i);
|
||||
|
||||
template <typename T, typename Indicator>
|
||||
prepare_temp_type &operator,(into_container<T, Indicator> const &ic)
|
||||
{
|
||||
rcpi_->exchange(ic);
|
||||
return *this;
|
||||
}
|
||||
template <typename T, typename Indicator>
|
||||
prepare_temp_type &operator,(use_container<T, Indicator> const &uc)
|
||||
{
|
||||
rcpi_->exchange(uc);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ref_counted_prepare_info * get_prepare_info() const { return rcpi_; }
|
||||
|
||||
|
||||
private:
|
||||
ref_counted_prepare_info * rcpi_;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif
|
||||
89
src/soci/include/soci/procedure.h
Normal file
89
src/soci/include/soci/procedure.h
Normal file
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_PROCEDURE_H_INCLUDED
|
||||
#define SOCI_PROCEDURE_H_INCLUDED
|
||||
|
||||
#include "soci/statement.h"
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
class SOCI_DECL procedure_impl : public statement_impl
|
||||
{
|
||||
public:
|
||||
procedure_impl(session & s) : statement_impl(s), refCount_(1) {}
|
||||
procedure_impl(prepare_temp_type const & prep);
|
||||
|
||||
void inc_ref() { ++refCount_; }
|
||||
void dec_ref()
|
||||
{
|
||||
if (--refCount_ == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int refCount_;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
class SOCI_DECL procedure
|
||||
{
|
||||
public:
|
||||
// this is a conversion constructor
|
||||
procedure(details::prepare_temp_type const & prep)
|
||||
: impl_(new details::procedure_impl(prep)) {}
|
||||
|
||||
~procedure() { impl_->dec_ref(); }
|
||||
|
||||
// copy is supported here
|
||||
procedure(procedure const & other)
|
||||
: impl_(other.impl_)
|
||||
{
|
||||
impl_->inc_ref();
|
||||
}
|
||||
void operator=(procedure const & other)
|
||||
{
|
||||
other.impl_->inc_ref();
|
||||
impl_->dec_ref();
|
||||
impl_ = other.impl_;
|
||||
}
|
||||
|
||||
// forwarders to procedure_impl
|
||||
// (or rather to its base interface from statement_impl)
|
||||
|
||||
bool execute(bool withDataExchange = false)
|
||||
{
|
||||
gotData_ = impl_->execute(withDataExchange);
|
||||
return gotData_;
|
||||
}
|
||||
|
||||
bool fetch()
|
||||
{
|
||||
gotData_ = impl_->fetch();
|
||||
return gotData_;
|
||||
}
|
||||
|
||||
bool got_data() const
|
||||
{
|
||||
return gotData_;
|
||||
}
|
||||
|
||||
private:
|
||||
details::procedure_impl * impl_;
|
||||
bool gotData_;
|
||||
};
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif
|
||||
59
src/soci/include/soci/query_transformation.h
Normal file
59
src/soci/include/soci/query_transformation.h
Normal file
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// Copyright (C) 2013 Mateusz Loskot <mateusz@loskot.net>
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_QUERY_TRANSFORMATION_H_INCLUDED
|
||||
#define SOCI_QUERY_TRANSFORMATION_H_INCLUDED
|
||||
|
||||
#include "soci/soci-platform.h"
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
// Query transformation is a mechanism that enables user to apply
|
||||
// any string-to-string transformation to SQL statement just
|
||||
// before it is executed.
|
||||
// Transformation procedure is specified by user,
|
||||
// be it a function or an arbitrary type as long as it
|
||||
// defines operator() with the appropriate signature:
|
||||
// unary function takes any type converible-to std::string
|
||||
// and returns std::string.
|
||||
|
||||
class query_transformation_function
|
||||
: public std::unary_function<std::string const&, std::string>
|
||||
{
|
||||
public:
|
||||
virtual ~query_transformation_function() {}
|
||||
virtual result_type operator()(argument_type a) const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class query_transformation : public query_transformation_function
|
||||
{
|
||||
public:
|
||||
query_transformation(T callback)
|
||||
: callback_(callback)
|
||||
{}
|
||||
|
||||
result_type operator()(argument_type query) const
|
||||
{
|
||||
return callback_(query);
|
||||
}
|
||||
|
||||
private:
|
||||
T callback_;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_QUERY_TRANSFORMATION_H_INCLUDED
|
||||
66
src/soci/include/soci/ref-counted-prepare-info.h
Normal file
66
src/soci/include/soci/ref-counted-prepare-info.h
Normal file
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_REF_COUNTED_PREPARE_INFO_INCLUDED
|
||||
#define SOCI_REF_COUNTED_PREPARE_INFO_INCLUDED
|
||||
|
||||
#include "soci/bind-values.h"
|
||||
#include "soci/ref-counted-statement.h"
|
||||
// std
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
class session;
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
class procedure_impl;
|
||||
class statement_impl;
|
||||
class into_type_base;
|
||||
|
||||
// this class conveys only the statement text and the bind/define info
|
||||
// it exists only to be passed to statement's constructor
|
||||
class ref_counted_prepare_info : public ref_counted_statement_base
|
||||
{
|
||||
public:
|
||||
ref_counted_prepare_info(session& s)
|
||||
: ref_counted_statement_base(s)
|
||||
{}
|
||||
|
||||
void exchange(use_type_ptr const& u) { uses_.exchange(u); }
|
||||
|
||||
template <typename T, typename Indicator>
|
||||
void exchange(use_container<T, Indicator> const &uc)
|
||||
{ uses_.exchange(uc); }
|
||||
|
||||
void exchange(into_type_ptr const& i) { intos_.exchange(i); }
|
||||
|
||||
template <typename T, typename Indicator>
|
||||
void exchange(into_container<T, Indicator> const &ic)
|
||||
{ intos_.exchange(ic); }
|
||||
|
||||
void final_action();
|
||||
|
||||
private:
|
||||
friend class statement_impl;
|
||||
friend class procedure_impl;
|
||||
|
||||
into_type_vector intos_;
|
||||
use_type_vector uses_;
|
||||
|
||||
std::string get_query() const;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif
|
||||
89
src/soci/include/soci/ref-counted-statement.h
Normal file
89
src/soci/include/soci/ref-counted-statement.h
Normal file
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_REF_COUNTED_STATEMENT_H_INCLUDED
|
||||
#define SOCI_REF_COUNTED_STATEMENT_H_INCLUDED
|
||||
|
||||
#include "soci/statement.h"
|
||||
#include "soci/into-type.h"
|
||||
#include "soci/use-type.h"
|
||||
// std
|
||||
#include <sstream>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
// this class is a base for both "once" and "prepare" statements
|
||||
class SOCI_DECL ref_counted_statement_base
|
||||
{
|
||||
public:
|
||||
ref_counted_statement_base(session& s);
|
||||
|
||||
virtual ~ref_counted_statement_base() {}
|
||||
|
||||
virtual void final_action() = 0;
|
||||
|
||||
void inc_ref() { ++refCount_; }
|
||||
void dec_ref()
|
||||
{
|
||||
if (--refCount_ == 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
final_action();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete this;
|
||||
throw;
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void accumulate(T const & t) { get_query_stream() << t; }
|
||||
|
||||
protected:
|
||||
// this function allows to break the circular dependenc
|
||||
// between session and this class
|
||||
std::ostringstream & get_query_stream();
|
||||
|
||||
int refCount_;
|
||||
|
||||
session & session_;
|
||||
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(ref_counted_statement_base)
|
||||
};
|
||||
|
||||
// this class is supposed to be a vehicle for the "once" statements
|
||||
// it executes the whole statement in its destructor
|
||||
class ref_counted_statement : public ref_counted_statement_base
|
||||
{
|
||||
public:
|
||||
ref_counted_statement(session & s)
|
||||
: ref_counted_statement_base(s), st_(s) {}
|
||||
|
||||
virtual void final_action();
|
||||
|
||||
template <typename T>
|
||||
void exchange(T &t) { st_.exchange(t); }
|
||||
|
||||
private:
|
||||
statement st_;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif
|
||||
79
src/soci/include/soci/row-exchange.h
Normal file
79
src/soci/include/soci/row-exchange.h
Normal file
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_INTO_ROW_H_INCLUDED
|
||||
#define SOCI_INTO_ROW_H_INCLUDED
|
||||
|
||||
#include "soci/into-type.h"
|
||||
#include "soci/exchange-traits.h"
|
||||
#include "soci/row.h"
|
||||
#include "soci/statement.h"
|
||||
// std
|
||||
#include <cstddef>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
// Support selecting into a row for dynamic queries
|
||||
|
||||
template <>
|
||||
class into_type<row>
|
||||
: public into_type_base // bypass the standard_into_type
|
||||
{
|
||||
public:
|
||||
into_type(row & r) : r_(r) {}
|
||||
into_type(row & r, indicator &) : r_(r) {}
|
||||
|
||||
private:
|
||||
// special handling for Row
|
||||
virtual void define(statement_impl & st, int & /* position */)
|
||||
{
|
||||
st.set_row(&r_);
|
||||
|
||||
// actual row description is performed
|
||||
// as part of the statement execute
|
||||
}
|
||||
|
||||
virtual void pre_fetch() {}
|
||||
virtual void post_fetch(bool gotData, bool /* calledFromFetch */)
|
||||
{
|
||||
r_.reset_get_counter();
|
||||
|
||||
if (gotData)
|
||||
{
|
||||
// this is used only to re-dispatch to derived class, if any
|
||||
// (the derived class might be generated automatically by
|
||||
// user conversions)
|
||||
convert_from_base();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void clean_up() {}
|
||||
|
||||
virtual std::size_t size() const { return 1; }
|
||||
|
||||
virtual void convert_from_base() {}
|
||||
|
||||
row & r_;
|
||||
|
||||
SOCI_NOT_COPYABLE(into_type)
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_traits<row>
|
||||
{
|
||||
typedef basic_type_tag type_family;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif
|
||||
140
src/soci/include/soci/row.h
Normal file
140
src/soci/include/soci/row.h
Normal file
@@ -0,0 +1,140 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_ROW_H_INCLUDED
|
||||
#define SOCI_ROW_H_INCLUDED
|
||||
|
||||
#include "soci/type-holder.h"
|
||||
#include "soci/soci-backend.h"
|
||||
#include "soci/type-conversion.h"
|
||||
// std
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
class SOCI_DECL column_properties
|
||||
{
|
||||
// use getters/setters in case we want to make some
|
||||
// of the getters lazy in the future
|
||||
public:
|
||||
|
||||
std::string get_name() const { return name_; }
|
||||
data_type get_data_type() const { return dataType_; }
|
||||
|
||||
void set_name(std::string const& name) { name_ = name; }
|
||||
void set_data_type(data_type dataType) { dataType_ = dataType; }
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
data_type dataType_;
|
||||
};
|
||||
|
||||
class SOCI_DECL row
|
||||
{
|
||||
public:
|
||||
row();
|
||||
~row();
|
||||
|
||||
void uppercase_column_names(bool forceToUpper);
|
||||
void add_properties(column_properties const& cp);
|
||||
std::size_t size() const;
|
||||
void clean_up();
|
||||
|
||||
indicator get_indicator(std::size_t pos) const;
|
||||
indicator get_indicator(std::string const& name) const;
|
||||
|
||||
template <typename T>
|
||||
inline void add_holder(T* t, indicator* ind)
|
||||
{
|
||||
holders_.push_back(new details::type_holder<T>(t));
|
||||
indicators_.push_back(ind);
|
||||
}
|
||||
|
||||
column_properties const& get_properties(std::size_t pos) const;
|
||||
column_properties const& get_properties(std::string const& name) const;
|
||||
|
||||
template <typename T>
|
||||
T get(std::size_t pos) const
|
||||
{
|
||||
typedef typename type_conversion<T>::base_type base_type;
|
||||
base_type const& baseVal = holders_.at(pos)->get<base_type>();
|
||||
|
||||
T ret;
|
||||
type_conversion<T>::from_base(baseVal, *indicators_.at(pos), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get(std::size_t pos, T const &nullValue) const
|
||||
{
|
||||
if (i_null == *indicators_.at(pos))
|
||||
{
|
||||
return nullValue;
|
||||
}
|
||||
|
||||
return get<T>(pos);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get(std::string const &name) const
|
||||
{
|
||||
std::size_t const pos = find_column(name);
|
||||
return get<T>(pos);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get(std::string const &name, T const &nullValue) const
|
||||
{
|
||||
std::size_t const pos = find_column(name);
|
||||
|
||||
if (i_null == *indicators_[pos])
|
||||
{
|
||||
return nullValue;
|
||||
}
|
||||
|
||||
return get<T>(pos);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
row const& operator>>(T& value) const
|
||||
{
|
||||
value = get<T>(currentPos_);
|
||||
++currentPos_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void skip(std::size_t num = 1) const
|
||||
{
|
||||
currentPos_ += num;
|
||||
}
|
||||
|
||||
void reset_get_counter() const
|
||||
{
|
||||
currentPos_ = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(row)
|
||||
|
||||
std::size_t find_column(std::string const& name) const;
|
||||
|
||||
std::vector<column_properties> columns_;
|
||||
std::vector<details::holder*> holders_;
|
||||
std::vector<indicator*> indicators_;
|
||||
std::map<std::string, std::size_t> index_;
|
||||
|
||||
bool uppercaseColumnNames_;
|
||||
mutable std::size_t currentPos_;
|
||||
};
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_ROW_H_INCLUDED
|
||||
59
src/soci/include/soci/rowid-exchange.h
Normal file
59
src/soci/include/soci/rowid-exchange.h
Normal file
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_ROWID_EXCHANGE_H_INCLUDED
|
||||
#define SOCI_ROWID_EXCHANGE_H_INCLUDED
|
||||
|
||||
#include "soci/rowid.h"
|
||||
#include "soci/into-type.h"
|
||||
#include "soci/use-type.h"
|
||||
#include "soci/exchange-traits.h"
|
||||
// std
|
||||
#include <string>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
template <>
|
||||
class use_type<rowid> : public standard_use_type
|
||||
{
|
||||
public:
|
||||
use_type(rowid & rid, std::string const & name = std::string())
|
||||
: standard_use_type(&rid, x_rowid, false, name) {}
|
||||
use_type(rowid const & rid, std::string const & name = std::string())
|
||||
: standard_use_type(const_cast<rowid *>(&rid), x_rowid, true, name) {}
|
||||
use_type(rowid & rid, indicator & ind,
|
||||
std::string const & name = std::string())
|
||||
: standard_use_type(&rid, x_rowid, ind, false, name) {}
|
||||
use_type(rowid const & rid, indicator & ind,
|
||||
std::string const & name = std::string())
|
||||
: standard_use_type(const_cast<rowid *>(&rid), x_rowid, ind, true, name) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
class into_type<rowid> : public standard_into_type
|
||||
{
|
||||
public:
|
||||
into_type(rowid & rid) : standard_into_type(&rid, x_rowid) {}
|
||||
into_type(rowid & rid, indicator & ind)
|
||||
:standard_into_type(&rid, x_rowid, ind) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct exchange_traits<soci::rowid>
|
||||
{
|
||||
typedef basic_type_tag type_family;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_ROWID_EXCHANGE_H_INCLUDED
|
||||
41
src/soci/include/soci/rowid.h
Normal file
41
src/soci/include/soci/rowid.h
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_ROWID_H_INCLUDED
|
||||
#define SOCI_ROWID_H_INCLUDED
|
||||
|
||||
#include "soci/soci-platform.h"
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
class session;
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
class rowid_backend;
|
||||
|
||||
} // namespace details
|
||||
|
||||
// ROWID support
|
||||
|
||||
class SOCI_DECL rowid
|
||||
{
|
||||
public:
|
||||
explicit rowid(session & s);
|
||||
~rowid();
|
||||
|
||||
details::rowid_backend * get_backend() { return backEnd_; }
|
||||
|
||||
private:
|
||||
details::rowid_backend *backEnd_;
|
||||
};
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif
|
||||
224
src/soci/include/soci/rowset.h
Normal file
224
src/soci/include/soci/rowset.h
Normal file
@@ -0,0 +1,224 @@
|
||||
//
|
||||
// Copyright (C) 2006-2008 Mateusz Loskot
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_ROWSET_H_INCLUDED
|
||||
#define SOCI_ROWSET_H_INCLUDED
|
||||
|
||||
#include "soci/statement.h"
|
||||
// std
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
//
|
||||
// rowset iterator of input category.
|
||||
//
|
||||
template <typename T>
|
||||
class rowset_iterator
|
||||
{
|
||||
public:
|
||||
|
||||
// Standard iterator traits
|
||||
|
||||
typedef std::input_iterator_tag iterator_category;
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
typedef T & reference;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
// Constructors
|
||||
|
||||
rowset_iterator()
|
||||
: st_(0), define_(0)
|
||||
{}
|
||||
|
||||
rowset_iterator(statement & st, T & define)
|
||||
: st_(&st), define_(&define)
|
||||
{
|
||||
// Fetch first row to properly initialize iterator
|
||||
++(*this);
|
||||
}
|
||||
|
||||
// Access operators
|
||||
|
||||
reference operator*() const
|
||||
{
|
||||
return (*define_);
|
||||
}
|
||||
|
||||
pointer operator->() const
|
||||
{
|
||||
return &(operator*());
|
||||
}
|
||||
|
||||
// Iteration operators
|
||||
|
||||
rowset_iterator & operator++()
|
||||
{
|
||||
// Fetch next row from dataset
|
||||
|
||||
if (st_->fetch() == false)
|
||||
{
|
||||
// Set iterator to non-derefencable state (pass-the-end)
|
||||
st_ = 0;
|
||||
define_ = 0;
|
||||
}
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
rowset_iterator operator++(int)
|
||||
{
|
||||
rowset_iterator tmp(*this);
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Comparison operators
|
||||
|
||||
bool operator==(rowset_iterator const & rhs) const
|
||||
{
|
||||
return (st_== rhs.st_ && define_ == rhs.define_);
|
||||
}
|
||||
|
||||
bool operator!=(rowset_iterator const & rhs) const
|
||||
{
|
||||
return ((*this == rhs) == false);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
statement * st_;
|
||||
T * define_;
|
||||
|
||||
}; // class rowset_iterator
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
//
|
||||
// Implementation of rowset
|
||||
//
|
||||
template <typename T>
|
||||
class rowset_impl
|
||||
{
|
||||
public:
|
||||
|
||||
typedef rowset_iterator<T> iterator;
|
||||
|
||||
rowset_impl(details::prepare_temp_type const & prep)
|
||||
: refs_(1), st_(new statement(prep)), define_(new T())
|
||||
{
|
||||
st_->exchange_for_rowset(into(*define_));
|
||||
st_->execute();
|
||||
}
|
||||
|
||||
void incRef()
|
||||
{
|
||||
++refs_;
|
||||
}
|
||||
|
||||
void decRef()
|
||||
{
|
||||
if (--refs_ == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
iterator begin() const
|
||||
{
|
||||
// No ownership transfer occurs here
|
||||
return iterator(*st_, *define_);
|
||||
}
|
||||
|
||||
iterator end() const
|
||||
{
|
||||
return iterator();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
unsigned int refs_;
|
||||
|
||||
#ifdef SOCI_CXX_C11
|
||||
const std::unique_ptr<statement> st_;
|
||||
const std::unique_ptr<T> define_;
|
||||
#else
|
||||
const std::auto_ptr<statement> st_;
|
||||
const std::auto_ptr<T> define_;
|
||||
#endif
|
||||
SOCI_NOT_COPYABLE(rowset_impl)
|
||||
}; // class rowset_impl
|
||||
|
||||
} // namespace details
|
||||
|
||||
|
||||
//
|
||||
// rowset is a thin wrapper on statement and provides access to STL-like input iterator.
|
||||
// The rowset_iterator can be used to easily loop through statement results and
|
||||
// use STL algorithms accepting input iterators.
|
||||
//
|
||||
template <typename T = soci::row>
|
||||
class rowset
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef rowset_iterator<T> iterator;
|
||||
typedef rowset_iterator<T> const_iterator;
|
||||
|
||||
// this is a conversion constructor
|
||||
rowset(details::prepare_temp_type const& prep)
|
||||
: pimpl_(new details::rowset_impl<T>(prep))
|
||||
{
|
||||
}
|
||||
|
||||
rowset(rowset const & other)
|
||||
: pimpl_(other.pimpl_)
|
||||
{
|
||||
pimpl_->incRef();
|
||||
}
|
||||
|
||||
~rowset()
|
||||
{
|
||||
pimpl_->decRef();
|
||||
}
|
||||
|
||||
rowset& operator=(rowset const& rhs)
|
||||
{
|
||||
if (&rhs != this)
|
||||
{
|
||||
rhs.pimpl_->incRef();
|
||||
pimpl_->decRef();
|
||||
pimpl_ = rhs.pimpl_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return pimpl_->begin();
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return pimpl_->end();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Pointer to implementation - the body
|
||||
details::rowset_impl<T>* pimpl_;
|
||||
|
||||
}; // class rowset
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_ROWSET_H_INCLUDED
|
||||
158
src/soci/include/soci/session.h
Normal file
158
src/soci/include/soci/session.h
Normal file
@@ -0,0 +1,158 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_SESSION_H_INCLUDED
|
||||
#define SOCI_SESSION_H_INCLUDED
|
||||
|
||||
#include "soci/once-temp-type.h"
|
||||
#include "soci/query_transformation.h"
|
||||
#include "soci/connection-parameters.h"
|
||||
|
||||
// std
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
class values;
|
||||
class backend_factory;
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
class session_backend;
|
||||
class statement_backend;
|
||||
class rowid_backend;
|
||||
class blob_backend;
|
||||
|
||||
} // namespace details
|
||||
|
||||
class connection_pool;
|
||||
|
||||
class SOCI_DECL session
|
||||
{
|
||||
private:
|
||||
|
||||
#ifdef SOCI_CXX_C11
|
||||
void set_query_transformation_(std::unique_ptr<details::query_transformation_function> & qtf);
|
||||
#else
|
||||
void set_query_transformation_(std::auto_ptr<details::query_transformation_function> qtf);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
public:
|
||||
session();
|
||||
explicit session(connection_parameters const & parameters);
|
||||
session(backend_factory const & factory, std::string const & connectString);
|
||||
session(std::string const & backendName, std::string const & connectString);
|
||||
explicit session(std::string const & connectString);
|
||||
explicit session(connection_pool & pool);
|
||||
|
||||
~session();
|
||||
|
||||
void open(connection_parameters const & parameters);
|
||||
void open(backend_factory const & factory, std::string const & connectString);
|
||||
void open(std::string const & backendName, std::string const & connectString);
|
||||
void open(std::string const & connectString);
|
||||
void close();
|
||||
void reconnect();
|
||||
|
||||
void begin();
|
||||
void commit();
|
||||
void rollback();
|
||||
|
||||
// once and prepare are for syntax sugar only
|
||||
details::once_type once;
|
||||
details::prepare_type prepare;
|
||||
|
||||
// even more sugar
|
||||
template <typename T>
|
||||
details::once_temp_type operator<<(T const & t) { return once << t; }
|
||||
|
||||
std::ostringstream & get_query_stream();
|
||||
std::string get_query() const;
|
||||
|
||||
template <typename T>
|
||||
void set_query_transformation(T callback)
|
||||
{
|
||||
|
||||
#ifdef SOCI_CXX_C11
|
||||
std::unique_ptr<details::query_transformation_function> qtf(new details::query_transformation<T>(callback));
|
||||
#else
|
||||
std::auto_ptr<details::query_transformation_function> qtf(new details::query_transformation<T>(callback));
|
||||
#endif
|
||||
set_query_transformation_(qtf);
|
||||
}
|
||||
|
||||
// support for basic logging
|
||||
void set_log_stream(std::ostream * s);
|
||||
std::ostream * get_log_stream() const;
|
||||
|
||||
void log_query(std::string const & query);
|
||||
std::string get_last_query() const;
|
||||
|
||||
void set_got_data(bool gotData);
|
||||
bool got_data() const;
|
||||
|
||||
void uppercase_column_names(bool forceToUpper);
|
||||
|
||||
bool get_uppercase_column_names() const;
|
||||
|
||||
// Functions for dealing with sequence/auto-increment values.
|
||||
|
||||
// If true is returned, value is filled with the next value from the given
|
||||
// sequence. Otherwise either the sequence is invalid (doesn't exist) or
|
||||
// the current backend doesn't support sequences. If you use sequences for
|
||||
// automatically generating primary key values, you should use
|
||||
// get_last_insert_id() after the insertion in this case.
|
||||
bool get_next_sequence_value(std::string const & sequence, long & value);
|
||||
|
||||
// If true is returned, value is filled with the last auto-generated value
|
||||
// for this table (although some backends ignore the table argument and
|
||||
// return the last value auto-generated in this session).
|
||||
bool get_last_insert_id(std::string const & table, long & value);
|
||||
|
||||
|
||||
// for diagnostics and advanced users
|
||||
// (downcast it to expected back-end session class)
|
||||
details::session_backend * get_backend() { return backEnd_; }
|
||||
|
||||
std::string get_backend_name() const;
|
||||
|
||||
details::statement_backend * make_statement_backend();
|
||||
details::rowid_backend * make_rowid_backend();
|
||||
details::blob_backend * make_blob_backend();
|
||||
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(session)
|
||||
|
||||
std::ostringstream query_stream_;
|
||||
details::query_transformation_function* query_transformation_;
|
||||
|
||||
std::ostream * logStream_;
|
||||
std::string lastQuery_;
|
||||
|
||||
connection_parameters lastConnectParameters_;
|
||||
|
||||
bool uppercaseColumnNames_;
|
||||
|
||||
details::session_backend * backEnd_;
|
||||
|
||||
bool gotData_;
|
||||
|
||||
bool isFromPool_;
|
||||
std::size_t poolPosition_;
|
||||
connection_pool * pool_;
|
||||
};
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_SESSION_H_INCLUDED
|
||||
265
src/soci/include/soci/soci-backend.h
Normal file
265
src/soci/include/soci/soci-backend.h
Normal file
@@ -0,0 +1,265 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_BACKEND_H_INCLUDED
|
||||
#define SOCI_BACKEND_H_INCLUDED
|
||||
|
||||
#include "soci/soci-platform.h"
|
||||
#include "soci/error.h"
|
||||
// std
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
// data types, as seen by the user
|
||||
enum data_type
|
||||
{
|
||||
dt_string, dt_date, dt_double, dt_integer, dt_long_long, dt_unsigned_long_long, dt_blob
|
||||
};
|
||||
|
||||
// the enum type for indicator variables
|
||||
enum indicator { i_ok, i_null, i_truncated };
|
||||
|
||||
class session;
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
// data types, as used to describe exchange format
|
||||
enum exchange_type
|
||||
{
|
||||
x_char,
|
||||
x_stdstring,
|
||||
x_short,
|
||||
x_integer,
|
||||
x_long_long,
|
||||
x_unsigned_long_long,
|
||||
x_double,
|
||||
x_stdtm,
|
||||
x_statement,
|
||||
x_rowid,
|
||||
x_blob
|
||||
};
|
||||
|
||||
// type of statement (used for optimizing statement preparation)
|
||||
enum statement_type
|
||||
{
|
||||
st_one_time_query,
|
||||
st_repeatable_query
|
||||
};
|
||||
|
||||
// polymorphic into type backend
|
||||
|
||||
class standard_into_type_backend
|
||||
{
|
||||
public:
|
||||
standard_into_type_backend() {}
|
||||
virtual ~standard_into_type_backend() {}
|
||||
|
||||
virtual void define_by_pos(int& position, void* data, exchange_type type) = 0;
|
||||
|
||||
virtual void pre_fetch() = 0;
|
||||
virtual void post_fetch(bool gotData, bool calledFromFetch, indicator* ind) = 0;
|
||||
|
||||
virtual void clean_up() = 0;
|
||||
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(standard_into_type_backend)
|
||||
};
|
||||
|
||||
class vector_into_type_backend
|
||||
{
|
||||
public:
|
||||
|
||||
vector_into_type_backend() {}
|
||||
virtual ~vector_into_type_backend() {}
|
||||
|
||||
virtual void define_by_pos(int& position, void* data, exchange_type type) = 0;
|
||||
|
||||
virtual void pre_fetch() = 0;
|
||||
virtual void post_fetch(bool gotData, indicator* ind) = 0;
|
||||
|
||||
virtual void resize(std::size_t sz) = 0;
|
||||
virtual std::size_t size() = 0;
|
||||
|
||||
virtual void clean_up() = 0;
|
||||
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(vector_into_type_backend)
|
||||
};
|
||||
|
||||
// polymorphic use type backend
|
||||
|
||||
class standard_use_type_backend
|
||||
{
|
||||
public:
|
||||
standard_use_type_backend() {}
|
||||
virtual ~standard_use_type_backend() {}
|
||||
|
||||
virtual void bind_by_pos(int& position, void* data,
|
||||
exchange_type type, bool readOnly) = 0;
|
||||
virtual void bind_by_name(std::string const& name,
|
||||
void* data, exchange_type type, bool readOnly) = 0;
|
||||
|
||||
virtual void pre_use(indicator const* ind) = 0;
|
||||
virtual void post_use(bool gotData, indicator * ind) = 0;
|
||||
|
||||
virtual void clean_up() = 0;
|
||||
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(standard_use_type_backend)
|
||||
};
|
||||
|
||||
class vector_use_type_backend
|
||||
{
|
||||
public:
|
||||
vector_use_type_backend() {}
|
||||
virtual ~vector_use_type_backend() {}
|
||||
|
||||
virtual void bind_by_pos(int& position, void* data, exchange_type type) = 0;
|
||||
virtual void bind_by_name(std::string const& name,
|
||||
void* data, exchange_type type) = 0;
|
||||
|
||||
virtual void pre_use(indicator const* ind) = 0;
|
||||
|
||||
virtual std::size_t size() = 0;
|
||||
|
||||
virtual void clean_up() = 0;
|
||||
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(vector_use_type_backend)
|
||||
};
|
||||
|
||||
// polymorphic statement backend
|
||||
|
||||
class statement_backend
|
||||
{
|
||||
public:
|
||||
statement_backend() {}
|
||||
virtual ~statement_backend() {}
|
||||
|
||||
virtual void alloc() = 0;
|
||||
virtual void clean_up() = 0;
|
||||
|
||||
virtual void prepare(std::string const& query, statement_type eType) = 0;
|
||||
|
||||
enum exec_fetch_result
|
||||
{
|
||||
ef_success,
|
||||
ef_no_data
|
||||
};
|
||||
|
||||
virtual exec_fetch_result execute(int number) = 0;
|
||||
virtual exec_fetch_result fetch(int number) = 0;
|
||||
|
||||
virtual long long get_affected_rows() = 0;
|
||||
virtual int get_number_of_rows() = 0;
|
||||
|
||||
virtual std::string get_parameter_name(int index) const = 0;
|
||||
|
||||
virtual std::string rewrite_for_procedure_call(std::string const& query) = 0;
|
||||
|
||||
virtual int prepare_for_describe() = 0;
|
||||
virtual void describe_column(int colNum, data_type& dtype,
|
||||
std::string& column_name) = 0;
|
||||
|
||||
virtual standard_into_type_backend* make_into_type_backend() = 0;
|
||||
virtual standard_use_type_backend* make_use_type_backend() = 0;
|
||||
virtual vector_into_type_backend* make_vector_into_type_backend() = 0;
|
||||
virtual vector_use_type_backend* make_vector_use_type_backend() = 0;
|
||||
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(statement_backend)
|
||||
};
|
||||
|
||||
// polymorphic RowID backend
|
||||
|
||||
class rowid_backend
|
||||
{
|
||||
public:
|
||||
virtual ~rowid_backend() {}
|
||||
};
|
||||
|
||||
// polymorphic blob backend
|
||||
|
||||
class blob_backend
|
||||
{
|
||||
public:
|
||||
blob_backend() {}
|
||||
virtual ~blob_backend() {}
|
||||
|
||||
virtual std::size_t get_len() = 0;
|
||||
virtual std::size_t read(std::size_t offset, char* buf,
|
||||
std::size_t toRead) = 0;
|
||||
virtual std::size_t write(std::size_t offset, char const* buf,
|
||||
std::size_t toWrite) = 0;
|
||||
virtual std::size_t append(char const* buf, std::size_t toWrite) = 0;
|
||||
virtual void trim(std::size_t newLen) = 0;
|
||||
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(blob_backend)
|
||||
};
|
||||
|
||||
// polymorphic session backend
|
||||
|
||||
class session_backend
|
||||
{
|
||||
public:
|
||||
session_backend() {}
|
||||
virtual ~session_backend() {}
|
||||
|
||||
virtual void begin() = 0;
|
||||
virtual void commit() = 0;
|
||||
virtual void rollback() = 0;
|
||||
|
||||
// At least one of these functions is usually not implemented for any given
|
||||
// backend as RDBMS support either sequences or auto-generated values, so
|
||||
// we don't declare them as pure virtuals to avoid having to define trivial
|
||||
// versions of them in the derived classes. However every backend should
|
||||
// define at least one of them to allow the code using auto-generated values
|
||||
// to work.
|
||||
virtual bool get_next_sequence_value(session&, std::string const&, long&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool get_last_insert_id(session&, std::string const&, long&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual std::string get_backend_name() const = 0;
|
||||
|
||||
virtual statement_backend* make_statement_backend() = 0;
|
||||
virtual rowid_backend* make_rowid_backend() = 0;
|
||||
virtual blob_backend* make_blob_backend() = 0;
|
||||
|
||||
private:
|
||||
SOCI_NOT_COPYABLE(session_backend)
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
// simple base class for the session back-end factory
|
||||
|
||||
class connection_parameters;
|
||||
|
||||
class SOCI_DECL backend_factory
|
||||
{
|
||||
public:
|
||||
backend_factory() {}
|
||||
virtual ~backend_factory() {}
|
||||
|
||||
virtual details::session_backend* make_session(
|
||||
connection_parameters const& parameters) const = 0;
|
||||
};
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_BACKEND_H_INCLUDED
|
||||
13
src/soci/include/soci/soci-config.h
Normal file
13
src/soci/include/soci/soci-config.h
Normal file
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCICONFIG_H_INCLUDED
|
||||
#define SOCICONFIG_H_INCLUDED
|
||||
|
||||
#include "soci/soci-platform.h"
|
||||
|
||||
#endif // SOCICONFIG_H_INCLUDED
|
||||
99
src/soci/include/soci/soci-platform.h
Normal file
99
src/soci/include/soci/soci-platform.h
Normal file
@@ -0,0 +1,99 @@
|
||||
//
|
||||
// Copyright (C) 2006-2008 Mateusz Loskot
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_PLATFORM_H_INCLUDED
|
||||
#define SOCI_PLATFORM_H_INCLUDED
|
||||
|
||||
//disable MSVC deprecated warnings
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#define LL_FMT_FLAGS "I64"
|
||||
#else
|
||||
#define LL_FMT_FLAGS "ll"
|
||||
#endif
|
||||
|
||||
// Portability hacks for Microsoft Visual C++ compiler
|
||||
#ifdef _MSC_VER
|
||||
#include <stdlib.h>
|
||||
|
||||
//Disables warnings about STL objects need to have dll-interface and/or
|
||||
//base class must have dll interface
|
||||
#pragma warning(disable:4251 4275)
|
||||
|
||||
|
||||
// Define if you have the vsnprintf variants.
|
||||
#if _MSC_VER < 1500
|
||||
# define vsnprintf _vsnprintf
|
||||
#endif
|
||||
|
||||
// Define if you have the snprintf variants.
|
||||
#define snprintf _snprintf
|
||||
|
||||
// Define if you have the strtoll and strtoull variants.
|
||||
#if _MSC_VER < 1300
|
||||
# error "Visual C++ versions prior 1300 don't support _strtoi64 and _strtoui64"
|
||||
#elif _MSC_VER >= 1300 && _MSC_VER < 1800
|
||||
namespace std {
|
||||
inline long long strtoll(char const* str, char** str_end, int base)
|
||||
{
|
||||
return _strtoi64(str, str_end, base);
|
||||
}
|
||||
|
||||
inline unsigned long long strtoull(char const* str, char** str_end, int base)
|
||||
{
|
||||
return _strtoui64(str, str_end, base);
|
||||
}
|
||||
}
|
||||
#endif // _MSC_VER < 1800
|
||||
#endif // _MSC_VER
|
||||
|
||||
#if defined(__CYGWIN__) || defined(__MINGW32__)
|
||||
#include <stdlib.h>
|
||||
namespace std {
|
||||
using ::strtoll;
|
||||
using ::strtoull;
|
||||
}
|
||||
#endif
|
||||
|
||||
//define DLL import/export on WIN32
|
||||
#ifdef _WIN32
|
||||
# ifdef SOCI_DLL
|
||||
# ifdef SOCI_SOURCE
|
||||
# define SOCI_DECL __declspec(dllexport)
|
||||
# else
|
||||
# define SOCI_DECL __declspec(dllimport)
|
||||
# endif // SOCI_SOURCE
|
||||
# endif // SOCI_DLL
|
||||
#endif // _WIN32
|
||||
//
|
||||
// If SOCI_DECL isn't defined yet define it now
|
||||
#ifndef SOCI_DECL
|
||||
# define SOCI_DECL
|
||||
#endif
|
||||
|
||||
#define SOCI_NOT_ASSIGNABLE(classname) \
|
||||
classname& operator=(const classname&);
|
||||
|
||||
#define SOCI_NOT_COPYABLE(classname) \
|
||||
classname(const classname&); \
|
||||
SOCI_NOT_ASSIGNABLE(classname)
|
||||
|
||||
#define SOCI_UNUSED(x) (void)x;
|
||||
|
||||
|
||||
|
||||
#endif // SOCI_PLATFORM_H_INCLUDED
|
||||
159
src/soci/include/soci/soci-simple.h
Normal file
159
src/soci/include/soci/soci-simple.h
Normal file
@@ -0,0 +1,159 @@
|
||||
//
|
||||
// Copyright (C) 2008 Maciej Sobczak
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_SIMPLE_H_INCLUDED
|
||||
#define SOCI_SIMPLE_H_INCLUDED
|
||||
|
||||
#include "soci/soci-platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
|
||||
// session
|
||||
|
||||
typedef void * session_handle;
|
||||
SOCI_DECL session_handle soci_create_session(char const * connectionString);
|
||||
SOCI_DECL void soci_destroy_session(session_handle s);
|
||||
|
||||
SOCI_DECL void soci_begin(session_handle s);
|
||||
SOCI_DECL void soci_commit(session_handle s);
|
||||
SOCI_DECL void soci_rollback(session_handle s);
|
||||
|
||||
SOCI_DECL int soci_session_state(session_handle s);
|
||||
SOCI_DECL char const * soci_session_error_message(session_handle s);
|
||||
|
||||
|
||||
// blob
|
||||
|
||||
typedef void *blob_handle;
|
||||
SOCI_DECL blob_handle soci_create_blob(session_handle s);
|
||||
SOCI_DECL void soci_destroy_blob(blob_handle b);
|
||||
|
||||
SOCI_DECL int soci_blob_get_len(blob_handle b);
|
||||
SOCI_DECL int soci_blob_read(blob_handle b, int offset, char *buf, int toRead);
|
||||
SOCI_DECL int soci_blob_write(blob_handle b, int offset, char const *buf, int toWrite);
|
||||
SOCI_DECL int soci_blob_append(blob_handle b, char const *buf, int toWrite);
|
||||
SOCI_DECL int soci_blob_trim(blob_handle b, int newLen);
|
||||
|
||||
SOCI_DECL int soci_blob_state(blob_handle b);
|
||||
SOCI_DECL char const * soci_blob_error_message(blob_handle b);
|
||||
|
||||
|
||||
// statement
|
||||
|
||||
typedef void * statement_handle;
|
||||
SOCI_DECL statement_handle soci_create_statement(session_handle s);
|
||||
SOCI_DECL void soci_destroy_statement(statement_handle st);
|
||||
|
||||
// positional bind of into elments (the functions return the position for convenience)
|
||||
SOCI_DECL int soci_into_string (statement_handle st);
|
||||
SOCI_DECL int soci_into_int (statement_handle st);
|
||||
SOCI_DECL int soci_into_long_long(statement_handle st);
|
||||
SOCI_DECL int soci_into_double (statement_handle st);
|
||||
SOCI_DECL int soci_into_date (statement_handle st);
|
||||
SOCI_DECL int soci_into_blob (statement_handle st);
|
||||
|
||||
// vector versions
|
||||
SOCI_DECL int soci_into_string_v (statement_handle st);
|
||||
SOCI_DECL int soci_into_int_v (statement_handle st);
|
||||
SOCI_DECL int soci_into_long_long_v(statement_handle st);
|
||||
SOCI_DECL int soci_into_double_v (statement_handle st);
|
||||
SOCI_DECL int soci_into_date_v (statement_handle st);
|
||||
|
||||
// positional read of into elements
|
||||
SOCI_DECL int soci_get_into_state (statement_handle st, int position);
|
||||
SOCI_DECL char const * soci_get_into_string (statement_handle st, int position);
|
||||
SOCI_DECL int soci_get_into_int (statement_handle st, int position);
|
||||
SOCI_DECL long long soci_get_into_long_long(statement_handle st, int position);
|
||||
SOCI_DECL double soci_get_into_double (statement_handle st, int position);
|
||||
SOCI_DECL char const * soci_get_into_date (statement_handle st, int position);
|
||||
SOCI_DECL blob_handle soci_get_into_blob (statement_handle st, int position);
|
||||
|
||||
// positional (re)size of vectors
|
||||
SOCI_DECL int soci_into_get_size_v(statement_handle st);
|
||||
SOCI_DECL void soci_into_resize_v (statement_handle st, int new_size);
|
||||
|
||||
// positional read of vectors
|
||||
SOCI_DECL int soci_get_into_state_v (statement_handle st, int position, int index);
|
||||
SOCI_DECL char const * soci_get_into_string_v (statement_handle st, int position, int index);
|
||||
SOCI_DECL int soci_get_into_int_v (statement_handle st, int position, int index);
|
||||
SOCI_DECL long long soci_get_into_long_long_v(statement_handle st, int position, int index);
|
||||
SOCI_DECL double soci_get_into_double_v (statement_handle st, int position, int index);
|
||||
SOCI_DECL char const * soci_get_into_date_v (statement_handle st, int position, int index);
|
||||
|
||||
|
||||
// named bind of use elements
|
||||
SOCI_DECL void soci_use_string (statement_handle st, char const * name);
|
||||
SOCI_DECL void soci_use_int (statement_handle st, char const * name);
|
||||
SOCI_DECL void soci_use_long_long(statement_handle st, char const * name);
|
||||
SOCI_DECL void soci_use_double (statement_handle st, char const * name);
|
||||
SOCI_DECL void soci_use_date (statement_handle st, char const * name);
|
||||
SOCI_DECL void soci_use_blob (statement_handle st, char const * name);
|
||||
|
||||
// vector versions
|
||||
SOCI_DECL void soci_use_string_v (statement_handle st, char const * name);
|
||||
SOCI_DECL void soci_use_int_v (statement_handle st, char const * name);
|
||||
SOCI_DECL void soci_use_long_long_v(statement_handle st, char const * name);
|
||||
SOCI_DECL void soci_use_double_v (statement_handle st, char const * name);
|
||||
SOCI_DECL void soci_use_date_v (statement_handle st, char const * name);
|
||||
|
||||
|
||||
// named write of use elements
|
||||
SOCI_DECL void soci_set_use_state (statement_handle st, char const * name, int state);
|
||||
SOCI_DECL void soci_set_use_string (statement_handle st, char const * name, char const * val);
|
||||
SOCI_DECL void soci_set_use_int (statement_handle st, char const * name, int val);
|
||||
SOCI_DECL void soci_set_use_long_long(statement_handle st, char const * name, long long val);
|
||||
SOCI_DECL void soci_set_use_double (statement_handle st, char const * name, double val);
|
||||
SOCI_DECL void soci_set_use_date (statement_handle st, char const * name, char const * val);
|
||||
SOCI_DECL void soci_set_use_blob (statement_handle st, char const * name, blob_handle blob);
|
||||
|
||||
// positional (re)size of vectors
|
||||
SOCI_DECL int soci_use_get_size_v(statement_handle st);
|
||||
SOCI_DECL void soci_use_resize_v (statement_handle st, int new_size);
|
||||
|
||||
// named write of use vectors
|
||||
SOCI_DECL void soci_set_use_state_v(statement_handle st,
|
||||
char const * name, int index, int state);
|
||||
SOCI_DECL void soci_set_use_string_v(statement_handle st,
|
||||
char const * name, int index, char const * val);
|
||||
SOCI_DECL void soci_set_use_int_v(statement_handle st,
|
||||
char const * name, int index, int val);
|
||||
SOCI_DECL void soci_set_use_long_long_v(statement_handle st,
|
||||
char const * name, int index, long long val);
|
||||
SOCI_DECL void soci_set_use_double_v(statement_handle st,
|
||||
char const * name, int index, double val);
|
||||
SOCI_DECL void soci_set_use_date_v(statement_handle st,
|
||||
char const * name, int index, char const * val);
|
||||
|
||||
|
||||
// named read of use elements (for modifiable use values)
|
||||
SOCI_DECL int soci_get_use_state (statement_handle st, char const * name);
|
||||
SOCI_DECL char const * soci_get_use_string (statement_handle st, char const * name);
|
||||
SOCI_DECL int soci_get_use_int (statement_handle st, char const * name);
|
||||
SOCI_DECL long long soci_get_use_long_long(statement_handle st, char const * name);
|
||||
SOCI_DECL double soci_get_use_double (statement_handle st, char const * name);
|
||||
SOCI_DECL char const * soci_get_use_date (statement_handle st, char const * name);
|
||||
SOCI_DECL blob_handle soci_get_use_blob (statement_handle st, char const * name);
|
||||
|
||||
|
||||
// statement preparation and execution
|
||||
SOCI_DECL void soci_prepare(statement_handle st, char const * query);
|
||||
SOCI_DECL int soci_execute(statement_handle st, int withDataExchange);
|
||||
SOCI_DECL long long soci_get_affected_rows(statement_handle st);
|
||||
SOCI_DECL int soci_fetch(statement_handle st);
|
||||
SOCI_DECL int soci_got_data(statement_handle st);
|
||||
|
||||
SOCI_DECL int soci_statement_state(statement_handle s);
|
||||
SOCI_DECL char const * soci_statement_error_message(statement_handle s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // SOCI_SIMPLE_H_INCLUDED
|
||||
56
src/soci/include/soci/soci.h
Normal file
56
src/soci/include/soci/soci.h
Normal file
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_H_INCLUDED
|
||||
#define SOCI_H_INCLUDED
|
||||
|
||||
// namespace soci
|
||||
#include "soci/soci-platform.h"
|
||||
#include "soci/backend-loader.h"
|
||||
#include "soci/blob.h"
|
||||
#include "soci/blob-exchange.h"
|
||||
#include "soci/connection-pool.h"
|
||||
#include "soci/error.h"
|
||||
#include "soci/exchange-traits.h"
|
||||
#include "soci/into.h"
|
||||
#include "soci/into-type.h"
|
||||
#include "soci/once-temp-type.h"
|
||||
#include "soci/prepare-temp-type.h"
|
||||
#include "soci/procedure.h"
|
||||
#include "soci/ref-counted-prepare-info.h"
|
||||
#include "soci/ref-counted-statement.h"
|
||||
#include "soci/row.h"
|
||||
#include "soci/row-exchange.h"
|
||||
#include "soci/rowid.h"
|
||||
#include "soci/rowid-exchange.h"
|
||||
#include "soci/rowset.h"
|
||||
#include "soci/session.h"
|
||||
#include "soci/soci-backend.h"
|
||||
#include "soci/statement.h"
|
||||
#include "soci/transaction.h"
|
||||
#include "soci/type-conversion.h"
|
||||
#include "soci/type-conversion-traits.h"
|
||||
#include "soci/type-holder.h"
|
||||
#include "soci/type-ptr.h"
|
||||
#include "soci/unsigned-types.h"
|
||||
#include "soci/use.h"
|
||||
#include "soci/use-type.h"
|
||||
#include "soci/values.h"
|
||||
#include "soci/values-exchange.h"
|
||||
|
||||
// namespace boost
|
||||
#ifdef SOCI_USE_BOOST
|
||||
#include <boost/version.hpp>
|
||||
#if defined(BOOST_VERSION) && BOOST_VERSION >= 103500
|
||||
#include "soci/boost-fusion.h"
|
||||
#endif // BOOST_VERSION
|
||||
#include "soci/boost-optional.h"
|
||||
#include "soci/boost-tuple.h"
|
||||
#include "soci/boost-gregorian-date.h"
|
||||
#endif // SOCI_USE_BOOST
|
||||
|
||||
#endif // SOCI_H_INCLUDED
|
||||
317
src/soci/include/soci/sqlite3/soci-sqlite3.h
Normal file
317
src/soci/include/soci/sqlite3/soci-sqlite3.h
Normal file
@@ -0,0 +1,317 @@
|
||||
//
|
||||
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, David Courtney
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_SQLITE3_H_INCLUDED
|
||||
#define SOCI_SQLITE3_H_INCLUDED
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef SOCI_DLL
|
||||
# ifdef SOCI_SQLITE3_SOURCE
|
||||
# define SOCI_SQLITE3_DECL __declspec(dllexport)
|
||||
# else
|
||||
# define SOCI_SQLITE3_DECL __declspec(dllimport)
|
||||
# endif // SOCI_SQLITE3_SOURCE
|
||||
# endif // SOCI_DLL
|
||||
#endif // _WIN32
|
||||
//
|
||||
// If SOCI_SQLITE3_DECL isn't defined yet define it now
|
||||
#ifndef SOCI_SQLITE3_DECL
|
||||
# define SOCI_SQLITE3_DECL
|
||||
#endif
|
||||
|
||||
#include <cstdarg>
|
||||
#include <vector>
|
||||
#include <soci/soci-backend.h>
|
||||
|
||||
// Disable flood of nonsense warnings generated for SQLite
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4510 4512 4610)
|
||||
#endif
|
||||
|
||||
namespace sqlite_api
|
||||
{
|
||||
|
||||
#if SQLITE_VERSION_NUMBER < 3003010
|
||||
// The sqlite3_destructor_type typedef introduced in 3.3.10
|
||||
// http://www.sqlite.org/cvstrac/tktview?tn=2191
|
||||
typedef void (*sqlite3_destructor_type)(void*);
|
||||
#endif
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
} // namespace sqlite_api
|
||||
|
||||
#undef SQLITE_STATIC
|
||||
#define SQLITE_STATIC ((sqlite_api::sqlite3_destructor_type)0)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
class sqlite3_soci_error : public soci_error
|
||||
{
|
||||
public:
|
||||
sqlite3_soci_error(std::string const & msg, int result);
|
||||
|
||||
int result() const;
|
||||
|
||||
private:
|
||||
int result_;
|
||||
};
|
||||
|
||||
struct sqlite3_statement_backend;
|
||||
struct sqlite3_standard_into_type_backend : details::standard_into_type_backend
|
||||
{
|
||||
sqlite3_standard_into_type_backend(sqlite3_statement_backend &st)
|
||||
: statement_(st) {}
|
||||
|
||||
virtual void define_by_pos(int &position,
|
||||
void *data, details::exchange_type type);
|
||||
|
||||
virtual void pre_fetch();
|
||||
virtual void post_fetch(bool gotData, bool calledFromFetch,
|
||||
indicator *ind);
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
sqlite3_statement_backend &statement_;
|
||||
|
||||
void *data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
};
|
||||
|
||||
struct sqlite3_vector_into_type_backend : details::vector_into_type_backend
|
||||
{
|
||||
sqlite3_vector_into_type_backend(sqlite3_statement_backend &st)
|
||||
: statement_(st) {}
|
||||
|
||||
void define_by_pos(int& position, void* data, details::exchange_type type);
|
||||
|
||||
void pre_fetch();
|
||||
void post_fetch(bool gotData, indicator* ind);
|
||||
|
||||
void resize(std::size_t sz);
|
||||
std::size_t size();
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
sqlite3_statement_backend& statement_;
|
||||
|
||||
void *data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
};
|
||||
|
||||
struct sqlite3_standard_use_type_backend : details::standard_use_type_backend
|
||||
{
|
||||
sqlite3_standard_use_type_backend(sqlite3_statement_backend &st);
|
||||
|
||||
virtual void bind_by_pos(int &position,
|
||||
void *data, details::exchange_type type, bool readOnly);
|
||||
virtual void bind_by_name(std::string const &name,
|
||||
void *data, details::exchange_type type, bool readOnly);
|
||||
|
||||
virtual void pre_use(indicator const *ind);
|
||||
virtual void post_use(bool gotData, indicator *ind);
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
sqlite3_statement_backend &statement_;
|
||||
|
||||
void *data_; // pointer to used data: soci::use(myvariable) --> data_ = &myvariable
|
||||
details::exchange_type type_; // type of data_
|
||||
int position_; // binding position
|
||||
std::string name_; // binding name
|
||||
};
|
||||
|
||||
struct sqlite3_vector_use_type_backend : details::vector_use_type_backend
|
||||
{
|
||||
sqlite3_vector_use_type_backend(sqlite3_statement_backend &st)
|
||||
: statement_(st) {}
|
||||
|
||||
virtual void bind_by_pos(int &position,
|
||||
void *data, details::exchange_type type);
|
||||
virtual void bind_by_name(std::string const &name,
|
||||
void *data, details::exchange_type type);
|
||||
|
||||
virtual void pre_use(indicator const *ind);
|
||||
|
||||
virtual std::size_t size();
|
||||
|
||||
virtual void clean_up();
|
||||
|
||||
sqlite3_statement_backend &statement_;
|
||||
|
||||
void *data_;
|
||||
details::exchange_type type_;
|
||||
int position_;
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
struct sqlite3_column
|
||||
{
|
||||
bool isNull_;
|
||||
data_type type_;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
std::size_t size_;
|
||||
union
|
||||
{
|
||||
const char *constData_;
|
||||
char *data_;
|
||||
};
|
||||
} buffer_;
|
||||
|
||||
int int32_;
|
||||
sqlite_api::sqlite3_int64 int64_;
|
||||
double double_;
|
||||
};
|
||||
};
|
||||
|
||||
typedef std::vector<sqlite3_column> sqlite3_row;
|
||||
typedef std::vector<sqlite3_row> sqlite3_recordset;
|
||||
|
||||
|
||||
struct sqlite3_column_info
|
||||
{
|
||||
data_type type_;
|
||||
std::string name_;
|
||||
};
|
||||
typedef std::vector<sqlite3_column_info> sqlite3_column_info_list;
|
||||
|
||||
struct sqlite3_session_backend;
|
||||
struct sqlite3_statement_backend : details::statement_backend
|
||||
{
|
||||
sqlite3_statement_backend(sqlite3_session_backend &session);
|
||||
|
||||
virtual void alloc();
|
||||
virtual void clean_up();
|
||||
virtual void prepare(std::string const &query,
|
||||
details::statement_type eType);
|
||||
void reset_if_needed();
|
||||
|
||||
virtual exec_fetch_result execute(int number);
|
||||
virtual exec_fetch_result fetch(int number);
|
||||
|
||||
virtual long long get_affected_rows();
|
||||
virtual int get_number_of_rows();
|
||||
virtual std::string get_parameter_name(int index) const;
|
||||
|
||||
virtual std::string rewrite_for_procedure_call(std::string const &query);
|
||||
|
||||
virtual int prepare_for_describe();
|
||||
virtual void describe_column(int colNum, data_type &dtype,
|
||||
std::string &columnName);
|
||||
|
||||
virtual sqlite3_standard_into_type_backend * make_into_type_backend();
|
||||
virtual sqlite3_standard_use_type_backend * make_use_type_backend();
|
||||
virtual sqlite3_vector_into_type_backend * make_vector_into_type_backend();
|
||||
virtual sqlite3_vector_use_type_backend * make_vector_use_type_backend();
|
||||
|
||||
sqlite3_session_backend &session_;
|
||||
sqlite_api::sqlite3_stmt *stmt_;
|
||||
sqlite3_recordset dataCache_;
|
||||
sqlite3_recordset useData_;
|
||||
bool databaseReady_;
|
||||
bool boundByName_;
|
||||
bool boundByPos_;
|
||||
sqlite3_column_info_list columns_;
|
||||
|
||||
|
||||
long long rowsAffectedBulk_; // number of rows affected by the last bulk operation
|
||||
|
||||
private:
|
||||
exec_fetch_result load_rowset(int totalRows);
|
||||
exec_fetch_result load_one();
|
||||
exec_fetch_result bind_and_execute(int number);
|
||||
};
|
||||
|
||||
struct sqlite3_rowid_backend : details::rowid_backend
|
||||
{
|
||||
sqlite3_rowid_backend(sqlite3_session_backend &session);
|
||||
|
||||
~sqlite3_rowid_backend();
|
||||
|
||||
unsigned long value_;
|
||||
};
|
||||
|
||||
struct sqlite3_blob_backend : details::blob_backend
|
||||
{
|
||||
sqlite3_blob_backend(sqlite3_session_backend &session);
|
||||
|
||||
~sqlite3_blob_backend();
|
||||
|
||||
virtual std::size_t get_len();
|
||||
virtual std::size_t read(std::size_t offset, char *buf,
|
||||
std::size_t toRead);
|
||||
virtual std::size_t write(std::size_t offset, char const *buf,
|
||||
std::size_t toWrite);
|
||||
virtual std::size_t append(char const *buf, std::size_t toWrite);
|
||||
virtual void trim(std::size_t newLen);
|
||||
|
||||
sqlite3_session_backend &session_;
|
||||
|
||||
std::size_t set_data(char const *buf, std::size_t toWrite);
|
||||
const char *get_buffer() const { return buf_; }
|
||||
|
||||
private:
|
||||
char *buf_;
|
||||
size_t len_;
|
||||
};
|
||||
|
||||
struct sqlite3_session_backend : details::session_backend
|
||||
{
|
||||
sqlite3_session_backend(connection_parameters const & parameters);
|
||||
|
||||
~sqlite3_session_backend();
|
||||
|
||||
virtual void begin();
|
||||
virtual void commit();
|
||||
virtual void rollback();
|
||||
|
||||
virtual bool get_last_insert_id(session&, std::string const&, long&);
|
||||
|
||||
virtual std::string get_backend_name() const { return "sqlite3"; }
|
||||
|
||||
void clean_up();
|
||||
|
||||
virtual sqlite3_statement_backend * make_statement_backend();
|
||||
virtual sqlite3_rowid_backend * make_rowid_backend();
|
||||
virtual sqlite3_blob_backend * make_blob_backend();
|
||||
|
||||
sqlite_api::sqlite3 *conn_;
|
||||
};
|
||||
|
||||
struct sqlite3_backend_factory : backend_factory
|
||||
{
|
||||
sqlite3_backend_factory() {}
|
||||
virtual sqlite3_session_backend * make_session(
|
||||
connection_parameters const & parameters) const;
|
||||
};
|
||||
|
||||
extern SOCI_SQLITE3_DECL sqlite3_backend_factory const sqlite3;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// for dynamic backend loading
|
||||
SOCI_SQLITE3_DECL backend_factory const * factory_sqlite3();
|
||||
SOCI_SQLITE3_DECL void register_factory_sqlite3();
|
||||
|
||||
} // extern "C"
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_SQLITE3_H_INCLUDED
|
||||
322
src/soci/include/soci/statement.h
Normal file
322
src/soci/include/soci/statement.h
Normal file
@@ -0,0 +1,322 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_STATEMENT_H_INCLUDED
|
||||
#define SOCI_STATEMENT_H_INCLUDED
|
||||
|
||||
#include "soci/bind-values.h"
|
||||
#include "soci/into-type.h"
|
||||
#include "soci/into.h"
|
||||
#include "soci/noreturn.h"
|
||||
#include "soci/use-type.h"
|
||||
#include "soci/use.h"
|
||||
#include "soci/soci-backend.h"
|
||||
#include "soci/row.h"
|
||||
// std
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
class session;
|
||||
class values;
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
class into_type_base;
|
||||
class use_type_base;
|
||||
class prepare_temp_type;
|
||||
|
||||
class SOCI_DECL statement_impl
|
||||
{
|
||||
public:
|
||||
explicit statement_impl(session & s);
|
||||
explicit statement_impl(prepare_temp_type const & prep);
|
||||
~statement_impl();
|
||||
|
||||
void alloc();
|
||||
void bind(values & v);
|
||||
|
||||
void exchange(into_type_ptr const & i) { intos_.exchange(i); }
|
||||
template <typename T, typename Indicator>
|
||||
void exchange(into_container<T, Indicator> const &ic)
|
||||
{ intos_.exchange(ic); }
|
||||
|
||||
void exchange(use_type_ptr const & u) { uses_.exchange(u); }
|
||||
template <typename T, typename Indicator>
|
||||
void exchange(use_container<T, Indicator> const &uc)
|
||||
{ uses_.exchange(uc); }
|
||||
|
||||
|
||||
void clean_up();
|
||||
void bind_clean_up();
|
||||
|
||||
void prepare(std::string const & query,
|
||||
statement_type eType = st_repeatable_query);
|
||||
void define_and_bind();
|
||||
void undefine_and_bind();
|
||||
bool execute(bool withDataExchange = false);
|
||||
long long get_affected_rows();
|
||||
bool fetch();
|
||||
void describe();
|
||||
void set_row(row * r);
|
||||
void exchange_for_rowset(into_type_ptr const & i) { exchange_for_rowset_(i); }
|
||||
template<typename T, typename Indicator>
|
||||
void exchange_for_rowset(into_container<T, Indicator> const &ic)
|
||||
{ exchange_for_rowset_(ic); }
|
||||
|
||||
// for diagnostics and advanced users
|
||||
// (downcast it to expected back-end statement class)
|
||||
statement_backend * get_backend() { return backEnd_; }
|
||||
|
||||
standard_into_type_backend * make_into_type_backend();
|
||||
standard_use_type_backend * make_use_type_backend();
|
||||
vector_into_type_backend * make_vector_into_type_backend();
|
||||
vector_use_type_backend * make_vector_use_type_backend();
|
||||
|
||||
void inc_ref();
|
||||
void dec_ref();
|
||||
|
||||
session & session_;
|
||||
|
||||
std::string rewrite_for_procedure_call(std::string const & query);
|
||||
|
||||
protected:
|
||||
into_type_vector intos_;
|
||||
use_type_vector uses_;
|
||||
std::vector<indicator *> indicators_;
|
||||
|
||||
private:
|
||||
// Call this method from a catch clause (only!) to rethrow the exception
|
||||
// after adding the context in which it happened, including the provided
|
||||
// description of the operation that failed, the SQL query and, if
|
||||
// applicable, its parameters.
|
||||
SOCI_NORETURN rethrow_current_exception_with_context(char const* operation);
|
||||
|
||||
int refCount_;
|
||||
|
||||
row * row_;
|
||||
std::size_t fetchSize_;
|
||||
std::size_t initialFetchSize_;
|
||||
std::string query_;
|
||||
|
||||
into_type_vector intosForRow_;
|
||||
int definePositionForRow_;
|
||||
|
||||
template <typename Into>
|
||||
void exchange_for_rowset_(Into const &i)
|
||||
{
|
||||
if (intos_.empty() == false)
|
||||
{
|
||||
throw soci_error("Explicit into elements not allowed with rowset.");
|
||||
}
|
||||
|
||||
intos_.exchange(i);
|
||||
|
||||
int definePosition = 1;
|
||||
for(into_type_vector::iterator iter = intos_.begin(),
|
||||
end = intos_.end();
|
||||
iter != end; iter++)
|
||||
{ (*iter)->define(*this, definePosition); }
|
||||
definePositionForRow_ = definePosition;
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename Indicator>
|
||||
void exchange_for_row(into_container<T, Indicator> const &ic)
|
||||
{ intosForRow_.exchange(ic); }
|
||||
void exchange_for_row(into_type_ptr const & i) { intosForRow_.exchange(i); }
|
||||
void define_for_row();
|
||||
|
||||
template<typename T>
|
||||
void into_row()
|
||||
{
|
||||
T * t = new T();
|
||||
indicator * ind = new indicator(i_ok);
|
||||
row_->add_holder(t, ind);
|
||||
exchange_for_row(into(*t, *ind));
|
||||
}
|
||||
|
||||
template<data_type>
|
||||
void bind_into();
|
||||
|
||||
bool alreadyDescribed_;
|
||||
|
||||
std::size_t intos_size();
|
||||
std::size_t uses_size();
|
||||
void pre_fetch();
|
||||
void pre_use();
|
||||
void post_fetch(bool gotData, bool calledFromFetch);
|
||||
void post_use(bool gotData);
|
||||
bool resize_intos(std::size_t upperBound = 0);
|
||||
void truncate_intos();
|
||||
|
||||
soci::details::statement_backend * backEnd_;
|
||||
|
||||
SOCI_NOT_COPYABLE(statement_impl)
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
// Statement is a handle class for statement_impl
|
||||
// (this provides copyability to otherwise non-copyable type)
|
||||
class SOCI_DECL statement
|
||||
{
|
||||
public:
|
||||
statement(session & s)
|
||||
: impl_(new details::statement_impl(s)) {}
|
||||
statement(details::prepare_temp_type const & prep)
|
||||
: impl_(new details::statement_impl(prep)) {}
|
||||
~statement() { impl_->dec_ref(); }
|
||||
|
||||
// copy is supported for this handle class
|
||||
statement(statement const & other)
|
||||
: impl_(other.impl_)
|
||||
{
|
||||
impl_->inc_ref();
|
||||
}
|
||||
|
||||
void operator=(statement const & other)
|
||||
{
|
||||
other.impl_->inc_ref();
|
||||
impl_->dec_ref();
|
||||
impl_ = other.impl_;
|
||||
}
|
||||
|
||||
void alloc() { impl_->alloc(); }
|
||||
void bind(values & v) { impl_->bind(v); }
|
||||
void exchange(details::into_type_ptr const & i) { impl_->exchange(i); }
|
||||
template <typename T, typename Indicator>
|
||||
void exchange(details::into_container<T, Indicator> const &ic) { impl_->exchange(ic); }
|
||||
void exchange(details::use_type_ptr const & u) { impl_->exchange(u); }
|
||||
template <typename T, typename Indicator>
|
||||
void exchange(details::use_container<T, Indicator> const &uc) { impl_->exchange(uc); }
|
||||
void clean_up() { impl_->clean_up(); }
|
||||
void bind_clean_up() { impl_->bind_clean_up(); }
|
||||
|
||||
void prepare(std::string const & query,
|
||||
details::statement_type eType = details::st_repeatable_query)
|
||||
{
|
||||
impl_->prepare(query, eType);
|
||||
}
|
||||
|
||||
void define_and_bind() { impl_->define_and_bind(); }
|
||||
void undefine_and_bind() { impl_->undefine_and_bind(); }
|
||||
bool execute(bool withDataExchange = false)
|
||||
{
|
||||
gotData_ = impl_->execute(withDataExchange);
|
||||
return gotData_;
|
||||
}
|
||||
|
||||
long long get_affected_rows()
|
||||
{
|
||||
return impl_->get_affected_rows();
|
||||
}
|
||||
|
||||
bool fetch()
|
||||
{
|
||||
gotData_ = impl_->fetch();
|
||||
return gotData_;
|
||||
}
|
||||
|
||||
bool got_data() const { return gotData_; }
|
||||
|
||||
void describe() { impl_->describe(); }
|
||||
void set_row(row * r) { impl_->set_row(r); }
|
||||
|
||||
template <typename T, typename Indicator>
|
||||
void exchange_for_rowset(details::into_container<T, Indicator> const & ic)
|
||||
{
|
||||
impl_->exchange_for_rowset(ic);
|
||||
}
|
||||
|
||||
void exchange_for_rowset(details::into_type_ptr const & i)
|
||||
{
|
||||
impl_->exchange_for_rowset(i);
|
||||
}
|
||||
|
||||
// for diagnostics and advanced users
|
||||
// (downcast it to expected back-end statement class)
|
||||
details::statement_backend * get_backend()
|
||||
{
|
||||
return impl_->get_backend();
|
||||
}
|
||||
|
||||
details::standard_into_type_backend * make_into_type_backend()
|
||||
{
|
||||
return impl_->make_into_type_backend();
|
||||
}
|
||||
|
||||
details::standard_use_type_backend * make_use_type_backend()
|
||||
{
|
||||
return impl_->make_use_type_backend();
|
||||
}
|
||||
|
||||
details::vector_into_type_backend * make_vector_into_type_backend()
|
||||
{
|
||||
return impl_->make_vector_into_type_backend();
|
||||
}
|
||||
|
||||
details::vector_use_type_backend * make_vector_use_type_backend()
|
||||
{
|
||||
return impl_->make_vector_use_type_backend();
|
||||
}
|
||||
|
||||
std::string rewrite_for_procedure_call(std::string const & query)
|
||||
{
|
||||
return impl_->rewrite_for_procedure_call(query);
|
||||
}
|
||||
|
||||
private:
|
||||
details::statement_impl * impl_;
|
||||
bool gotData_;
|
||||
};
|
||||
|
||||
namespace details
|
||||
{
|
||||
// exchange_traits for statement
|
||||
|
||||
template <>
|
||||
struct exchange_traits<statement>
|
||||
{
|
||||
typedef basic_type_tag type_family;
|
||||
enum { x_type = x_statement };
|
||||
};
|
||||
|
||||
// into and use types for Statement (for nested statements and cursors)
|
||||
|
||||
template <>
|
||||
class into_type<statement> : public standard_into_type
|
||||
{
|
||||
public:
|
||||
into_type(statement & s) : standard_into_type(&s, x_statement) {}
|
||||
into_type(statement & s, indicator & ind)
|
||||
: standard_into_type(&s, x_statement, ind) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
class use_type<statement> : public standard_use_type
|
||||
{
|
||||
public:
|
||||
use_type(statement & s, std::string const & name = std::string())
|
||||
: standard_use_type(&s, x_statement, false, name) {}
|
||||
use_type(statement & s, indicator & ind,
|
||||
std::string const & name = std::string())
|
||||
: standard_use_type(&s, x_statement, ind, false, name) {}
|
||||
|
||||
// Note: there is no const version of use for statement,
|
||||
// because most likely it would not make much sense anyway.
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_STATEMENT_H_INCLUDED
|
||||
36
src/soci/include/soci/transaction.h
Normal file
36
src/soci/include/soci/transaction.h
Normal file
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_TRANSACTION_H_INCLUDED
|
||||
#define SOCI_TRANSACTION_H_INCLUDED
|
||||
|
||||
#include "soci/soci-platform.h"
|
||||
#include "soci/session.h"
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
class SOCI_DECL transaction
|
||||
{
|
||||
public:
|
||||
explicit transaction(session& sql);
|
||||
|
||||
~transaction();
|
||||
|
||||
void commit();
|
||||
void rollback();
|
||||
|
||||
private:
|
||||
bool handled_;
|
||||
session& sql_;
|
||||
|
||||
SOCI_NOT_COPYABLE(transaction)
|
||||
};
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_TRANSACTION_H_INCLUDED
|
||||
41
src/soci/include/soci/type-conversion-traits.h
Normal file
41
src/soci/include/soci/type-conversion-traits.h
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_TYPE_CONVERSION_TRAITS_H_INCLUDED
|
||||
#define SOCI_TYPE_CONVERSION_TRAITS_H_INCLUDED
|
||||
|
||||
#include "soci/soci-backend.h"
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
// default traits class type_conversion, acts as pass through for row::get()
|
||||
// when no actual conversion is needed.
|
||||
template <typename T, typename Enable = void>
|
||||
struct type_conversion
|
||||
{
|
||||
typedef T base_type;
|
||||
|
||||
static void from_base(base_type const & in, indicator ind, T & out)
|
||||
{
|
||||
if (ind == i_null)
|
||||
{
|
||||
throw soci_error("Null value not allowed for this type");
|
||||
}
|
||||
out = in;
|
||||
}
|
||||
|
||||
static void to_base(T const & in, base_type & out, indicator & ind)
|
||||
{
|
||||
out = in;
|
||||
ind = i_ok;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_TYPE_CONVERSION_TRAITS_H_INCLUDED
|
||||
364
src/soci/include/soci/type-conversion.h
Normal file
364
src/soci/include/soci/type-conversion.h
Normal file
@@ -0,0 +1,364 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_TYPE_CONVERSION_H_INCLUDED
|
||||
#define SOCI_TYPE_CONVERSION_H_INCLUDED
|
||||
|
||||
#include "soci/type-conversion-traits.h"
|
||||
#include "soci/into-type.h"
|
||||
#include "soci/use-type.h"
|
||||
// std
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
// this class is used to ensure correct order of construction
|
||||
// of into_type and use_type elements that use type_conversion
|
||||
|
||||
template <typename T>
|
||||
struct base_value_holder
|
||||
{
|
||||
typename type_conversion<T>::base_type val_;
|
||||
};
|
||||
|
||||
// Automatically create into_type from a type_conversion
|
||||
|
||||
template <typename T>
|
||||
class conversion_into_type
|
||||
: private base_value_holder<T>,
|
||||
public into_type<typename type_conversion<T>::base_type>
|
||||
{
|
||||
public:
|
||||
typedef typename type_conversion<T>::base_type base_type;
|
||||
|
||||
conversion_into_type(T & value)
|
||||
: into_type<base_type>(details::base_value_holder<T>::val_, ownInd_)
|
||||
, value_(value)
|
||||
, ownInd_()
|
||||
, ind_(ownInd_)
|
||||
{
|
||||
}
|
||||
|
||||
conversion_into_type(T & value, indicator & ind)
|
||||
: into_type<base_type>(details::base_value_holder<T>::val_, ind)
|
||||
, value_(value)
|
||||
, ownInd_(ind) // unused, just keep the pair of indicator(s) consistent
|
||||
, ind_(ind)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
void convert_from_base()
|
||||
{
|
||||
type_conversion<T>::from_base(
|
||||
details::base_value_holder<T>::val_, ind_, value_);
|
||||
}
|
||||
|
||||
T & value_;
|
||||
|
||||
indicator ownInd_;
|
||||
|
||||
// ind_ refers to either ownInd_, or the one provided by the user
|
||||
// in any case, ind_ refers to some valid indicator
|
||||
// and can be used by conversion routines
|
||||
indicator & ind_;
|
||||
|
||||
SOCI_NOT_COPYABLE(conversion_into_type)
|
||||
};
|
||||
|
||||
// Automatically create use_type from a type_conversion
|
||||
|
||||
template <typename T>
|
||||
class conversion_use_type
|
||||
: private details::base_value_holder<T>,
|
||||
public use_type<typename type_conversion<T>::base_type>
|
||||
{
|
||||
public:
|
||||
typedef typename type_conversion<T>::base_type base_type;
|
||||
|
||||
conversion_use_type(T & value, std::string const & name = std::string())
|
||||
: use_type<base_type>(details::base_value_holder<T>::val_, ownInd_, name)
|
||||
, value_(value)
|
||||
, ownInd_()
|
||||
, ind_(ownInd_)
|
||||
, readOnly_(false)
|
||||
{
|
||||
// TODO: likely to be removed (SHA: c166625a28f7c907318134f625ff5acea7d9a1f8)
|
||||
//convert_to_base();
|
||||
}
|
||||
|
||||
conversion_use_type(T const & value, std::string const & name = std::string())
|
||||
: use_type<base_type>(details::base_value_holder<T>::val_, ownInd_, name)
|
||||
, value_(const_cast<T &>(value))
|
||||
, ownInd_()
|
||||
, ind_(ownInd_)
|
||||
, readOnly_(true)
|
||||
{
|
||||
// TODO: likely to be removed (SHA: c166625a28f7c907318134f625ff5acea7d9a1f8)
|
||||
//convert_to_base();
|
||||
}
|
||||
|
||||
conversion_use_type(T & value, indicator & ind,
|
||||
std::string const & name = std::string())
|
||||
: use_type<base_type>(details::base_value_holder<T>::val_, ind, name)
|
||||
, value_(value)
|
||||
, ind_(ind)
|
||||
, readOnly_(false)
|
||||
{
|
||||
// TODO: likely to be removed (SHA: c166625a28f7c907318134f625ff5acea7d9a1f8)
|
||||
//convert_to_base();
|
||||
}
|
||||
|
||||
conversion_use_type(T const & value, indicator & ind,
|
||||
std::string const & name = std::string())
|
||||
: use_type<base_type>(details::base_value_holder<T>::val_, ind, name)
|
||||
, value_(const_cast<T &>(value))
|
||||
, ind_(ind)
|
||||
, readOnly_(true)
|
||||
{
|
||||
// TODO: likely to be removed (SHA: c166625a28f7c907318134f625ff5acea7d9a1f8)
|
||||
//convert_to_base();
|
||||
}
|
||||
|
||||
void convert_from_base()
|
||||
{
|
||||
// NOTE:
|
||||
// readOnly_ flag indicates that use_type object has been generated
|
||||
// based on non-const object passed by user as input argument.
|
||||
// For const objects, this is effectively no-op conversion.
|
||||
// See standard_use_type::post_use() for more details.
|
||||
|
||||
if (readOnly_ == false)
|
||||
{
|
||||
type_conversion<T>::from_base(
|
||||
details::base_value_holder<T>::val_, ind_, value_);
|
||||
}
|
||||
}
|
||||
|
||||
void convert_to_base()
|
||||
{
|
||||
type_conversion<T>::to_base(value_,
|
||||
details::base_value_holder<T>::val_, ind_);
|
||||
}
|
||||
|
||||
private:
|
||||
T & value_;
|
||||
|
||||
indicator ownInd_;
|
||||
|
||||
// ind_ refers to either ownInd_, or the one provided by the user
|
||||
// in any case, ind_ refers to some valid indicator
|
||||
// and can be used by conversion routines
|
||||
indicator & ind_;
|
||||
|
||||
bool readOnly_;
|
||||
|
||||
SOCI_NOT_COPYABLE(conversion_use_type)
|
||||
};
|
||||
|
||||
// this class is used to ensure correct order of construction
|
||||
// of vector based into_type and use_type elements that use type_conversion
|
||||
|
||||
template <typename T>
|
||||
struct base_vector_holder
|
||||
{
|
||||
base_vector_holder(std::size_t sz = 0) : vec_(sz) {}
|
||||
mutable std::vector<typename type_conversion<T>::base_type> vec_;
|
||||
};
|
||||
|
||||
// Automatically create a std::vector based into_type from a type_conversion
|
||||
|
||||
template <typename T>
|
||||
class conversion_into_type<std::vector<T> >
|
||||
: private details::base_vector_holder<T>,
|
||||
public into_type<std::vector<typename type_conversion<T>::base_type> >
|
||||
{
|
||||
public:
|
||||
typedef typename std::vector
|
||||
<
|
||||
typename type_conversion<T>::base_type
|
||||
> base_type;
|
||||
|
||||
conversion_into_type(std::vector<T> & value)
|
||||
: details::base_vector_holder<T>(value.size())
|
||||
, into_type<base_type>(details::base_vector_holder<T>::vec_, ownInd_)
|
||||
, value_(value)
|
||||
, ownInd_()
|
||||
, ind_(ownInd_)
|
||||
{
|
||||
}
|
||||
|
||||
conversion_into_type(std::vector<T> & value, std::vector<indicator> & ind)
|
||||
: details::base_vector_holder<T>(value.size())
|
||||
, into_type<base_type>(details::base_vector_holder<T>::vec_, ind)
|
||||
, value_(value)
|
||||
, ind_(ind)
|
||||
{}
|
||||
|
||||
virtual std::size_t size() const
|
||||
{
|
||||
// the user might have resized his vector in the meantime
|
||||
// -> synchronize the base-value mirror to have the same size
|
||||
|
||||
std::size_t const userSize = value_.size();
|
||||
details::base_vector_holder<T>::vec_.resize(userSize);
|
||||
return userSize;
|
||||
}
|
||||
|
||||
virtual void resize(std::size_t sz)
|
||||
{
|
||||
value_.resize(sz);
|
||||
ind_.resize(sz);
|
||||
details::base_vector_holder<T>::vec_.resize(sz);
|
||||
}
|
||||
|
||||
private:
|
||||
void convert_from_base()
|
||||
{
|
||||
std::size_t const sz = details::base_vector_holder<T>::vec_.size();
|
||||
|
||||
for (std::size_t i = 0; i != sz; ++i)
|
||||
{
|
||||
type_conversion<T>::from_base(
|
||||
details::base_vector_holder<T>::vec_[i], ind_[i], value_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<T> & value_;
|
||||
|
||||
std::vector<indicator> ownInd_;
|
||||
|
||||
// ind_ refers to either ownInd_, or the one provided by the user
|
||||
// in any case, ind_ refers to some valid vector of indicators
|
||||
// and can be used by conversion routines
|
||||
std::vector<indicator> & ind_;
|
||||
|
||||
SOCI_NOT_COPYABLE(conversion_into_type)
|
||||
};
|
||||
|
||||
|
||||
// Automatically create a std::vector based use_type from a type_conversion
|
||||
|
||||
template <typename T>
|
||||
class conversion_use_type<std::vector<T> >
|
||||
: private details::base_vector_holder<T>,
|
||||
public use_type<std::vector<typename type_conversion<T>::base_type> >
|
||||
{
|
||||
public:
|
||||
typedef typename std::vector
|
||||
<
|
||||
typename type_conversion<T>::base_type
|
||||
> base_type;
|
||||
|
||||
conversion_use_type(std::vector<T> & value,
|
||||
std::string const & name=std::string())
|
||||
: details::base_vector_holder<T>(value.size())
|
||||
, use_type<base_type>(
|
||||
details::base_vector_holder<T>::vec_, ownInd_, name)
|
||||
, value_(value)
|
||||
, ownInd_()
|
||||
, ind_(ownInd_)
|
||||
{
|
||||
}
|
||||
|
||||
conversion_use_type(std::vector<T> & value,
|
||||
std::vector<indicator> & ind,
|
||||
std::string const & name = std::string())
|
||||
: details::base_vector_holder<T>(value.size())
|
||||
, use_type<base_type>(
|
||||
details::base_vector_holder<T>::vec_, ind, name)
|
||||
, value_(value)
|
||||
, ind_(ind)
|
||||
{}
|
||||
|
||||
private:
|
||||
void convert_from_base()
|
||||
{
|
||||
std::size_t const sz = details::base_vector_holder<T>::vec_.size();
|
||||
value_.resize(sz);
|
||||
ind_.resize(sz);
|
||||
for (std::size_t i = 0; i != sz; ++i)
|
||||
{
|
||||
type_conversion<T>::from_base(
|
||||
details::base_vector_holder<T>::vec_[i], value_[i], ind_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void convert_to_base()
|
||||
{
|
||||
std::size_t const sz = value_.size();
|
||||
details::base_vector_holder<T>::vec_.resize(sz);
|
||||
ind_.resize(sz);
|
||||
for (std::size_t i = 0; i != sz; ++i)
|
||||
{
|
||||
type_conversion<T>::to_base(value_[i],
|
||||
details::base_vector_holder<T>::vec_[i], ind_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<T> & value_;
|
||||
|
||||
std::vector<indicator> ownInd_;
|
||||
|
||||
// ind_ refers to either ownInd_, or the one provided by the user
|
||||
// in any case, ind_ refers to some valid vector of indicators
|
||||
// and can be used by conversion routines
|
||||
std::vector<indicator> & ind_;
|
||||
|
||||
SOCI_NOT_COPYABLE(conversion_use_type)
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
into_type_ptr do_into(T & t, user_type_tag)
|
||||
{
|
||||
return into_type_ptr(new conversion_into_type<T>(t));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
into_type_ptr do_into(T & t, indicator & ind, user_type_tag)
|
||||
{
|
||||
return into_type_ptr(new conversion_into_type<T>(t, ind));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
use_type_ptr do_use(T & t, std::string const & name, user_type_tag)
|
||||
{
|
||||
return use_type_ptr(new conversion_use_type<T>(t, name));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
use_type_ptr do_use(T const & t, std::string const & name, user_type_tag)
|
||||
{
|
||||
return use_type_ptr(new conversion_use_type<T>(t, name));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
use_type_ptr do_use(T & t, indicator & ind,
|
||||
std::string const & name, user_type_tag)
|
||||
{
|
||||
return use_type_ptr(new conversion_use_type<T>(t, ind, name));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
use_type_ptr do_use(T const & t, indicator & ind,
|
||||
std::string const & name, user_type_tag)
|
||||
{
|
||||
return use_type_ptr(new conversion_use_type<T>(t, ind, name));
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_TYPE_CONVERSION_H_INCLUDED
|
||||
68
src/soci/include/soci/type-holder.h
Normal file
68
src/soci/include/soci/type-holder.h
Normal file
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_TYPE_HOLDER_H_INCLUDED
|
||||
#define SOCI_TYPE_HOLDER_H_INCLUDED
|
||||
// std
|
||||
#include <typeinfo>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
// Base class holder + derived class type_holder for storing type data
|
||||
// instances in a container of holder objects
|
||||
template <typename T>
|
||||
class type_holder;
|
||||
|
||||
class holder
|
||||
{
|
||||
public:
|
||||
holder() {}
|
||||
virtual ~holder() {}
|
||||
|
||||
template<typename T>
|
||||
T get()
|
||||
{
|
||||
type_holder<T>* p = dynamic_cast<type_holder<T> *>(this);
|
||||
if (p)
|
||||
{
|
||||
return p->template value<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::bad_cast();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<typename T>
|
||||
T value();
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class type_holder : public holder
|
||||
{
|
||||
public:
|
||||
type_holder(T * t) : t_(t) {}
|
||||
~type_holder() { delete t_; }
|
||||
|
||||
template<typename TypeValue>
|
||||
TypeValue value() const { return *t_; }
|
||||
|
||||
private:
|
||||
T * t_;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_TYPE_HOLDER_H_INCLUDED
|
||||
30
src/soci/include/soci/type-ptr.h
Normal file
30
src/soci/include/soci/type-ptr.h
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_TYPE_PTR_H_INCLUDED
|
||||
#define SOCI_TYPE_PTR_H_INCLUDED
|
||||
|
||||
namespace soci { namespace details {
|
||||
|
||||
template <typename T>
|
||||
class type_ptr
|
||||
{
|
||||
public:
|
||||
type_ptr(T * p) : p_(p) {}
|
||||
~type_ptr() { delete p_; }
|
||||
|
||||
T * get() const { return p_; }
|
||||
void release() const { p_ = 0; }
|
||||
|
||||
private:
|
||||
mutable T * p_;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_TYPE_PTR_H_INCLUDED
|
||||
114
src/soci/include/soci/unsigned-types.h
Normal file
114
src/soci/include/soci/unsigned-types.h
Normal file
@@ -0,0 +1,114 @@
|
||||
//
|
||||
// Copyright (C) 2010 Maciej Sobczak
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_UNSIGNED_TYPES_H_INCLUDED
|
||||
#define SOCI_UNSIGNED_TYPES_H_INCLUDED
|
||||
|
||||
#include "soci/type-conversion-traits.h"
|
||||
#include <limits>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
// simple fall-back for unsigned types
|
||||
|
||||
template <>
|
||||
struct type_conversion<unsigned char>
|
||||
{
|
||||
typedef long long base_type;
|
||||
|
||||
static void from_base(base_type const & in, indicator ind,
|
||||
unsigned char & out)
|
||||
{
|
||||
if (ind == i_null)
|
||||
{
|
||||
throw soci_error("Null value not allowed for this type.");
|
||||
}
|
||||
|
||||
const base_type max = (std::numeric_limits<unsigned char>::max)();
|
||||
const base_type min = (std::numeric_limits<unsigned char>::min)();
|
||||
if (in < min || in > max)
|
||||
{
|
||||
/* throw soci_error("Value outside of allowed range."); */
|
||||
}
|
||||
|
||||
out = static_cast<unsigned char>(in);
|
||||
}
|
||||
|
||||
static void to_base(unsigned char const & in,
|
||||
base_type & out, indicator & ind)
|
||||
{
|
||||
out = static_cast<base_type>(in);
|
||||
ind = i_ok;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_conversion<unsigned short>
|
||||
{
|
||||
typedef long long base_type;
|
||||
|
||||
static void from_base(base_type const & in, indicator ind,
|
||||
unsigned short & out)
|
||||
{
|
||||
if (ind == i_null)
|
||||
{
|
||||
throw soci_error("Null value not allowed for this type.");
|
||||
}
|
||||
|
||||
const long long max = (std::numeric_limits<unsigned short>::max)();
|
||||
const long long min = (std::numeric_limits<unsigned short>::min)();
|
||||
if (in < min || in > max)
|
||||
{
|
||||
/* throw soci_error("Value outside of allowed range."); */
|
||||
}
|
||||
|
||||
out = static_cast<unsigned short>(in);
|
||||
}
|
||||
|
||||
static void to_base(unsigned short const & in,
|
||||
base_type & out, indicator & ind)
|
||||
{
|
||||
out = static_cast<base_type>(in);
|
||||
ind = i_ok;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_conversion<unsigned int>
|
||||
{
|
||||
typedef long long base_type;
|
||||
|
||||
static void from_base(base_type const & in, indicator ind,
|
||||
unsigned int & out)
|
||||
{
|
||||
if (ind == i_null)
|
||||
{
|
||||
throw soci_error("Null value not allowed for this type.");
|
||||
}
|
||||
|
||||
const long long max = (std::numeric_limits<unsigned int>::max)();
|
||||
const long long min = (std::numeric_limits<unsigned int>::min)();
|
||||
if (in < min || in > max)
|
||||
{
|
||||
/* throw soci_error("Value outside of allowed range."); */
|
||||
}
|
||||
|
||||
out = static_cast<unsigned int>(in);
|
||||
}
|
||||
|
||||
static void to_base(unsigned int const & in,
|
||||
base_type & out, indicator & ind)
|
||||
{
|
||||
out = static_cast<base_type>(in);
|
||||
ind = i_ok;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_UNSIGNED_TYPES_H_INCLUDED
|
||||
246
src/soci/include/soci/use-type.h
Normal file
246
src/soci/include/soci/use-type.h
Normal file
@@ -0,0 +1,246 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_USE_TYPE_H_INCLUDED
|
||||
#define SOCI_USE_TYPE_H_INCLUDED
|
||||
|
||||
#include "soci/soci-platform.h"
|
||||
#include "soci/soci-backend.h"
|
||||
#include "soci/type-ptr.h"
|
||||
#include "soci/exchange-traits.h"
|
||||
// std
|
||||
#include <cstddef>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace soci { namespace details {
|
||||
|
||||
class statement_impl;
|
||||
|
||||
// this is intended to be a base class for all classes that deal with
|
||||
// binding input data (and OUT PL/SQL variables)
|
||||
class SOCI_DECL use_type_base
|
||||
{
|
||||
public:
|
||||
virtual ~use_type_base() {}
|
||||
|
||||
virtual void bind(statement_impl & st, int & position) = 0;
|
||||
virtual std::string get_name() const = 0;
|
||||
virtual void dump_value(std::ostream& os) const = 0;
|
||||
virtual void pre_use() = 0;
|
||||
virtual void post_use(bool gotData) = 0;
|
||||
virtual void clean_up() = 0;
|
||||
|
||||
virtual std::size_t size() const = 0; // returns the number of elements
|
||||
};
|
||||
|
||||
typedef type_ptr<use_type_base> use_type_ptr;
|
||||
|
||||
class SOCI_DECL standard_use_type : public use_type_base
|
||||
{
|
||||
public:
|
||||
standard_use_type(void* data, exchange_type type,
|
||||
bool readOnly, std::string const& name = std::string())
|
||||
: data_(data)
|
||||
, type_(type)
|
||||
, ind_(NULL)
|
||||
, readOnly_(readOnly)
|
||||
, name_(name)
|
||||
, backEnd_(NULL)
|
||||
{
|
||||
// FIXME: This was added with Ilia's patch
|
||||
// https://github.com/SOCI/soci/commit/c166625a28f7c907318134f625ff5acea7d9a1f8
|
||||
// but it seems to be a troublemaker, causing duplicated conversions
|
||||
//convert_to_base();
|
||||
}
|
||||
|
||||
standard_use_type(void* data, exchange_type type, indicator& ind,
|
||||
bool readOnly, std::string const& name = std::string())
|
||||
: data_(data)
|
||||
, type_(type)
|
||||
, ind_(&ind)
|
||||
, readOnly_(readOnly)
|
||||
, name_(name)
|
||||
, backEnd_(NULL)
|
||||
{
|
||||
// FIXME
|
||||
//convert_to_base();
|
||||
}
|
||||
|
||||
virtual ~standard_use_type();
|
||||
virtual void bind(statement_impl & st, int & position);
|
||||
virtual std::string get_name() const { return name_; }
|
||||
virtual void dump_value(std::ostream& os) const;
|
||||
virtual void * get_data() { return data_; }
|
||||
|
||||
// conversion hook (from arbitrary user type to base type)
|
||||
virtual void convert_to_base() {}
|
||||
virtual void convert_from_base() {}
|
||||
|
||||
protected:
|
||||
virtual void pre_use();
|
||||
|
||||
private:
|
||||
virtual void post_use(bool gotData);
|
||||
virtual void clean_up();
|
||||
virtual std::size_t size() const { return 1; }
|
||||
|
||||
void* data_;
|
||||
exchange_type type_;
|
||||
indicator* ind_;
|
||||
bool readOnly_;
|
||||
std::string name_;
|
||||
|
||||
standard_use_type_backend* backEnd_;
|
||||
};
|
||||
|
||||
class SOCI_DECL vector_use_type : public use_type_base
|
||||
{
|
||||
public:
|
||||
vector_use_type(void* data, exchange_type type,
|
||||
std::string const& name = std::string())
|
||||
: data_(data)
|
||||
, type_(type)
|
||||
, ind_(NULL)
|
||||
, name_(name)
|
||||
, backEnd_(NULL)
|
||||
{}
|
||||
|
||||
vector_use_type(void* data, exchange_type type,
|
||||
std::vector<indicator> const& ind,
|
||||
std::string const& name = std::string())
|
||||
: data_(data)
|
||||
, type_(type)
|
||||
, ind_(&ind)
|
||||
, name_(name)
|
||||
, backEnd_(NULL)
|
||||
{}
|
||||
|
||||
~vector_use_type();
|
||||
|
||||
private:
|
||||
virtual void bind(statement_impl& st, int & position);
|
||||
virtual std::string get_name() const { return name_; }
|
||||
virtual void dump_value(std::ostream& os) const;
|
||||
virtual void pre_use();
|
||||
virtual void post_use(bool) { /* nothing to do */ }
|
||||
virtual void clean_up();
|
||||
virtual std::size_t size() const;
|
||||
|
||||
void* data_;
|
||||
exchange_type type_;
|
||||
std::vector<indicator> const* ind_;
|
||||
std::string name_;
|
||||
|
||||
vector_use_type_backend * backEnd_;
|
||||
|
||||
virtual void convert_to_base() {}
|
||||
};
|
||||
|
||||
// implementation for the basic types (those which are supported by the library
|
||||
// out of the box without user-provided conversions)
|
||||
|
||||
template <typename T>
|
||||
class use_type : public standard_use_type
|
||||
{
|
||||
public:
|
||||
use_type(T& t, std::string const& name = std::string())
|
||||
: standard_use_type(&t,
|
||||
static_cast<exchange_type>(exchange_traits<T>::x_type), false, name)
|
||||
{}
|
||||
|
||||
use_type(T const& t, std::string const& name = std::string())
|
||||
: standard_use_type(const_cast<T*>(&t),
|
||||
static_cast<exchange_type>(exchange_traits<T>::x_type), true, name)
|
||||
{}
|
||||
|
||||
use_type(T& t, indicator& ind, std::string const& name = std::string())
|
||||
: standard_use_type(&t,
|
||||
static_cast<exchange_type>(exchange_traits<T>::x_type), ind, false, name)
|
||||
{}
|
||||
|
||||
use_type(T const& t, indicator& ind, std::string const& name = std::string())
|
||||
: standard_use_type(const_cast<T*>(&t),
|
||||
static_cast<exchange_type>(exchange_traits<T>::x_type), ind, false, name)
|
||||
{}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class use_type<std::vector<T> > : public vector_use_type
|
||||
{
|
||||
public:
|
||||
use_type(std::vector<T>& v, std::string const& name = std::string())
|
||||
: vector_use_type(&v,
|
||||
static_cast<exchange_type>(exchange_traits<T>::x_type), name)
|
||||
{}
|
||||
|
||||
use_type(std::vector<T> const& v, std::string const& name = std::string())
|
||||
: vector_use_type(const_cast<std::vector<T>*>(&v),
|
||||
static_cast<exchange_type>(exchange_traits<T>::x_type), name)
|
||||
{}
|
||||
|
||||
use_type(std::vector<T>& v, std::vector<indicator> const& ind,
|
||||
std::string const& name = std::string())
|
||||
: vector_use_type(&v,
|
||||
static_cast<exchange_type>(exchange_traits<T>::x_type), ind, name)
|
||||
{}
|
||||
|
||||
use_type(std::vector<T> const& v, std::vector<indicator> const& ind,
|
||||
std::string const& name = std::string())
|
||||
: vector_use_type(const_cast<std::vector<T> *>(&v),
|
||||
static_cast<exchange_type>(exchange_traits<T>::x_type), ind, name)
|
||||
{}
|
||||
};
|
||||
|
||||
// helper dispatchers for basic types
|
||||
|
||||
template <typename T>
|
||||
use_type_ptr do_use(T & t, std::string const & name, basic_type_tag)
|
||||
{
|
||||
return use_type_ptr(new use_type<T>(t, name));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
use_type_ptr do_use(T const & t, std::string const & name, basic_type_tag)
|
||||
{
|
||||
return use_type_ptr(new use_type<T>(t, name));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
use_type_ptr do_use(T & t, indicator & ind,
|
||||
std::string const & name, basic_type_tag)
|
||||
{
|
||||
return use_type_ptr(new use_type<T>(t, ind, name));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
use_type_ptr do_use(T const & t, indicator & ind,
|
||||
std::string const & name, basic_type_tag)
|
||||
{
|
||||
return use_type_ptr(new use_type<T>(t, ind, name));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
use_type_ptr do_use(T & t, std::vector<indicator> & ind,
|
||||
std::string const & name, basic_type_tag)
|
||||
{
|
||||
return use_type_ptr(new use_type<T>(t, ind, name));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
use_type_ptr do_use(T const & t, std::vector<indicator> & ind,
|
||||
std::string const & name, basic_type_tag)
|
||||
{
|
||||
return use_type_ptr(new use_type<T>(t, ind, name));
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namesapce soci
|
||||
|
||||
#endif // SOCI_USE_TYPE_H_INCLUDED
|
||||
78
src/soci/include/soci/use.h
Normal file
78
src/soci/include/soci/use.h
Normal file
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_USE_H_INCLUDED
|
||||
#define SOCI_USE_H_INCLUDED
|
||||
|
||||
#include "soci/use-type.h"
|
||||
#include "soci/exchange-traits.h"
|
||||
#include "soci/type-conversion.h"
|
||||
#include "soci/soci-backend.h"
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
template <typename T, typename Indicator>
|
||||
struct use_container
|
||||
{
|
||||
use_container(T &_t, Indicator &_ind, const std::string &_name)
|
||||
: t(_t), ind(_ind), name(_name) {}
|
||||
|
||||
T &t;
|
||||
Indicator &ind;
|
||||
const std::string &name;
|
||||
private:
|
||||
SOCI_NOT_ASSIGNABLE(use_container)
|
||||
};
|
||||
|
||||
typedef void no_indicator;
|
||||
template <typename T>
|
||||
struct use_container<T, no_indicator>
|
||||
{
|
||||
use_container(T &_t, const std::string &_name)
|
||||
: t(_t), name(_name) {}
|
||||
|
||||
T &t;
|
||||
const std::string &name;
|
||||
private:
|
||||
SOCI_NOT_ASSIGNABLE(use_container)
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
template <typename T>
|
||||
details::use_container<T, details::no_indicator> use(T &t, const std::string &name = std::string())
|
||||
{ return details::use_container<T, details::no_indicator>(t, name); }
|
||||
|
||||
template <typename T>
|
||||
details::use_container<const T, details::no_indicator> use(T const &t, const std::string &name = std::string())
|
||||
{ return details::use_container<const T, details::no_indicator>(t, name); }
|
||||
|
||||
template <typename T>
|
||||
details::use_container<T, indicator> use(T &t, indicator & ind, std::string const &name = std::string())
|
||||
{ return details::use_container<T, indicator>(t, ind, name); }
|
||||
|
||||
template <typename T>
|
||||
details::use_container<const T, indicator> use(T const &t, indicator & ind, std::string const &name = std::string())
|
||||
{ return details::use_container<const T, indicator>(t, ind, name); }
|
||||
|
||||
// vector containers
|
||||
template <typename T>
|
||||
details::use_container<T, std::vector<indicator> >
|
||||
use(T &t, std::vector<indicator> & ind, const std::string &name = std::string())
|
||||
{ return details::use_container<T, std::vector<indicator> >(t, ind, name); }
|
||||
|
||||
template <typename T>
|
||||
details::use_container<std::vector<T>, details::no_indicator >
|
||||
use(std::vector<T> &t, const std::string &name = std::string())
|
||||
{ return details::use_container<std::vector<T>, details::no_indicator>(t, name); }
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_USE_H_INCLUDED
|
||||
148
src/soci/include/soci/values-exchange.h
Normal file
148
src/soci/include/soci/values-exchange.h
Normal file
@@ -0,0 +1,148 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_VALUES_EXCHANGE_H_INCLUDED
|
||||
#define SOCI_VALUES_EXCHANGE_H_INCLUDED
|
||||
|
||||
#include "soci/values.h"
|
||||
#include "soci/into-type.h"
|
||||
#include "soci/use-type.h"
|
||||
#include "soci/row-exchange.h"
|
||||
// std
|
||||
#include <cstddef>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
template <>
|
||||
struct exchange_traits<values>
|
||||
{
|
||||
typedef basic_type_tag type_family;
|
||||
|
||||
// dummy value to satisfy the template engine, never used
|
||||
enum { x_type = 0 };
|
||||
};
|
||||
|
||||
template <>
|
||||
class use_type<values> : public use_type_base
|
||||
{
|
||||
public:
|
||||
use_type(values & v, std::string const & /*name*/ = std::string())
|
||||
: v_(v)
|
||||
{}
|
||||
|
||||
// we ignore the possibility to have the whole values as NULL
|
||||
use_type(values & v, indicator /*ind*/, std::string const & /*name*/ = std::string())
|
||||
: v_(v)
|
||||
{}
|
||||
|
||||
virtual void bind(details::statement_impl & st, int & /*position*/)
|
||||
{
|
||||
v_.uppercase_column_names(st.session_.get_uppercase_column_names());
|
||||
|
||||
convert_to_base();
|
||||
st.bind(v_);
|
||||
}
|
||||
|
||||
virtual std::string get_name() const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
||||
oss << "(";
|
||||
|
||||
std::size_t const num_columns = v_.get_number_of_columns();
|
||||
for (std::size_t n = 0; n < num_columns; ++n)
|
||||
{
|
||||
if (n != 0)
|
||||
oss << ", ";
|
||||
|
||||
oss << v_.get_properties(n).get_name();
|
||||
}
|
||||
|
||||
oss << ")";
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
virtual void dump_value(std::ostream& os) const
|
||||
{
|
||||
// TODO: Dump all columns.
|
||||
os << "<value>";
|
||||
}
|
||||
|
||||
virtual void post_use(bool /*gotData*/)
|
||||
{
|
||||
v_.reset_get_counter();
|
||||
convert_from_base();
|
||||
}
|
||||
|
||||
virtual void pre_use() {convert_to_base();}
|
||||
virtual void clean_up() {v_.clean_up();}
|
||||
virtual std::size_t size() const { return 1; }
|
||||
|
||||
// these are used only to re-dispatch to derived class
|
||||
// (the derived class might be generated automatically by
|
||||
// user conversions)
|
||||
virtual void convert_to_base() {}
|
||||
virtual void convert_from_base() {}
|
||||
|
||||
private:
|
||||
values & v_;
|
||||
|
||||
SOCI_NOT_COPYABLE(use_type)
|
||||
};
|
||||
|
||||
// this is not supposed to be used - no support for bulk ORM
|
||||
template <>
|
||||
class use_type<std::vector<values> >
|
||||
{
|
||||
private:
|
||||
use_type();
|
||||
};
|
||||
|
||||
template <>
|
||||
class into_type<values> : public into_type<row>
|
||||
{
|
||||
public:
|
||||
into_type(values & v)
|
||||
: into_type<row>(v.get_row()), v_(v)
|
||||
{}
|
||||
|
||||
into_type(values & v, indicator & ind)
|
||||
: into_type<row>(v.get_row(), ind), v_(v)
|
||||
{}
|
||||
|
||||
void clean_up()
|
||||
{
|
||||
v_.clean_up();
|
||||
}
|
||||
|
||||
private:
|
||||
values & v_;
|
||||
|
||||
SOCI_NOT_COPYABLE(into_type)
|
||||
};
|
||||
|
||||
// this is not supposed to be used - no support for bulk ORM
|
||||
template <>
|
||||
class into_type<std::vector<values> >
|
||||
{
|
||||
private:
|
||||
into_type();
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_VALUES_EXCHANGE_H_INCLUDED
|
||||
354
src/soci/include/soci/values.h
Normal file
354
src/soci/include/soci/values.h
Normal file
@@ -0,0 +1,354 @@
|
||||
//
|
||||
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_VALUES_H_INCLUDED
|
||||
#define SOCI_VALUES_H_INCLUDED
|
||||
|
||||
#include "soci/statement.h"
|
||||
#include "soci/into-type.h"
|
||||
#include "soci/use-type.h"
|
||||
// std
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace soci
|
||||
{
|
||||
|
||||
namespace details
|
||||
{
|
||||
|
||||
class copy_base
|
||||
{
|
||||
public:
|
||||
virtual ~copy_base() {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct copy_holder : public copy_base
|
||||
{
|
||||
copy_holder(T const & v) : value_(v) {}
|
||||
|
||||
T value_;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
class SOCI_DECL values
|
||||
{
|
||||
friend class details::statement_impl;
|
||||
friend class details::into_type<values>;
|
||||
friend class details::use_type<values>;
|
||||
|
||||
public:
|
||||
|
||||
values() : row_(NULL), currentPos_(0), uppercaseColumnNames_(false) {}
|
||||
|
||||
indicator get_indicator(std::size_t pos) const;
|
||||
indicator get_indicator(std::string const & name) const;
|
||||
|
||||
template <typename T>
|
||||
T get(std::size_t pos) const
|
||||
{
|
||||
if (row_ != NULL)
|
||||
{
|
||||
return row_->get<T>(pos);
|
||||
}
|
||||
else if (*indicators_[pos] != i_null)
|
||||
{
|
||||
return get_from_uses<T>(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg << "Column at position "
|
||||
<< static_cast<unsigned long>(pos)
|
||||
<< " contains NULL value and no default was provided";
|
||||
throw soci_error(msg.str());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get(std::size_t pos, T const & nullValue) const
|
||||
{
|
||||
if (row_ != NULL)
|
||||
{
|
||||
return row_->get<T>(pos, nullValue);
|
||||
}
|
||||
else if (*indicators_[pos] == i_null)
|
||||
{
|
||||
return nullValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return get_from_uses<T>(pos);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get(std::string const & name) const
|
||||
{
|
||||
return row_ != NULL ? row_->get<T>(name) : get_from_uses<T>(name);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get(std::string const & name, T const & nullValue) const
|
||||
{
|
||||
return row_ != NULL
|
||||
? row_->get<T>(name, nullValue)
|
||||
: get_from_uses<T>(name, nullValue);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
values const & operator>>(T & value) const
|
||||
{
|
||||
if (row_ != NULL)
|
||||
{
|
||||
// row maintains its own position counter
|
||||
// which is automatically reset when needed
|
||||
|
||||
*row_ >> value;
|
||||
}
|
||||
else if (*indicators_[currentPos_] != i_null)
|
||||
{
|
||||
// if there is no row object, then the data can be
|
||||
// extracted from the locally stored use elements,
|
||||
// but for this the position counter has to be maintained
|
||||
// as well
|
||||
|
||||
value = get_from_uses<T>(currentPos_);
|
||||
++currentPos_;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg << "Column at position "
|
||||
<< static_cast<unsigned long>(currentPos_)
|
||||
<< " contains NULL value and no default was provided";
|
||||
throw soci_error(msg.str());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void skip(std::size_t num = 1) const
|
||||
{
|
||||
if (row_ != NULL)
|
||||
{
|
||||
row_->skip(num);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentPos_ += num;
|
||||
}
|
||||
}
|
||||
|
||||
void reset_get_counter() const
|
||||
{
|
||||
if (row_ != NULL)
|
||||
{
|
||||
row_->reset_get_counter();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentPos_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void set(std::string const & name, T const & value, indicator indic = i_ok)
|
||||
{
|
||||
typedef typename type_conversion<T>::base_type base_type;
|
||||
if(index_.find(name) == index_.end())
|
||||
{
|
||||
index_.insert(std::make_pair(name, uses_.size()));
|
||||
|
||||
indicator * pind = new indicator(indic);
|
||||
indicators_.push_back(pind);
|
||||
|
||||
base_type baseValue;
|
||||
if (indic == i_ok)
|
||||
{
|
||||
type_conversion<T>::to_base(value, baseValue, *pind);
|
||||
}
|
||||
|
||||
details::copy_holder<base_type> * pcopy =
|
||||
new details::copy_holder<base_type>(baseValue);
|
||||
deepCopies_.push_back(pcopy);
|
||||
|
||||
uses_.push_back(new details::use_type<base_type>(
|
||||
pcopy->value_, *pind, name));
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t index = index_.find(name)->second;
|
||||
*indicators_[index] = indic;
|
||||
if (indic == i_ok)
|
||||
{
|
||||
type_conversion<T>::to_base(
|
||||
value,
|
||||
static_cast<details::copy_holder<base_type>*>(deepCopies_[index])->value_,
|
||||
*indicators_[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void set(const T & value, indicator indic = i_ok)
|
||||
{
|
||||
indicator * pind = new indicator(indic);
|
||||
indicators_.push_back(pind);
|
||||
|
||||
typedef typename type_conversion<T>::base_type base_type;
|
||||
base_type baseValue;
|
||||
type_conversion<T>::to_base(value, baseValue, *pind);
|
||||
|
||||
details::copy_holder<base_type> * pcopy =
|
||||
new details::copy_holder<base_type>(baseValue);
|
||||
deepCopies_.push_back(pcopy);
|
||||
|
||||
uses_.push_back(new details::use_type<base_type>(
|
||||
pcopy->value_, *pind));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
values & operator<<(T const & value)
|
||||
{
|
||||
set(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void uppercase_column_names(bool forceToUpper)
|
||||
{
|
||||
uppercaseColumnNames_ = forceToUpper;
|
||||
}
|
||||
|
||||
std::size_t get_number_of_columns() const
|
||||
{
|
||||
return row_ ? row_->size() : 0;
|
||||
}
|
||||
|
||||
column_properties const& get_properties(std::size_t pos) const;
|
||||
column_properties const& get_properties(std::string const &name) const;
|
||||
|
||||
private:
|
||||
|
||||
//TODO To make values generally usable outside of type_conversion's,
|
||||
// these should be reference counted smart pointers
|
||||
row * row_;
|
||||
std::vector<details::standard_use_type *> uses_;
|
||||
std::map<details::use_type_base *, indicator *> unused_;
|
||||
std::vector<indicator *> indicators_;
|
||||
std::map<std::string, std::size_t> index_;
|
||||
std::vector<details::copy_base *> deepCopies_;
|
||||
|
||||
mutable std::size_t currentPos_;
|
||||
|
||||
bool uppercaseColumnNames_;
|
||||
|
||||
// When type_conversion::to() is called, a values object is created
|
||||
// without an underlying row object. In that case, get_from_uses()
|
||||
// returns the underlying field values
|
||||
template <typename T>
|
||||
T get_from_uses(std::string const & name, T const & nullValue) const
|
||||
{
|
||||
std::map<std::string, std::size_t>::const_iterator pos = index_.find(name);
|
||||
if (pos != index_.end())
|
||||
{
|
||||
if (*indicators_[pos->second] == i_null)
|
||||
{
|
||||
return nullValue;
|
||||
}
|
||||
|
||||
return get_from_uses<T>(pos->second);
|
||||
}
|
||||
throw soci_error("Value named " + name + " not found.");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get_from_uses(std::string const & name) const
|
||||
{
|
||||
std::map<std::string, std::size_t>::const_iterator pos = index_.find(name);
|
||||
if (pos != index_.end())
|
||||
{
|
||||
return get_from_uses<T>(pos->second);
|
||||
}
|
||||
throw soci_error("Value named " + name + " not found.");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get_from_uses(std::size_t pos) const
|
||||
{
|
||||
details::standard_use_type* u = uses_[pos];
|
||||
|
||||
typedef typename type_conversion<T>::base_type base_type;
|
||||
|
||||
if (dynamic_cast<details::use_type<base_type> *>(u))
|
||||
{
|
||||
base_type const & baseValue = *static_cast<base_type*>(u->get_data());
|
||||
|
||||
T val;
|
||||
indicator ind = *indicators_[pos];
|
||||
type_conversion<T>::from_base(baseValue, ind, val);
|
||||
return val;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg << "Value at position "
|
||||
<< static_cast<unsigned long>(pos)
|
||||
<< " was set using a different type"
|
||||
" than the one passed to get()";
|
||||
throw soci_error(msg.str());
|
||||
}
|
||||
}
|
||||
|
||||
row& get_row()
|
||||
{
|
||||
row_ = new row();
|
||||
row_->uppercase_column_names(uppercaseColumnNames_);
|
||||
|
||||
return * row_;
|
||||
}
|
||||
|
||||
// this is called by Statement::bind(values)
|
||||
void add_unused(details::use_type_base * u, indicator * i)
|
||||
{
|
||||
static_cast<details::standard_use_type *>(u)->convert_to_base();
|
||||
unused_.insert(std::make_pair(u, i));
|
||||
}
|
||||
|
||||
// this is called by details::into_type<values>::clean_up()
|
||||
// and use_type<values>::clean_up()
|
||||
void clean_up()
|
||||
{
|
||||
delete row_;
|
||||
row_ = NULL;
|
||||
|
||||
// delete any uses and indicators which were created by set() but
|
||||
// were not bound by the Statement
|
||||
// (bound uses and indicators are deleted in Statement::clean_up())
|
||||
for (std::map<details::use_type_base *, indicator *>::iterator pos =
|
||||
unused_.begin(); pos != unused_.end(); ++pos)
|
||||
{
|
||||
delete pos->first;
|
||||
delete pos->second;
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i != deepCopies_.size(); ++i)
|
||||
{
|
||||
delete deepCopies_[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace soci
|
||||
|
||||
#endif // SOCI_VALUES_H_INCLUDED
|
||||
34
src/soci/include/soci/version.h
Normal file
34
src/soci/include/soci/version.h
Normal file
@@ -0,0 +1,34 @@
|
||||
// SOCI version.hpp configuration header file
|
||||
|
||||
//
|
||||
// Copyright (C) 2011 Mateusz Loskot <mateusz@loskot.net>
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef SOCI_VERSION_HPP
|
||||
#define SOCI_VERSION_HPP
|
||||
|
||||
// When updating the version here, don't forget to update it in CMakeLists.txt!
|
||||
|
||||
//
|
||||
// Caution, this is the only SOCI header that is guarenteed
|
||||
// to change with every SOCI release, including this header
|
||||
// will cause a recompile every time a new SOCI version is
|
||||
// released.
|
||||
//
|
||||
// SOCI_VERSION % 100 is the patch level
|
||||
// SOCI_VERSION / 100 % 1000 is the minor version
|
||||
// SOCI_VERSION / 100000 is the major version
|
||||
|
||||
#define SOCI_VERSION 400000
|
||||
|
||||
//
|
||||
// SOCI_LIB_VERSION must be defined to be the same as SOCI_VERSION
|
||||
// but as a *string* in the form "x_y[_z]" where x is the major version
|
||||
// number, y is the minor version number, and z is the patch level if not 0.
|
||||
|
||||
#define SOCI_LIB_VERSION "4_0_0"
|
||||
|
||||
#endif // SOCI_VERSION_HPP
|
||||
Reference in New Issue
Block a user