项目配置更新

增加debug参数

更新三方库

稳定性优化

增加模块:http客户端、编解码、sqlserver客户端、时间、锁
This commit is contained in:
xx
2024-05-27 20:48:45 +08:00
parent e718d01e85
commit 6128e2064b
127 changed files with 11762 additions and 113 deletions

View 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.

View File

@@ -0,0 +1,266 @@
//
// 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 "soci-compiler.h"
#include <cstdint>
#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);
// Copy contents of a BLOB in buf into the given string.
void copy_from_blob(firebird_statement_backend &st, char *buf, std::string &out);
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:
{
int16_t tmp = static_cast<int16_t>(round_for_isc(value*multiplier)/divisor);
std::memcpy(var->sqldata, &tmp, sizeof(int16_t));
}
break;
case SQL_LONG:
{
int32_t tmp = static_cast<int32_t>(round_for_isc(value*multiplier)/divisor);
std::memcpy(var->sqldata, &tmp, sizeof(int32_t));
}
break;
case SQL_INT64:
{
int64_t tmp = static_cast<int64_t>(round_for_isc(value*multiplier)/divisor);
std::memcpy(var->sqldata, &tmp, sizeof(int64_t));
}
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;
}
}
SOCI_GCC_WARNING_SUPPRESS(cast-align)
switch (var->sqltype & ~1)
{
case SQL_SHORT:
return static_cast<T1>(*reinterpret_cast<int16_t*>(var->sqldata)/tens);
case SQL_LONG:
return static_cast<T1>(*reinterpret_cast<int32_t*>(var->sqldata)/tens);
case SQL_INT64:
return static_cast<T1>(*reinterpret_cast<int64_t*>(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");
}
SOCI_GCC_WARNING_RESTORE(cast-align)
}
} // namespace firebird
} // namespace details
} // namespace soci
#endif // SOCI_FIREBIRD_COMMON_H_INCLUDED

View 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

View File

@@ -0,0 +1,42 @@
//
// Copyright (C) 2020 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_AUTOSTATEMENT_H_INCLUDED
#define SOCI_PRIVATE_SOCI_AUTOSTATEMENT_H_INCLUDED
namespace soci
{
namespace details
{
// This helper class can be used with any statement backend to initialize and
// cleanup a statement backend object in a RAII way. Normally this is not
// needed because it's done by statement_impl, but this can be handy when using
// a concrete backend inside this backend own code, see e.g. ODBC session
// implementation.
template <typename Backend>
struct auto_statement : Backend
{
template <typename Session>
explicit auto_statement(Session& session)
: Backend(session)
{
this->alloc();
}
~auto_statement() override
{
this->clean_up();
}
};
} // namespace details
} // namespace soci
#endif // SOCI_PRIVATE_SOCI_AUTOSTATEMENT_H_INCLUDED

View 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"
// SOCI_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 SOCI_CHECK_GCC(major, minor) \
((__GNUC__ > (major)) \
|| (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
#else
# define SOCI_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__) || SOCI_CHECK_GCC(4, 6)
# define SOCI_GCC_WARNING_SUPPRESS(x) \
_Pragma (SOCI_STRINGIZE(GCC diagnostic push)) \
_Pragma (SOCI_STRINGIZE(GCC diagnostic ignored SOCI_STRINGIZE(SOCI_CONCAT(-W,x))))
# define SOCI_GCC_WARNING_RESTORE(x) \
_Pragma (SOCI_STRINGIZE(GCC diagnostic pop))
#else /* gcc < 4.6 or not gcc and not clang at all */
# define SOCI_GCC_WARNING_SUPPRESS(x)
# define SOCI_GCC_WARNING_RESTORE(x)
#endif
#endif // SOCI_PRIVATE_SOCI_COMPILER_H_INCLUDED

View 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

View 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

View File

@@ -0,0 +1,87 @@
//
// Copyright (C) 2020 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_CSTRTOI_H_INCLUDED
#define SOCI_PRIVATE_SOCI_CSTRTOI_H_INCLUDED
#include "soci/error.h"
#include <cstdlib>
#include <limits>
namespace soci
{
namespace details
{
// Convert string to a signed value of the given type, checking for overflow.
//
// Fill the provided result parameter and return true on success or false on
// error, e.g. if the string couldn't be converted at all, if anything remains
// in the string after conversion or if the value is out of range.
template <typename T>
bool cstring_to_integer(T& result, char const* buf)
{
char * end;
// No strtoll() on MSVC versions prior to Visual Studio 2013
#if !defined (_MSC_VER) || (_MSC_VER >= 1800)
long long t = strtoll(buf, &end, 10);
#else
long long t = _strtoi64(buf, &end, 10);
#endif
if (end == buf || *end != '\0')
return false;
// successfully converted to long long
// and no other characters were found in the buffer
const T max = (std::numeric_limits<T>::max)();
const T min = (std::numeric_limits<T>::min)();
if (t > static_cast<long long>(max) || t < static_cast<long long>(min))
return false;
result = static_cast<T>(t);
return true;
}
// Similar to the above, but for the unsigned integral types.
template <typename T>
bool cstring_to_unsigned(T& result, char const* buf)
{
char * end;
// No strtoll() on MSVC versions prior to Visual Studio 2013
#if !defined (_MSC_VER) || (_MSC_VER >= 1800)
unsigned long long t = strtoull(buf, &end, 10);
#else
unsigned long long t = _strtoui64(buf, &end, 10);
#endif
if (end == buf || *end != '\0')
return false;
// successfully converted to unsigned long long
// and no other characters were found in the buffer
const T max = (std::numeric_limits<T>::max)();
if (t > static_cast<unsigned long long>(max))
return false;
result = static_cast<T>(t);
return true;
}
} // namespace details
} // namespace soci
#endif // SOCI_PRIVATE_SOCI_CSTRTOI_H_INCLUDED

View 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

View File

@@ -0,0 +1,129 @@
//
// 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 "soci/type-wrappers.h"
#include "soci/blob.h"
#include <cstdint>
#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_int8>
{
typedef int8_t value_type;
};
template <>
struct exchange_type_traits<x_uint8>
{
typedef uint8_t value_type;
};
template <>
struct exchange_type_traits<x_int16>
{
typedef int16_t value_type;
};
template <>
struct exchange_type_traits<x_uint16>
{
typedef uint16_t value_type;
};
template <>
struct exchange_type_traits<x_int32>
{
typedef int32_t value_type;
};
template <>
struct exchange_type_traits<x_uint32>
{
typedef uint32_t value_type;
};
template <>
struct exchange_type_traits<x_int64>
{
typedef int64_t value_type;
};
template <>
struct exchange_type_traits<x_uint64>
{
typedef uint64_t 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;
};
template <>
struct exchange_type_traits<x_longstring>
{
typedef long_string value_type;
};
template <>
struct exchange_type_traits<x_xmltype>
{
typedef xml_type value_type;
};
template <>
struct exchange_type_traits<x_blob>
{
typedef blob 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

View File

@@ -0,0 +1,69 @@
//
// 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>
#ifdef _WIN32
#define timegm _mkgmtime
#endif
namespace soci
{
namespace details
{
SOCI_DECL time_t timegm_impl_soci ( struct tm* tb );
template <typename T>
auto timegm_impl(T* t) -> decltype(timegm(t))
{
return timegm(t);
}
template <typename T>
auto timegm_impl(T t) -> time_t
{
return timegm_impl_soci(t);
}
// 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;
timegm_impl(&t);
}
// Helper function for parsing datetime values.
//
// Throws if the string in buf couldn't be parsed as a date or a time string.
SOCI_DECL void parse_std_tm(char const *buf, std::tm &t);
} // namespace details
} // namespace soci
#endif // SOCI_PRIVATE_SOCI_MKTIME_H_INCLUDED

View File

@@ -0,0 +1,82 @@
#ifndef SOCI_PRIVATE_SOCI_TRIVIAL_BLOB_BACKEND_H_INCLUDED
#define SOCI_PRIVATE_SOCI_TRIVIAL_BLOB_BACKEND_H_INCLUDED
#include "soci/soci-backend.h"
#include <vector>
#include <cstring>
#include <cstdint>
namespace soci
{
namespace details
{
/**
* This Blob implementation uses an explicit buffer that is read from and written to, instead of
* directly communicating with the underlying database.
* Thus, it is intended to be used whenever the underlying database does not offer a more efficient
* way of dealing with BLOBs.
*/
class trivial_blob_backend : public details::blob_backend
{
public:
std::size_t get_len() override { return buffer_.size(); }
std::size_t read_from_start(void* buf, std::size_t toRead,
std::size_t offset = 0) override
{
if (offset > buffer_.size() || (offset == buffer_.size() && offset > 0))
{
throw soci_error("Can't read past-the-end of BLOB data.");
}
// make sure that we don't try to read
// past the end of the data
toRead = std::min<decltype(toRead)>(toRead, buffer_.size() - offset);
memcpy(buf, buffer_.data() + offset, toRead);
return toRead;
}
std::size_t write_from_start(const void* buf, std::size_t toWrite,
std::size_t offset = 0) override
{
if (offset > buffer_.size())
{
throw soci_error("Can't start writing far past-the-end of BLOB data.");
}
buffer_.resize(std::max<std::size_t>(buffer_.size(), offset + toWrite));
memcpy(buffer_.data() + offset, buf, toWrite);
return toWrite;
}
std::size_t append(void const* buf, std::size_t toWrite) override
{
return write_from_start(buf, toWrite, buffer_.size());
}
void trim(std::size_t newLen) override { buffer_.resize(newLen); }
std::size_t set_data(void const* buf, std::size_t toWrite)
{
buffer_.clear();
return write_from_start(buf, toWrite);
}
const std::uint8_t *get_buffer() const { return buffer_.data(); }
protected:
std::vector< std::uint8_t > buffer_;
};
}
}
#endif // SOCI_PRIVATE_SOCI_TRIVIAL_BLOB_BACKEND_H_INCLUDED

View File

@@ -0,0 +1,157 @@
//
// Copyright (C) 2021 Sinitsyn Ilya
// 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_VECTOR_HELPERS_H_INCLUDED
#define SOCI_VECTOR_HELPERS_H_INCLUDED
#include "soci-exchange-cast.h"
namespace soci
{
namespace details
{
// Helper functions to work with vectors.
template <exchange_type e>
std::vector<typename exchange_type_traits<e>::value_type>& exchange_vector_type_cast(void *data)
{
return *static_cast<std::vector<typename exchange_type_traits<e>::value_type>*>(data);
}
// Get the size of the vector.
inline std::size_t get_vector_size(exchange_type e, void *data)
{
switch (e)
{
case x_char:
return exchange_vector_type_cast<x_char>(data).size();
case x_stdstring:
return exchange_vector_type_cast<x_stdstring>(data).size();
case x_int8:
return exchange_vector_type_cast<x_int8>(data).size();
case x_uint8:
return exchange_vector_type_cast<x_uint8>(data).size();
case x_int16:
return exchange_vector_type_cast<x_int16>(data).size();
case x_uint16:
return exchange_vector_type_cast<x_uint16>(data).size();
case x_int32:
return exchange_vector_type_cast<x_int32>(data).size();
case x_uint32:
return exchange_vector_type_cast<x_uint32>(data).size();
case x_int64:
return exchange_vector_type_cast<x_int64>(data).size();
case x_uint64:
return exchange_vector_type_cast<x_uint64>(data).size();
case x_double:
return exchange_vector_type_cast<x_double>(data).size();
case x_stdtm:
return exchange_vector_type_cast<x_stdtm>(data).size();
case x_xmltype:
return exchange_vector_type_cast<x_xmltype>(data).size();
case x_longstring:
return exchange_vector_type_cast<x_longstring>(data).size();
case x_statement:
case x_rowid:
case x_blob:
break;
}
throw soci_error("Failed to get the size of the vector of non-supported type.");
}
// Set the size of the vector.
inline void resize_vector(exchange_type e, void *data, std::size_t newSize)
{
switch (e)
{
case x_char:
exchange_vector_type_cast<x_char>(data).resize(newSize);
return;
case x_stdstring:
exchange_vector_type_cast<x_stdstring>(data).resize(newSize);
return;
case x_int8:
exchange_vector_type_cast<x_int8>(data).resize(newSize);
return;
case x_uint8:
exchange_vector_type_cast<x_uint8>(data).resize(newSize);
return;
case x_int16:
exchange_vector_type_cast<x_int16>(data).resize(newSize);
return;
case x_uint16:
exchange_vector_type_cast<x_uint16>(data).resize(newSize);
return;
case x_int32:
exchange_vector_type_cast<x_int32>(data).resize(newSize);
return;
case x_uint32:
exchange_vector_type_cast<x_uint32>(data).resize(newSize);
return;
case x_int64:
exchange_vector_type_cast<x_int64>(data).resize(newSize);
return;
case x_uint64:
exchange_vector_type_cast<x_uint64>(data).resize(newSize);
return;
case x_double:
exchange_vector_type_cast<x_double>(data).resize(newSize);
return;
case x_stdtm:
exchange_vector_type_cast<x_stdtm>(data).resize(newSize);
return;
case x_xmltype:
exchange_vector_type_cast<x_xmltype>(data).resize(newSize);
return;
case x_longstring:
exchange_vector_type_cast<x_longstring>(data).resize(newSize);
return;
case x_statement:
case x_rowid:
case x_blob:
break;
}
throw soci_error("Failed to get the size of the vector of non-supported type.");
}
// Get the string at the given index of the vector.
inline std::string& vector_string_value(exchange_type e, void *data, std::size_t ind)
{
switch (e)
{
case x_stdstring:
return exchange_vector_type_cast<x_stdstring>(data).at(ind);
case x_xmltype:
return exchange_vector_type_cast<x_xmltype>(data).at(ind).value;
case x_longstring:
return exchange_vector_type_cast<x_longstring>(data).at(ind).value;
case x_char:
case x_int8:
case x_uint8:
case x_int16:
case x_uint16:
case x_int32:
case x_uint32:
case x_int64:
case x_uint64:
case x_double:
case x_stdtm:
case x_statement:
case x_rowid:
case x_blob:
break;
}
throw soci_error("Can't get the string value from the vector of values with non-supported type.");
}
} // namespace details
} // namespace soci
#endif // SOCI_VECTOR_HELPERS_H_INCLUDED

View File

@@ -0,0 +1,40 @@
//
// 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
{
// only used internally and shouldn't/can't be used from outside the library,
// successful calls to get() should be matched by calls to unget() with the
// same name
backend_factory const & get(std::string const & name);
void unget(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

216
3rdparty/soci/include/soci/bind-values.h vendored Normal file
View File

@@ -0,0 +1,216 @@
#ifndef SOCI_BIND_VALUES_H_INCLUDED
#define SOCI_BIND_VALUES_H_INCLUDED
#include "soci/soci-platform.h"
#include "exchange-traits.h"
#include "into-type.h"
#include "into.h"
#include "soci-backend.h"
#include "use-type.h"
#include "use.h"
#ifdef SOCI_HAVE_BOOST
# include <boost/fusion/algorithm/iteration/for_each.hpp>
# include <boost/mpl/bool.hpp>
# include <boost/version.hpp>
# if BOOST_VERSION >= 106800
# define SOCI_BOOST_FUSION_FOREACH_REFERENCE &
# else
# define SOCI_BOOST_FUSION_FOREACH_REFERENCE
# endif
#endif // SOCI_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 SOCI_HAVE_BOOST
exchange_(uc, (typename boost::fusion::traits::is_sequence<T>::type *)NULL);
#else
exchange_(uc, NULL);
#endif // SOCI_HAVE_BOOST
}
private:
#ifdef SOCI_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 */)
{
use_sequence<T, Indicator> f(*this, uc.ind);
boost::fusion::for_each<T,
use_sequence<T, Indicator>
SOCI_BOOST_FUSION_FOREACH_REFERENCE>(uc.t, f);
}
template <typename T>
void exchange_(use_container<T, details::no_indicator> const &uc, boost::mpl::true_ * /* fusion sequence */)
{
use_sequence<T, details::no_indicator> f(*this);
boost::fusion::for_each<T,
use_sequence<T, details::no_indicator>
SOCI_BOOST_FUSION_FOREACH_REFERENCE>(uc.t, f);
}
#endif // SOCI_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 SOCI_HAVE_BOOST
exchange_(ic, (typename boost::fusion::traits::is_sequence<T>::type *)NULL);
#else
exchange_(ic, NULL);
#endif // SOCI_HAVE_BOOST
}
private:
#ifdef SOCI_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 */)
{
into_sequence<T, Indicator> f(*this, ic.ind);
boost::fusion::for_each<T,
into_sequence<T, Indicator>
SOCI_BOOST_FUSION_FOREACH_REFERENCE>(ic.t, f);
}
template <typename T>
void exchange_(into_container<T, details::no_indicator> const &ic, boost::mpl::true_ * /* fusion sequence */)
{
into_sequence<T, details::no_indicator> f(*this);
boost::fusion::for_each<T,
into_sequence<T, details::no_indicator>
SOCI_BOOST_FUSION_FOREACH_REFERENCE>(ic.t, f);
}
#endif // SOCI_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

View 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

84
3rdparty/soci/include/soci/blob.h vendored Normal file
View File

@@ -0,0 +1,84 @@
//
// 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>
#include <memory>
namespace soci
{
// basic blob operations
class session;
namespace details
{
class blob_backend;
} // namespace details
class SOCI_DECL blob
{
public:
// Creates an invalid blob object
blob() = default;
explicit blob(session & s);
~blob();
blob(blob &&other) = default;
blob &operator=(blob &&other) = default;
// Checks whether this blob is in a valid state
bool is_valid() const;
// (Re)initializes this blob
void initialize(session &s);
std::size_t get_len();
// offset is backend-specific
[[deprecated("Use read_from_start instead")]]
std::size_t read(std::size_t offset, void * buf, std::size_t toRead);
// Extracts data from this blob into the given buffer.
// At most toRead bytes are extracted (and copied into buf).
// The amount of actually read bytes is returned.
//
// Note: Using an offset > 0 on a blob whose size is less than
// or equal to offset, will throw an exception.
std::size_t read_from_start(void * buf, std::size_t toRead,
std::size_t offset = 0);
// offset is backend-specific
[[deprecated("Use write_from_start instead")]]
std::size_t write(std::size_t offset, const void * buf,
std::size_t toWrite);
// offset starts from 0
std::size_t write_from_start(const void * buf, std::size_t toWrite,
std::size_t offset = 0);
std::size_t append(const void * buf, std::size_t toWrite);
void trim(std::size_t newLen);
details::blob_backend * get_backend() { return backEnd_.get(); }
private:
SOCI_NOT_COPYABLE(blob)
std::unique_ptr<details::blob_backend> backEnd_;
void ensure_initialized();
};
} // namespace soci
#endif

View 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

View File

@@ -0,0 +1,50 @@
//
// 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);
}
struct move_from_base_check :
std::integral_constant<bool, false> {};
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

View File

@@ -0,0 +1,92 @@
//
// 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>
#include <boost/optional/optional_io.hpp>
namespace soci
{
// simple fall-back for boost::optional
template <typename T>
struct type_conversion<boost::optional<T> >
{
typedef typename type_conversion<T>::base_type base_type;
struct from_base_check : std::integral_constant<bool, true> {};
static void from_base(base_type const & in, indicator ind,
boost::optional<T> & out)
{
if (ind == i_null)
{
out.reset();
}
else
{
T tmp = T();
type_conversion<T>::from_base(in, ind, tmp);
out = tmp;
}
}
struct move_from_base_check :
std::integral_constant<bool,
!std::is_const<base_type>::value
&& std::is_constructible<boost::optional<T>, typename std::add_rvalue_reference<base_type>::type>::value
> {};
static void move_from_base(base_type & in, indicator ind, boost::optional<T> & out)
{
static_assert(move_from_base_check::value,
"move_to_base can only be used if the target type can be constructed from an rvalue base reference");
if (ind == i_null)
{
out.reset();
}
else
{
out = std::move(in);
}
}
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;
}
}
static void move_to_base(boost::optional<T> & in, base_type & out, indicator & ind)
{
if (in.is_initialized())
{
out = std::move(in.get());
ind = i_ok;
}
else
{
ind = i_null;
}
}
};
} // namespace soci
#endif // SOCI_BOOST_OPTIONAL_H_INCLUDED

View 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

47
3rdparty/soci/include/soci/callbacks.h vendored Normal file
View File

@@ -0,0 +1,47 @@
//
// Copyright (C) 2015 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_CALLBACKS_H_INCLUDED
#define SOCI_CALLBACKS_H_INCLUDED
namespace soci
{
class session;
// Simple callback interface for reporting failover events.
// The meaning of each operation is intended to be portable,
// but the behaviour details and parameters can be backend-specific.
class SOCI_DECL failover_callback
{
public:
// Called when the failover operation has started,
// after discovering connectivity problems.
virtual void started() {}
// Called after successful failover and creating a new connection;
// the sql parameter denotes the new connection and allows the user
// to replay any initial sequence of commands (like session configuration).
virtual void finished(session & /* sql */) {}
// Called when the attempt to reconnect failed,
// if the user code sets the retry parameter to true,
// then new connection will be attempted;
// the newTarget connection string is a hint that can be ignored
// by external means.
virtual void failed(bool & /* out */ /* retry */,
std::string & /* out */ /* newTarget */) {}
// Called when there was a failure that prevents further failover attempts.
virtual void aborted() {}
};
} // namespace soci
#endif // SOCI_CALLBACKS_H_INCLUDED

149
3rdparty/soci/include/soci/column-info.h vendored Normal file
View File

@@ -0,0 +1,149 @@
//
// Copyright (C) 2016 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_COLUMN_INFO_H_INCLUDED
#define SOCI_COLUMN_INFO_H_INCLUDED
#include "soci/soci-backend.h"
#include "soci/type-conversion.h"
#include "soci/values.h"
#include <cstdint>
namespace soci
{
struct SOCI_DECL column_info
{
std::string name;
// DEPRECATED. USE dataType INSTEAD.
data_type type;
db_type dataType;
std::size_t length; // meaningful for text columns only
std::size_t precision;
std::size_t scale;
bool nullable;
};
template <>
struct type_conversion<column_info>
{
typedef values base_type;
static std::size_t get_numeric_value(const values & v,
const std::string & field_name)
{
db_type dt = v.get_properties(field_name).get_db_type();
switch (dt)
{
case db_double:
return static_cast<std::size_t>(
v.get<double>(field_name, 0.0));
case db_int8:
return static_cast<std::size_t>(
v.get<int8_t>(field_name, 0));
case db_uint8:
return static_cast<std::size_t>(
v.get<uint8_t>(field_name, 0));
case db_int16:
return static_cast<std::size_t>(
v.get<int16_t>(field_name, 0));
case db_uint16:
return static_cast<std::size_t>(
v.get<uint16_t>(field_name, 0));
case db_int32:
return static_cast<std::size_t>(
v.get<int32_t>(field_name, 0));
case db_uint32:
return static_cast<std::size_t>(
v.get<uint32_t>(field_name, 0));
case db_int64:
return static_cast<std::size_t>(
v.get<int64_t>(field_name, 0ll));
case db_uint64:
return static_cast<std::size_t>(
v.get<uint64_t>(field_name, 0ull));
default:
return 0u;
}
}
static void from_base(values const & v, indicator /* ind */, column_info & ci)
{
ci.name = v.get<std::string>("COLUMN_NAME");
ci.length = get_numeric_value(v, "CHARACTER_MAXIMUM_LENGTH");
ci.precision = get_numeric_value(v, "NUMERIC_PRECISION");
ci.scale = get_numeric_value(v, "NUMERIC_SCALE");
const std::string & type_name = v.get<std::string>("DATA_TYPE");
if (type_name == "text" || type_name == "TEXT" ||
type_name == "clob" || type_name == "CLOB" ||
type_name.find("char") != std::string::npos ||
type_name.find("CHAR") != std::string::npos)
{
ci.type = dt_string;
ci.dataType = db_string;
}
else if (type_name == "integer" || type_name == "INTEGER")
{
ci.type = dt_integer;
ci.dataType = db_int32;
}
else if (type_name.find("number") != std::string::npos ||
type_name.find("NUMBER") != std::string::npos ||
type_name.find("numeric") != std::string::npos ||
type_name.find("NUMERIC") != std::string::npos)
{
if (ci.scale != 0)
{
ci.type = dt_double;
ci.dataType = db_double;
}
else
{
ci.type = dt_integer;
ci.dataType = db_int32;
}
}
else if (type_name.find("time") != std::string::npos ||
type_name.find("TIME") != std::string::npos ||
type_name.find("date") != std::string::npos ||
type_name.find("DATE") != std::string::npos)
{
ci.type = dt_date;
ci.dataType = db_date;
}
else if (type_name.find("blob") != std::string::npos ||
type_name.find("BLOB") != std::string::npos ||
type_name.find("oid") != std::string::npos ||
type_name.find("OID") != std::string::npos)
{
ci.type = dt_blob;
ci.dataType = db_blob;
}
else if (type_name.find("xml") != std::string::npos ||
type_name.find("XML") != std::string::npos)
{
ci.type = dt_xml;
ci.dataType = db_xml;
}
else
{
// this seems to be a safe default
ci.type = dt_string;
ci.dataType = db_string;
}
const std::string & nullable_s = v.get<std::string>("IS_NULLABLE");
ci.nullable = (nullable_s == "YES");
}
};
} // namespace soci
#endif // SOCI_COLUMN_INFO_H_INCLUDED

View File

@@ -0,0 +1,99 @@
//
// 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
{
// Names of some predefined options and their values.
extern SOCI_DECL char const * option_reconnect;
extern SOCI_DECL char const * option_true;
namespace details
{
class dynamic_backend_ref;
} // namespace details
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);
connection_parameters(connection_parameters const& other);
connection_parameters(connection_parameters && other);
connection_parameters& operator=(connection_parameters const& other);
connection_parameters& operator=(connection_parameters && other);
~connection_parameters();
// Retrieve the backend and the connection strings specified in the ctor.
backend_factory const * get_factory() const { return factory_; }
void set_connect_string(const std::string & connectString) { connectString_ = connectString; }
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;
}
// Return true if the option with the given name was found with option_true
// value.
bool is_option_on(const char * name) const
{
std::string value;
return get_option(name, value) && value == option_true;
}
private:
void reset_after_move();
// The backend and connection string specified in our ctor.
backend_factory const * factory_;
std::string connectString_;
// References the backend name used for obtaining the factor from
// dynamic_backends.
details::dynamic_backend_ref * backendRef_;
// 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

View File

@@ -0,0 +1,41 @@
//
// 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_;
SOCI_NOT_COPYABLE(connection_pool)
};
}
#endif // SOCI_CONNECTION_POOL_H_INCLUDED

View File

@@ -0,0 +1,293 @@
//
// 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
#include <soci/soci-platform.h>
#ifdef SOCI_DB2_SOURCE
# define SOCI_DB2_DECL SOCI_DECL_EXPORT
#else
# define SOCI_DB2_DECL SOCI_DECL_IMPORT
#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 SOCI_DB2_DECL db2_soci_error : public soci_error {
public:
db2_soci_error(std::string const & msg, SQLRETURN rc) : soci_error(msg),errorCode(rc) {};
~db2_soci_error() noexcept override { };
//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;
};
// 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 DB2 CLI, i.e. one of SQL_DRIVER_XXX
// (in string form as all options are strings currently).
extern SOCI_DB2_DECL char const * db2_option_driver_complete;
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) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch, indicator* ind) override;
void clean_up() override;
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) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator* ind) override;
void resize(std::size_t sz) override;
std::size_t size() override;
void clean_up() override;
db2_statement_backend& statement_;
void prepare_indicators(std::size_t size);
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) override;
void bind_by_name(std::string const& name, void* data, details::exchange_type type, bool readOnly) override;
void pre_use(indicator const* ind) override;
void post_use(bool gotData, indicator* ind) override;
void clean_up() override;
db2_statement_backend& statement_;
void *prepare_for_bind(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) override;
void bind_by_name(std::string const& name, void* data, details::exchange_type type) override;
void pre_use(indicator const* ind) override;
std::size_t size() override;
void clean_up() override;
db2_statement_backend& statement_;
void prepare_indicators(std::size_t size);
void *prepare_for_bind(SQLUINTEGER &size,SQLSMALLINT &sqlType, SQLSMALLINT &cType);
std::vector<SQLLEN> indVec;
void *data;
char *buf;
details::exchange_type type;
std::size_t colSize;
int position;
};
struct db2_session_backend;
struct SOCI_DB2_DECL db2_statement_backend : details::statement_backend
{
db2_statement_backend(db2_session_backend &session);
void alloc() override;
void clean_up() override;
void prepare(std::string const& query, details::statement_type eType) override;
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const& query) override;
int prepare_for_describe() override;
void describe_column(int colNum, db_type& dbtype, std::string& columnName) override;
size_t column_size(int col);
db2_standard_into_type_backend* make_into_type_backend() override;
db2_standard_use_type_backend* make_use_type_backend() override;
db2_vector_into_type_backend* make_vector_into_type_backend() override;
db2_vector_use_type_backend* make_vector_use_type_backend() override;
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() override;
};
struct db2_blob_backend : details::blob_backend
{
db2_blob_backend(db2_session_backend& session);
~db2_blob_backend() override;
std::size_t get_len() override;
std::size_t read_from_start(void* buf, std::size_t toRead, std::size_t offset = 0) override;
std::size_t write_from_start(const void* buf, std::size_t toWrite, std::size_t offset = 0) override;
std::size_t append(const void* buf, std::size_t toWrite) override;
void trim(std::size_t newLen) override;
db2_session_backend& session_;
};
struct db2_session_backend : details::session_backend
{
db2_session_backend(connection_parameters const& parameters);
~db2_session_backend() override;
bool is_connected() override;
void begin() override;
void commit() override;
void rollback() override;
std::string get_dummy_from_table() const override { return "sysibm.sysdummy1"; }
std::string get_backend_name() const override { return "DB2"; }
void clean_up();
db2_statement_backend* make_statement_backend() override;
db2_rowid_backend* make_rowid_backend() override;
db2_blob_backend* make_blob_backend() override;
void parseConnectString(std::string const &);
void parseKeyVal(std::string const &);
std::string connection_string_;
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 override;
};
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

View 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
#include <soci/soci-platform.h>
#ifdef SOCI_EMPTY_SOURCE
# define SOCI_EMPTY_DECL SOCI_DECL_EXPORT
#else
# define SOCI_EMPTY_DECL SOCI_DECL_IMPORT
#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) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch, indicator* ind) override;
void clean_up() override;
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) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator* ind) override;
void resize(std::size_t sz) override;
std::size_t size() override;
void clean_up() override;
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) override;
void bind_by_name(std::string const& name, void* data, details::exchange_type type, bool readOnly) override;
void pre_use(indicator const* ind) override;
void post_use(bool gotData, indicator* ind) override;
void clean_up() override;
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) override;
void bind_by_name(std::string const& name, void* data, details::exchange_type type) override;
void pre_use(indicator const* ind) override;
std::size_t size() override;
void clean_up() override;
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() override;
void clean_up() override;
void prepare(std::string const& query, details::statement_type eType) override;
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const& query) override;
int prepare_for_describe() override;
void describe_column(int colNum, db_type& dbtype, std::string& columnName) override;
empty_standard_into_type_backend* make_into_type_backend() override;
empty_standard_use_type_backend* make_use_type_backend() override;
empty_vector_into_type_backend* make_vector_into_type_backend() override;
empty_vector_use_type_backend* make_vector_use_type_backend() override;
empty_session_backend& session_;
};
struct empty_rowid_backend : details::rowid_backend
{
empty_rowid_backend(empty_session_backend &session);
~empty_rowid_backend() override;
};
struct empty_blob_backend : details::blob_backend
{
empty_blob_backend(empty_session_backend& session);
~empty_blob_backend() override;
std::size_t get_len() override;
std::size_t read_from_start(void * buf, std::size_t toRead, std::size_t offset = 0) override;
std::size_t write_from_start(const void * buf, std::size_t toWrite, std::size_t offset = 0) override;
std::size_t append(const void* buf, std::size_t toWrite) override;
void trim(std::size_t newLen) override;
empty_session_backend& session_;
};
struct empty_session_backend : details::session_backend
{
empty_session_backend(connection_parameters const& parameters);
~empty_session_backend() override;
bool is_connected() override { return true; }
void begin() override;
void commit() override;
void rollback() override;
std::string get_dummy_from_table() const override { return std::string(); }
std::string get_backend_name() const override { return "empty"; }
void clean_up();
empty_statement_backend* make_statement_backend() override;
empty_rowid_backend* make_rowid_backend() override;
empty_blob_backend* make_blob_backend() override;
};
struct SOCI_EMPTY_DECL empty_backend_factory : backend_factory
{
empty_backend_factory() {}
empty_session_backend* make_session(connection_parameters const& parameters) const override;
};
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

66
3rdparty/soci/include/soci/error.h vendored Normal file
View File

@@ -0,0 +1,66 @@
//
// 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) noexcept;
soci_error& operator=(soci_error const& e) noexcept;
~soci_error() noexcept override;
// 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.
char const* what() const noexcept override;
// 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);
// Basic error classes.
enum error_category
{
connection_error,
invalid_statement,
no_privilege,
no_data,
constraint_violation,
unknown_transaction_state,
system_error,
unknown
};
// Basic error classification support
virtual error_category get_error_category() const { return unknown; }
private:
// Optional extra information (currently just the context data).
class soci_error_extra_info* info_;
};
} // namespace soci
#endif // SOCI_ERROR_H_INCLUDED

View File

@@ -0,0 +1,190 @@
//
// 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/soci-types.h"
#include "soci/type-conversion-traits.h"
#include "soci/soci-backend.h"
#include "soci/type-wrappers.h"
// std
#include <cstdint>
#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<int8_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_int8 };
};
template <>
struct exchange_traits<uint8_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_uint8 };
};
template <>
struct exchange_traits<int16_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_int16 };
};
template <>
struct exchange_traits<uint16_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_uint16 };
};
template <>
struct exchange_traits<int32_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_int32 };
};
template <>
struct exchange_traits<uint32_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_uint32 };
};
template <>
struct exchange_traits<int64_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_int64 };
};
template <>
struct exchange_traits<uint64_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_uint64 };
};
#if defined(SOCI_INT64_IS_LONG)
template <>
struct exchange_traits<long long> : exchange_traits<int64_t>
{
};
template <>
struct exchange_traits<unsigned long long> : exchange_traits<uint64_t>
{
};
#elif defined(SOCI_LONG_IS_64_BIT)
template <>
struct exchange_traits<long> : exchange_traits<int64_t>
{
};
template <>
struct exchange_traits<unsigned long> : exchange_traits<uint64_t>
{
};
#else
template <>
struct exchange_traits<long> : exchange_traits<int32_t>
{
};
template <>
struct exchange_traits<unsigned long> : exchange_traits<uint32_t>
{
};
#endif
template <>
struct exchange_traits<double>
{
typedef basic_type_tag type_family;
enum { x_type = x_double };
};
template <>
struct exchange_traits<char>
{
typedef basic_type_tag type_family;
enum { x_type = x_char };
};
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 };
};
// handling of wrapper types
template <>
struct exchange_traits<xml_type>
{
typedef basic_type_tag type_family;
enum { x_type = x_xmltype };
};
template <>
struct exchange_traits<long_string>
{
typedef basic_type_tag type_family;
enum { x_type = x_longstring };
};
} // namespace details
} // namespace soci
#endif // SOCI_EXCHANGE_TRAITS_H_INCLUDED

View File

@@ -0,0 +1,356 @@
//
// 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
#include <soci/soci-platform.h>
#ifdef SOCI_FIREBIRD_SOURCE
# define SOCI_FIREBIRD_DECL SOCI_DECL_EXPORT
#else
# define SOCI_FIREBIRD_DECL SOCI_DECL_IMPORT
#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>
#include <cstdint>
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() noexcept override {};
std::vector<ISC_STATUS> status_;
};
enum BuffersType
{
eStandard, eVector
};
struct firebird_blob_backend;
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), data_(NULL), type_(), position_(0), buf_(NULL), indISCHolder_(0)
{}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch,
indicator *ind) override;
void clean_up() override;
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), data_(NULL), type_(), position_(0), buf_(NULL), indISCHolder_(0)
{}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator *ind) override;
void resize(std::size_t sz) override;
std::size_t size() override;
void clean_up() override;
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), data_(NULL), type_(), position_(0), buf_(NULL), indISCHolder_(0),
blob_(NULL)
{}
void bind_by_pos(int &position,
void *data, details::exchange_type type, bool readOnly) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type, bool readOnly) override;
void pre_use(indicator const *ind) override;
void post_use(bool gotData, indicator *ind) override;
void clean_up() override;
firebird_statement_backend &statement_;
virtual void exchangeData();
void *data_;
details::exchange_type type_;
int position_;
char *buf_;
short indISCHolder_;
private:
// Allocate a temporary blob, fill it with the data from the provided
// string and copy its ID into buf_.
void copy_to_blob(const std::string& in);
// This is used for types mapping to CLOB.
firebird_blob_backend* blob_;
};
struct firebird_vector_use_type_backend : details::vector_use_type_backend
{
firebird_vector_use_type_backend(firebird_statement_backend &st)
: statement_(st), data_(NULL), type_(), position_(0), buf_(NULL), indISCHolder_(0),
blob_(NULL)
{}
void bind_by_pos(int &position,
void *data, details::exchange_type type) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type) override;
void pre_use(indicator const *ind) override;
std::size_t size() override;
void clean_up() override;
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_;
private:
// Allocate a temporary blob, fill it with the data from the provided
// string and copy its ID into buf_.
void copy_to_blob(const std::string &in);
// This is used for types mapping to CLOB.
firebird_blob_backend *blob_;
};
struct firebird_session_backend;
struct firebird_statement_backend : details::statement_backend
{
firebird_statement_backend(firebird_session_backend &session);
void alloc() override;
void clean_up() override;
void prepare(std::string const &query,
details::statement_type eType) override;
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const &query) override;
int prepare_for_describe() override;
void describe_column(int colNum,
db_type &dbtype,
std::string &columnName) override;
firebird_standard_into_type_backend * make_into_type_backend() override;
firebird_standard_use_type_backend * make_use_type_backend() override;
firebird_vector_into_type_backend * make_vector_into_type_backend() override;
firebird_vector_use_type_backend * make_vector_use_type_backend() override;
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() override;
std::size_t get_len() override;
std::size_t read_from_start(void * buf, std::size_t toRead, std::size_t offset = 0) override;
std::size_t write_from_start(const void * buf, std::size_t toWrite, std::size_t offset = 0) override;
std::size_t append(const void *buf, std::size_t toWrite) override;
void trim(std::size_t newLen) override;
// Writes the current data into the database by allocating a new BLOB
// object for it.
//
// Returns The ID of the newly created BLOB object
ISC_QUAD save_to_db();
void assign(ISC_QUAD const & bid);
private:
void open();
long getBLOBInfo();
void load();
void writeBuffer(std::size_t offset, void const * buf,
std::size_t toWrite);
void closeBlob();
firebird_session_backend &session_;
ISC_QUAD blob_id_;
// BLOB id was fetched from database (true)
// or this is new BLOB
bool from_db_;
isc_blob_handle blob_handle_;
// buffer for BLOB data
std::vector<std::uint8_t> data_;
bool loaded_;
long max_seg_size_;
};
struct firebird_session_backend : details::session_backend
{
firebird_session_backend(connection_parameters const & parameters);
~firebird_session_backend() override;
bool is_connected() override;
void begin() override;
void commit() override;
void rollback() override;
bool get_next_sequence_value(session & s,
std::string const & sequence, long long & value) override;
std::string get_dummy_from_table() const override { return "rdb$database"; }
std::string get_backend_name() const override { return "firebird"; }
void cleanUp();
firebird_statement_backend * make_statement_backend() override;
details::rowid_backend* make_rowid_backend() override;
firebird_blob_backend * make_blob_backend() override;
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() {}
firebird_session_backend * make_session(
connection_parameters const & parameters) const override;
};
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

View File

@@ -0,0 +1,155 @@
#ifndef SOCI_FIXED_SIZE_INTS_H_INCLUDED
#define SOCI_FIXED_SIZE_INTS_H_INCLUDED
#include "soci/soci-types.h"
#include "soci/type-conversion-traits.h"
#include <cstdint>
namespace soci
{
// Completion of dt_[u]int* bindings for all architectures.
// This allows us to extract values on types where the type definition is
// specific to the underlying architecture. E.g. Unix defines a int64_t as
// long. This would make it impossible to extract a dt_int64 value as both
// long and long long. With the following type_conversion specializations,
// this becomes possible.
#if defined(SOCI_INT64_IS_LONG)
template <>
struct type_conversion<long long>
{
typedef int64_t base_type;
static void from_base(base_type const & in, indicator ind, long long & out)
{
if (ind == i_null)
{
throw soci_error("Null value not allowed for this type.");
}
out = static_cast<long long>(in);
}
static void to_base(long long const & in, base_type & out, indicator & ind)
{
out = static_cast<base_type>(in);
ind = i_ok;
}
};
template <>
struct type_conversion<unsigned long long>
{
typedef uint64_t base_type;
static void from_base(base_type const & in, indicator ind, unsigned long long & out)
{
if (ind == i_null)
{
throw soci_error("Null value not allowed for this type.");
}
out = static_cast<unsigned long long>(in);
}
static void to_base(unsigned long long const & in, base_type & out, indicator & ind)
{
out = static_cast<base_type>(in);
ind = i_ok;
}
};
#elif defined(SOCI_LONG_IS_64_BIT)
template <>
struct type_conversion<long>
{
typedef int64_t base_type;
static void from_base(base_type const & in, indicator ind, long & out)
{
if (ind == i_null)
{
throw soci_error("Null value not allowed for this type.");
}
out = static_cast<long>(in);
}
static void to_base(long const & in, base_type & out, indicator & ind)
{
out = static_cast<base_type>(in);
ind = i_ok;
}
};
template <>
struct type_conversion<unsigned long>
{
typedef uint64_t base_type;
static void from_base(base_type const & in, indicator ind, unsigned long & out)
{
if (ind == i_null)
{
throw soci_error("Null value not allowed for this type.");
}
out = static_cast<unsigned long>(in);
}
static void to_base(unsigned long const & in, base_type & out, indicator & ind)
{
out = static_cast<base_type>(in);
ind = i_ok;
}
};
#else
template <>
struct type_conversion<long>
{
typedef int32_t base_type;
static void from_base(base_type const & in, indicator ind, long & out)
{
if (ind == i_null)
{
throw soci_error("Null value not allowed for this type.");
}
out = static_cast<long>(in);
}
static void to_base(long const & in, base_type & out, indicator & ind)
{
out = static_cast<base_type>(in);
ind = i_ok;
}
};
template <>
struct type_conversion<unsigned long>
{
typedef uint32_t base_type;
static void from_base(base_type const & in, indicator ind, unsigned long & out)
{
if (ind == i_null)
{
throw soci_error("Null value not allowed for this type.");
}
out = static_cast<unsigned long>(in);
}
static void to_base(unsigned long const & in, base_type & out, indicator & ind)
{
out = static_cast<base_type>(in);
ind = i_ok;
}
};
#endif
} // namespace soci
#endif // SOCI_FIXED_SIZE_INTS_H_INCLUDED

213
3rdparty/soci/include/soci/into-type.h vendored Normal file
View File

@@ -0,0 +1,213 @@
//
// Copyright (C) 2004-2016 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_exec(int num) = 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)
{
// Backends won't initialize the indicator if no data is retrieved, so
// do it here, like this we can be sure it has a defined value even if
// an exception is thrown before anything else happens.
*ind_ = i_null;
}
~standard_into_type() override;
protected:
void post_fetch(bool gotData, bool calledFromFetch) override;
private:
void define(statement_impl & st, int & position) override;
void pre_exec(int num) override;
void pre_fetch() override;
void clean_up() override;
std::size_t size() const override { 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),
begin_(0), end_(NULL), backEnd_(NULL) {}
vector_into_type(void * data, exchange_type type,
std::size_t begin, std::size_t * end)
: data_(data), type_(type), indVec_(NULL),
begin_(begin), end_(end), backEnd_(NULL) {}
vector_into_type(void * data, exchange_type type,
std::vector<indicator> & ind)
: data_(data), type_(type), indVec_(&ind),
begin_(0), end_(NULL), backEnd_(NULL) {}
vector_into_type(void * data, exchange_type type,
std::vector<indicator> & ind,
std::size_t begin, std::size_t * end)
: data_(data), type_(type), indVec_(&ind),
begin_(begin), end_(end), backEnd_(NULL) {}
~vector_into_type() override;
protected:
void post_fetch(bool gotData, bool calledFromFetch) override;
void define(statement_impl & st, int & position) override;
void pre_exec(int num) override;
void pre_fetch() override;
void clean_up() override;
void resize(std::size_t sz) override;
std::size_t size() const override;
void * data_;
exchange_type type_;
std::vector<indicator> * indVec_;
std::size_t begin_;
std::size_t * end_;
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::size_t begin, std::size_t * end)
: vector_into_type(&v,
static_cast<exchange_type>(exchange_traits<T>::x_type),
begin, end) {}
into_type(std::vector<T> & v, std::vector<indicator> & ind)
: vector_into_type(&v,
static_cast<exchange_type>(exchange_traits<T>::x_type), ind) {}
into_type(std::vector<T> & v, std::vector<indicator> & ind,
std::size_t begin, std::size_t * end)
: vector_into_type(&v,
static_cast<exchange_type>(exchange_traits<T>::x_type), ind,
begin, end) {}
};
// 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));
}
template <typename T>
into_type_ptr do_into(std::vector<T> & t,
std::size_t begin, std::size_t * end, basic_type_tag)
{
return into_type_ptr(new into_type<std::vector<T> >(t, begin, end));
}
template <typename T>
into_type_ptr do_into(std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, std::size_t * end, basic_type_tag)
{
return into_type_ptr(new into_type<std::vector<T> >(t, ind, begin, end));
}
} // namespace details
} // namespace soci
#endif // SOCI_INTO_TYPE_H_INCLUDED

97
3rdparty/soci/include/soci/into.h vendored Normal file
View File

@@ -0,0 +1,97 @@
//
// Copyright (C) 2004-2016 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));
}
// vectors with index ranges
template <typename T>
details::into_type_ptr into(std::vector<T> & t,
std::size_t begin, std::size_t & end)
{
return details::do_into(t, begin, &end,
typename details::exchange_traits<std::vector<T> >::type_family());
}
template <typename T>
details::into_type_ptr into(std::vector<T> & t, std::vector<indicator> & ind)
{
return details::do_into(t, ind,
typename details::exchange_traits<std::vector<T> >::type_family());
}
template <typename T>
details::into_type_ptr into(std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, std::size_t & end)
{
return details::do_into(t, ind, begin, &end,
typename details::exchange_traits<std::vector<T> >::type_family());
}
} // namespace soci
#endif // SOCI_INTO_H_INCLUDED

View File

@@ -0,0 +1,49 @@
//
// Copyright (C) 2023 Robert Adam
// 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_IS_DETECTED_H_INCLUDED
#define SOCI_IS_DETECTED_H_INCLUDED
#include <type_traits>
namespace soci
{
namespace details
{
template<typename...>
using void_t = void;
using false_type = std::integral_constant<bool, false>;
using true_type = std::integral_constant<bool, true>;
// Implementation from https://blog.tartanllama.xyz/detection-idiom/
// Note, this is a stub that we require until standard C++ gets support
// for the detection idiom that is not experimental (and thus can be
// assumed to be present).
namespace detector_detail
{
template <template <class...> class Trait, class Enabler, class... Args>
struct is_detected : false_type {};
template <template <class...> class Trait, class... Args>
struct is_detected<Trait, void_t<Trait<Args...>>, Args...> : true_type {};
}
template <template <class...> class Trait, class... Args>
using is_detected = typename detector_detail::is_detected<Trait, void, Args...>::type;
}
}
#endif // SOCI_IS_DETECTED_H_INCLUDED

82
3rdparty/soci/include/soci/logger.h vendored Normal file
View File

@@ -0,0 +1,82 @@
//
// 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_LOGGER_H_INCLUDED
#define SOCI_LOGGER_H_INCLUDED
#include "soci/soci-platform.h"
#include <ostream>
namespace soci
{
// Allows to customize the logging of database operations performed by SOCI.
//
// To do it, derive your own class from logger_impl and override its pure
// virtual start_query() and do_clone() methods (overriding the other methods
// is optional), then call session::set_logger() with a logger object using
// your implementation.
class SOCI_DECL logger_impl
{
public:
logger_impl() {}
virtual ~logger_impl();
// Called to indicate that a new query is about to be executed.
virtual void start_query(std::string const & query) = 0;
logger_impl * clone() const;
// These methods are for compatibility only as they're used to implement
// session basic logging support, you should only override them if you want
// to use session::set_stream() and similar methods with your custom logger.
virtual void set_stream(std::ostream * s);
virtual std::ostream * get_stream() const;
virtual std::string get_last_query() const;
private:
// Override to return a new heap-allocated copy of this object.
virtual logger_impl * do_clone() const = 0;
// Non-copyable
logger_impl(logger_impl const &);
logger_impl & operator=(logger_impl const &);
};
// A wrapper class representing a logger.
//
// Unlike logger_impl, this class has value semantics and can be manipulated
// easily without any danger of memory leaks or dereferencing a NULL pointer.
class SOCI_DECL logger
{
public:
// No default constructor, must always have an associated logger_impl.
// Create a logger using the provided non-NULL implementation (an exception
// is thrown if the pointer is NULL). The logger object takes ownership of
// the pointer and will delete it.
logger(logger_impl * impl);
logger(logger const & other);
logger& operator=(logger const & other);
~logger();
void start_query(std::string const & query) { m_impl->start_query(query); }
// Methods used for the implementation of session basic logging support.
void set_stream(std::ostream * s) { m_impl->set_stream(s); }
std::ostream * get_stream() const { return m_impl->get_stream(); }
std::string get_last_query() const { return m_impl->get_last_query(); }
private:
logger_impl * m_impl;
};
} // namespace soci
#endif // SOCI_LOGGER_H_INCLUDED

View File

@@ -0,0 +1,314 @@
//
// 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
#include <soci/soci-platform.h>
#ifdef SOCI_MYSQL_SOURCE
# define SOCI_MYSQL_DECL SOCI_DECL_EXPORT
#else
# define SOCI_MYSQL_DECL SOCI_DECL_IMPORT
#endif
#include <soci/soci-backend.h>
#include <private/soci-trivial-blob-backend.h>
#ifdef _WIN32
#include <winsock.h> // SOCKET
#endif // _WIN32
// Some version of mysql.h contain trailing comma in an enum declaration that
// trigger -Wpedantic, so suppress it as there is nothing to be done about it
// using the macros defined in our private soci-compiler.h header, that we can
// only include when building SOCI itself.
#ifdef SOCI_MYSQL_SOURCE
#include "soci-compiler.h"
#endif
#ifdef SOCI_GCC_WARNING_SUPPRESS
SOCI_GCC_WARNING_SUPPRESS(pedantic)
#endif
#include <mysql.h> // MySQL Client
#include <errmsg.h> // MySQL Error codes
#ifdef SOCI_GCC_WARNING_RESTORE
SOCI_GCC_WARNING_RESTORE(pedantic)
#endif
#include <vector>
namespace soci
{
class SOCI_MYSQL_DECL mysql_soci_error : public soci_error
{
public:
mysql_soci_error(std::string const & msg, int errNum)
: soci_error(msg), err_num_(errNum), cat_(unknown) {
if(errNum == CR_CONNECTION_ERROR ||
errNum == CR_CONN_HOST_ERROR ||
errNum == CR_SERVER_GONE_ERROR ||
errNum == CR_SERVER_LOST ||
errNum == 1927) { // Lost connection to backend server
cat_ = connection_error;
}
}
error_category get_error_category() const override { return cat_; }
unsigned int err_num_;
error_category cat_;
};
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) {}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch,
indicator *ind) override;
void clean_up() override;
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) {}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator *ind) override;
void resize(std::size_t sz) override;
std::size_t size() override;
void clean_up() override;
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) {}
void bind_by_pos(int &position,
void *data, details::exchange_type type, bool readOnly) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type, bool readOnly) override;
void pre_use(indicator const *ind) override;
void post_use(bool gotData, indicator *ind) override;
void clean_up() override;
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) {}
void bind_by_pos(int &position,
void *data, details::exchange_type type) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type) override;
void pre_use(indicator const *ind) override;
std::size_t size() override;
void clean_up() override;
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);
void alloc() override;
void clean_up() override;
void prepare(std::string const &query,
details::statement_type eType) override;
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const &query) override;
int prepare_for_describe() override;
void describe_column(int colNum,
db_type &dbtype,
std::string &columnName) override;
data_type to_data_type(db_type dbt) const override;
mysql_standard_into_type_backend * make_into_type_backend() override;
mysql_standard_use_type_backend * make_use_type_backend() override;
mysql_vector_into_type_backend * make_vector_into_type_backend() override;
mysql_vector_use_type_backend * make_vector_use_type_backend() override;
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
// Set to true if the last column passed to describe_column() was a
// MEDIUMINT UNSIGNED one, see to_data_type().
bool lastDescribedUnsignedMediumInt_ = false;
// 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() override;
};
class mysql_blob_backend : public details::trivial_blob_backend
{
public:
mysql_blob_backend(mysql_session_backend &session);
~mysql_blob_backend() override;
std::size_t hex_str_size() const;
void write_hex_str(char *buf, std::size_t size) const;
std::string as_hex_str() const;
void load_from_hex_str(const char* str, std::size_t length);
};
struct mysql_session_backend : details::session_backend
{
mysql_session_backend(connection_parameters const & parameters);
~mysql_session_backend() override;
bool is_connected() override;
void begin() override;
void commit() override;
void rollback() override;
bool get_last_insert_id(session&, std::string const&, long long&) override;
// Note that MySQL supports both "SELECT 2+2" and "SELECT 2+2 FROM DUAL"
// syntaxes, but there doesn't seem to be any reason to use the longer one.
std::string get_dummy_from_table() const override { return std::string(); }
std::string get_backend_name() const override { return "mysql"; }
void clean_up();
mysql_statement_backend * make_statement_backend() override;
mysql_rowid_backend * make_rowid_backend() override;
mysql_blob_backend * make_blob_backend() override;
std::string get_table_names_query() const override
{
return "SELECT table_name AS 'TABLE_NAME' FROM information_schema.tables WHERE table_schema = DATABASE()";
}
MYSQL *conn_;
};
struct mysql_backend_factory : backend_factory
{
mysql_backend_factory() {}
mysql_session_backend * make_session(
connection_parameters const & parameters) const override;
};
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
3rdparty/soci/include/soci/noreturn.h vendored Normal file
View 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

View File

@@ -0,0 +1,624 @@
//
// 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
#include <soci/soci-platform.h>
#ifdef SOCI_ODBC_SOURCE
# define SOCI_ODBC_DECL SOCI_DECL_EXPORT
#else
# define SOCI_ODBC_DECL SOCI_DECL_IMPORT
#endif
#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;
// select max size from following MSDN article
// https://msdn.microsoft.com/en-us/library/ms130896.aspx
SQLLEN const ODBC_MAX_COL_SIZE = 8000;
// 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
};
// IBM DB2 driver is not compliant to ODBC spec for indicators in 64bit
// SQLLEN is still defined 32bit (int) but spec requires 64bit (long)
inline bool requires_noncompliant_32bit_sqllen() const;
inline SQLLEN get_sqllen_from_value(const SQLLEN val) const;
inline void set_sqllen_from_value(SQLLEN &target, const SQLLEN val) const;
inline bool supports_negative_tinyint() const;
inline bool can_convert_to_unsigned_sql_type() const;
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)
{}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch,
indicator *ind) override;
void clean_up() override;
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),
data_(NULL), buf_(NULL), position_(0) {}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator *ind) override;
void resize(std::size_t sz) override;
std::size_t size() override;
void clean_up() override;
// Normally data retrieved from the database is handled in post_fetch(),
// however we may need to call SQLFetch() multiple times, so we call this
// function instead after each call to it to retrieve the given range of
// rows.
void do_post_fetch_rows(std::size_t beginRow, std::size_t endRow);
// IBM DB2 driver is not compliant to ODBC spec for indicators in 64bit
// SQLLEN is still defined 32bit (int) but spec requires 64bit (long)
inline SQLLEN get_sqllen_from_vector_at(std::size_t idx) const;
// Rebind the single vector value at the given index to the first row.
// Used when vector values are fetched by single row.
void rebind_row(std::size_t rowInd);
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_;
int position_;
};
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) {}
void bind_by_pos(int &position,
void *data, details::exchange_type type, bool readOnly) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type, bool readOnly) override;
void pre_use(indicator const *ind) override;
void post_use(bool gotData, indicator *ind) override;
void clean_up() override;
// 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_;
private:
// Copy string data to buf_ and set size, sqlType and cType to the values
// appropriate for strings.
void copy_from_string(std::string const& s,
SQLLEN& size,
SQLSMALLINT& sqlType,
SQLSMALLINT& cType);
};
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),
data_(NULL), buf_(NULL) {}
// helper function for preparing indicators
// (as part of the define_by_pos)
void prepare_indicators(std::size_t size);
// helper of pre_use(), return the pointer to the data to be used by ODBC.
void* prepare_for_bind(SQLUINTEGER &size, SQLSMALLINT &sqlType, SQLSMALLINT &cType);
void bind_by_pos(int &position,
void *data, details::exchange_type type) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type) override;
void pre_use(indicator const *ind) override;
std::size_t size() override;
void clean_up() override;
// IBM DB2 driver is not compliant to ODBC spec for indicators in 64bit
// SQLLEN is still defined 32bit (int) but spec requires 64bit (long)
inline void set_sqllen_from_vector_at(const std::size_t idx, const SQLLEN val);
std::vector<SQLLEN> indHolderVec_;
void *data_;
details::exchange_type type_;
int position_;
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);
void alloc() override;
void clean_up() override;
void prepare(std::string const &query,
details::statement_type eType) override;
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const &query) override;
int prepare_for_describe() override;
void describe_column(int colNum,
db_type &dbtype,
std::string &columnName) override;
data_type to_data_type(db_type dbt) const override;
// helper for defining into vector<string>
std::size_t column_size(int position);
odbc_standard_into_type_backend * make_into_type_backend() override;
odbc_standard_use_type_backend * make_use_type_backend() override;
odbc_vector_into_type_backend * make_vector_into_type_backend() override;
odbc_vector_use_type_backend * make_vector_use_type_backend() override;
odbc_session_backend &session_;
SQLHSTMT hstmt_;
SQLULEN numRowsFetched_;
bool fetchVectorByRows_;
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
// This vector, containing non-owning non-null pointers, can be empty if
// we're not using any vector "intos".
std::vector<odbc_vector_into_type_backend*> intos_;
private:
// fetch() helper wrapping SQLFetch() call for the given range of rows.
exec_fetch_result do_fetch(int beginRow, int endRow);
};
struct odbc_rowid_backend : details::rowid_backend
{
odbc_rowid_backend(odbc_session_backend &session);
~odbc_rowid_backend() override;
};
struct odbc_blob_backend : details::blob_backend
{
odbc_blob_backend(odbc_session_backend &session);
~odbc_blob_backend() override;
std::size_t get_len() override;
std::size_t read_from_start(void *buf, std::size_t toRead, std::size_t offset = 0) override;
std::size_t write_from_start(const void *buf, std::size_t toWrite, std::size_t offset = 0) override;
std::size_t append(const void *buf, std::size_t toWrite) override;
void trim(std::size_t newLen) override;
odbc_session_backend &session_;
};
struct odbc_session_backend : details::session_backend
{
odbc_session_backend(connection_parameters const & parameters);
~odbc_session_backend() override;
bool is_connected() override;
void begin() override;
void commit() override;
void rollback() override;
bool get_next_sequence_value(session & s,
std::string const & sequence, long long & value) override;
bool get_last_insert_id(session & s,
std::string const & table, long long & value) override;
std::string get_dummy_from_table() const override;
std::string get_backend_name() const override { return "odbc"; }
void configure_connection();
void reset_transaction();
void clean_up();
odbc_statement_backend * make_statement_backend() override;
odbc_rowid_backend * make_rowid_backend() override;
odbc_blob_backend * make_blob_backend() override;
enum database_product
{
prod_uninitialized, // Never returned by get_database_product().
prod_db2,
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.
SOCI_ODBC_DECL database_product get_database_product() const;
// Return full ODBC connection string.
std::string get_connection_string() const { return connection_string_; }
SQLHENV henv_;
SQLHDBC hdbc_;
std::string connection_string_;
private:
mutable 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))
{
}
error_category get_error_category() const override
{
const char* const s = reinterpret_cast<const char*>(sqlstate_);
if ((s[0] == '0' && s[1] == '8') ||
strcmp(s, "HYT01") == 0)
return connection_error;
if (strcmp(s, "23000") == 0 ||
strcmp(s, "40002") == 0 ||
strcmp(s, "44000") == 0)
return constraint_violation;
if (strcmp(s, "HY014") == 0)
return system_error;
return unknown;
}
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;
}
inline bool odbc_standard_type_backend_base::requires_noncompliant_32bit_sqllen() const
{
// IBM DB2 did not implement the ODBC specification for indicator sizes in 64bit.
// They still use SQLLEN as 32bit even if the driver is compiled 64bit
// This breaks the backend in terms of using indicators
// see: https://bugs.php.net/bug.php?id=54007
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
return statement_.session_.get_database_product()
== odbc_session_backend::prod_db2;
#else
return false;
#endif
}
inline SQLLEN odbc_standard_type_backend_base::get_sqllen_from_value(const SQLLEN val) const
{
if (requires_noncompliant_32bit_sqllen())
{
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#elif defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wstrict-aliasing"
#endif
return *reinterpret_cast<const int*>(&val);
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#elif defined(__clang__)
#pragma clang diagnostic pop
#endif
}
return val;
}
inline void odbc_standard_type_backend_base::set_sqllen_from_value(SQLLEN &target, const SQLLEN val) const
{
if (requires_noncompliant_32bit_sqllen())
{
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#elif defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wstrict-aliasing"
#endif
reinterpret_cast<int*>(&target)[0] = *reinterpret_cast<const int*>(&val);
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#elif defined(__clang__)
#pragma clang diagnostic pop
#endif
}
else
{
target = val;
}
}
inline bool odbc_standard_type_backend_base::supports_negative_tinyint() const
{
// MSSQL ODBC driver only supports a range of [0..255] for tinyint.
return statement_.session_.get_database_product()
!= odbc_session_backend::prod_mssql;
}
inline bool odbc_standard_type_backend_base::can_convert_to_unsigned_sql_type() const
{
// MSSQL ODBC driver seemingly can't handle the conversion of unsigned C
// types to their respective unsigned SQL type because they are out of
// range for their supported signed types. This results in the error
// "Numeric value out of range (SQL state 22003)".
// The only place it works is with tinyint values as their range is
// [0..255], i.e. they have enough space for unsigned values anyway.
return statement_.session_.get_database_product()
!= odbc_session_backend::prod_mssql;
}
inline SQLLEN odbc_vector_into_type_backend::get_sqllen_from_vector_at(std::size_t idx) const
{
if (requires_noncompliant_32bit_sqllen())
{
return reinterpret_cast<const int*>(&indHolderVec_[0])[idx];
}
return indHolderVec_[idx];
}
inline void odbc_vector_use_type_backend::set_sqllen_from_vector_at(const std::size_t idx, const SQLLEN val)
{
if (requires_noncompliant_32bit_sqllen())
{
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#elif defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wstrict-aliasing"
#endif
reinterpret_cast<int*>(&indHolderVec_[0])[idx] = *reinterpret_cast<const int*>(&val);
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#elif defined(__clang__)
#pragma clang diagnostic pop
#endif
}
else
{
indHolderVec_[idx] = val;
}
}
struct odbc_backend_factory : backend_factory
{
odbc_backend_factory() {}
odbc_session_backend * make_session(
connection_parameters const & parameters) const override;
};
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

View File

@@ -0,0 +1,183 @@
//
// Copyright (C) 2004-2016 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/soci-platform.h"
#include "soci/ref-counted-statement.h"
#include "soci/prepare-temp-type.h"
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() noexcept(false);
template <typename T>
once_temp_type & operator<<(T const & t)
{
rcst_->accumulate(t);
return *this;
}
once_temp_type & operator,(into_type_ptr const &);
once_temp_type & operator,(use_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
// Note: ddl_type is intended to be used just as once_temp_type,
// but since it can be also used directly (explicitly) by the user code,
// it is declared outside of the namespace details.
class SOCI_DECL ddl_type
{
public:
ddl_type(session & s);
ddl_type(const ddl_type & d);
ddl_type & operator=(const ddl_type & d);
~ddl_type() noexcept(false);
void create_table(const std::string & tableName);
void add_column(const std::string & tableName,
const std::string & columnName, db_type dt,
int precision, int scale);
void alter_column(const std::string & tableName,
const std::string & columnName, db_type dt,
int precision, int scale);
void drop_column(const std::string & tableName,
const std::string & columnName);
ddl_type & column(const std::string & columnName, db_type dt,
int precision = 0, int scale = 0);
ddl_type & unique(const std::string & name,
const std::string & columnNames);
ddl_type & primary_key(const std::string & name,
const std::string & columnNames);
ddl_type & foreign_key(const std::string & name,
const std::string & columnNames,
const std::string & refTableName,
const std::string & refColumnNames);
ddl_type & operator()(const std::string & arbitrarySql);
// helper function for handling delimiters
// between various parts of DDL statements
void set_tail(const std::string & tail);
// The functions below still work but are deprecated (but we don't give
// deprecation warnings for them because there is no real harm in using
// them).
//
// Use the overloads taking db_type instead in the new code.
void add_column(const std::string & tableName,
const std::string & columnName, data_type dt,
int precision, int scale)
{
add_column(tableName, columnName, details::to_db_type(dt), precision, scale);
}
void alter_column(const std::string & tableName,
const std::string & columnName, data_type dt,
int precision, int scale)
{
alter_column(tableName, columnName, details::to_db_type(dt), precision, scale);
}
ddl_type & column(const std::string & columnName, data_type dt,
int precision = 0, int scale = 0)
{
return column(columnName, details::to_db_type(dt), precision, scale);
}
private:
session * s_;
details::ref_counted_statement * rcst_;
};
} // namespace soci
#endif

View File

@@ -0,0 +1,492 @@
//
// Copyright (C) 2004-2016 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
#include <soci/soci-platform.h>
#ifdef SOCI_ORACLE_SOURCE
# define SOCI_ORACLE_DECL SOCI_DECL_EXPORT
#else
# define SOCI_ORACLE_DECL SOCI_DECL_IMPORT
#endif
#include <soci/soci-backend.h>
#include <oci.h> // OCI
#include <sstream>
#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);
error_category get_error_category() const override { return cat_; }
int err_num_;
error_category cat_;
};
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) {}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_exec(int num) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch,
indicator *ind) override;
void clean_up() override;
oracle_statement_backend &statement_;
OCIDefine *defnp_;
sb2 indOCIHolder_;
void *data_;
void *ociData_;
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),
data_(NULL), buf_(NULL), user_ranges_(true) {}
void define_by_pos(int &position,
void *data, details::exchange_type type) override
{
user_ranges_ = false;
define_by_pos_bulk(position, data, type, 0, &end_var_);
}
void define_by_pos_bulk(
int & position, void * data, details::exchange_type type,
std::size_t begin, std::size_t * end) override;
void pre_exec(int num) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator *ind) override;
void resize(std::size_t sz) override;
std::size_t size() override;
std::size_t full_size();
void clean_up() override;
// 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_;
std::vector<sb2> indOCIHolderVec_;
void *data_;
char *buf_; // generic buffer
details::exchange_type type_;
std::size_t begin_;
std::size_t * end_;
std::size_t end_var_;
bool user_ranges_;
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) {}
void bind_by_pos(int &position,
void *data, details::exchange_type type, bool readOnly) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type, bool readOnly) override;
// common part for bind_by_pos and bind_by_name
void prepare_for_bind(void *&data, sb4 &size, ub2 &oracleType, bool readOnly);
void pre_exec(int num) override;
void pre_use(indicator const *ind) override;
void post_use(bool gotData, indicator *ind) override;
void clean_up() override;
oracle_statement_backend &statement_;
OCIBind *bindp_;
sb2 indOCIHolder_;
void *data_;
void *ociData_;
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),
data_(NULL), buf_(NULL), bind_position_(0) {}
void bind_by_pos(int & position,
void * data, details::exchange_type type) override
{
bind_by_pos_bulk(position, data, type, 0, &end_var_);
}
void bind_by_pos_bulk(int & position,
void * data, details::exchange_type type,
std::size_t begin, std::size_t * end) override;
void bind_by_name(const std::string & name,
void * data, details::exchange_type type) override
{
bind_by_name_bulk(name, data, type, 0, &end_var_);
}
void bind_by_name_bulk(std::string const &name,
void *data, details::exchange_type type,
std::size_t begin, std::size_t * end) override;
// pre_use() helper
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);
void pre_use(indicator const *ind) override;
std::size_t size() override; // active size (might be lower than full vector size)
std::size_t full_size(); // actual size of the user-provided vector
void clean_up() override;
oracle_statement_backend &statement_;
OCIBind *bindp_;
std::vector<sb2> indOCIHolderVec_;
void *data_;
char *buf_; // generic buffer
details::exchange_type type_;
std::size_t begin_;
std::size_t * end_;
std::size_t end_var_;
// used for strings only
std::vector<ub2> sizes_;
std::size_t maxSize_;
// name is used if non-empty, otherwise position
std::string bind_name_;
int bind_position_;
};
struct oracle_session_backend;
struct oracle_statement_backend : details::statement_backend
{
oracle_statement_backend(oracle_session_backend &session);
void alloc() override;
void clean_up() override;
void prepare(std::string const &query,
details::statement_type eType) override;
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const &query) override;
int prepare_for_describe() override;
void describe_column(int colNum,
db_type &dbtype,
std::string &columnName) override;
// helper for defining into vector<string>
std::size_t column_size(int position);
oracle_standard_into_type_backend * make_into_type_backend() override;
oracle_standard_use_type_backend * make_use_type_backend() override;
oracle_vector_into_type_backend * make_vector_into_type_backend() override;
oracle_vector_use_type_backend * make_vector_use_type_backend() override;
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() override;
OCIRowid *rowidp_;
};
struct oracle_blob_backend : details::blob_backend
{
typedef OCILobLocator * locator_t;
oracle_blob_backend(oracle_session_backend &session);
~oracle_blob_backend() override;
std::size_t get_len() override;
std::size_t read_from_start(void * buf, std::size_t toRead, std::size_t offset = 0) override;
std::size_t write_from_start(const void * buf, std::size_t toWrite, std::size_t offset = 0) override;
std::size_t append(const void *buf, std::size_t toWrite) override;
void trim(std::size_t newLen) override;
locator_t get_lob_locator() const;
void set_lob_locator(locator_t locator, bool initialized = true);
void reset();
void ensure_initialized();
private:
std::size_t do_deprecated_read(std::size_t offset, void *buf, std::size_t toRead) override
{
// Offsets are 1-based in Oracle
return read_from_start(buf, toRead, offset - 1);
}
std::size_t do_deprecated_write(std::size_t offset, const void *buf, std::size_t toWrite) override
{
// Offsets are 1-based in Oracle
return write_from_start(buf, toWrite, offset - 1);
}
oracle_session_backend &session_;
locator_t lobp_;
// If this is true, then the locator lobp_ points to something useful
// (instead of being the equivalent to a pointer with random value)
bool initialized_;
};
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,
int charset = 0,
int ncharset = 0);
~oracle_session_backend() override;
bool is_connected() override;
void begin() override;
void commit() override;
void rollback() override;
std::string get_table_names_query() const override
{
return "select table_name"
" from user_tables";
}
std::string get_column_descriptions_query() const override
{
return "select column_name,"
" data_type,"
" char_length as character_maximum_length,"
" data_precision as numeric_precision,"
" data_scale as numeric_scale,"
" decode(nullable, 'Y', 'YES', 'N', 'NO') as is_nullable"
" from user_tab_columns"
" where table_name = :t";
}
std::string create_column_type(db_type dt,
int precision, int scale) override
{
// Oracle-specific SQL syntax:
std::string res;
switch (dt)
{
case db_string:
{
std::ostringstream oss;
if (precision == 0)
{
oss << "clob";
}
else
{
oss << "varchar(" << precision << ")";
}
res += oss.str();
}
break;
case db_date:
res += "timestamp";
break;
case db_double:
{
std::ostringstream oss;
if (precision == 0)
{
oss << "number";
}
else
{
oss << "number(" << precision << ", " << scale << ")";
}
res += oss.str();
}
break;
case db_int16:
res += "smallint";
break;
case db_int32:
res += "integer";
break;
case db_int64:
res += "number";
break;
case db_uint64:
res += "number";
break;
case db_blob:
res += "blob";
break;
case db_xml:
res += "xmltype";
break;
default:
throw soci_error("this db_type is not supported in create_column");
}
return res;
}
std::string add_column(const std::string & tableName,
const std::string & columnName, db_type dt,
int precision, int scale) override
{
return "alter table " + tableName + " add " +
columnName + " " + create_column_type(dt, precision, scale);
}
std::string alter_column(const std::string & tableName,
const std::string & columnName, db_type dt,
int precision, int scale) override
{
return "alter table " + tableName + " modify " +
columnName + " " + create_column_type(dt, precision, scale);
}
std::string empty_blob() override
{
return "empty_blob()";
}
std::string nvl() override
{
return "nvl";
}
bool get_next_sequence_value(session &s,
std::string const &sequence, long long &value) override;
std::string get_dummy_from_table() const override { return "dual"; }
std::string get_backend_name() const override { return "oracle"; }
void clean_up();
oracle_statement_backend * make_statement_backend() override;
oracle_rowid_backend * make_rowid_backend() override;
oracle_blob_backend * make_blob_backend() override;
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() {}
oracle_session_backend * make_session(
connection_parameters const & parameters) const override;
};
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

View File

@@ -0,0 +1,442 @@
//
// 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
#include <soci/soci-platform.h>
#ifdef SOCI_POSTGRESQL_SOURCE
# define SOCI_POSTGRESQL_DECL SOCI_DECL_EXPORT
#else
# define SOCI_POSTGRESQL_DECL SOCI_DECL_IMPORT
#endif
#include <soci/soci-backend.h>
#include "soci/connection-parameters.h"
#include <libpq-fe.h>
#include <vector>
#include <unordered_map>
namespace soci
{
class SOCI_POSTGRESQL_DECL postgresql_soci_error : public soci_error
{
public:
postgresql_soci_error(std::string const & msg, char const * sqlst);
std::string sqlstate() const;
error_category get_error_category() const override { return cat_; }
private:
char sqlstate_[ 5 ]; // not std::string to keep copy-constructor no-throw
error_category cat_;
};
struct postgresql_session_backend;
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 result object and will call PQclear() on it.
explicit postgresql_result(
postgresql_session_backend & sessionBackend,
PGresult * result)
: sessionBackend_(sessionBackend)
{
init(result);
}
// Frees any currently stored result pointer and takes ownership of the
// given one.
void reset(PGresult* result = NULL)
{
clear();
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() { clear(); }
private:
void init(PGresult* result)
{
result_ = result;
}
void clear()
{
// Notice that it is safe to call PQclear() with NULL pointer, it
// simply does nothing in this case.
PQclear(result_);
}
postgresql_session_backend & sessionBackend_;
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) {}
void define_by_pos(int & position,
void * data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch,
indicator * ind) override;
void clean_up() override;
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), user_ranges_(true) {}
void define_by_pos(int & position,
void * data, details::exchange_type type) override
{
user_ranges_ = false;
define_by_pos_bulk(position, data, type, 0, &end_var_);
}
void define_by_pos_bulk(int & position,
void * data, details::exchange_type type,
std::size_t begin, std::size_t * end) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator * ind) override;
void resize(std::size_t sz) override;
std::size_t size() override; // active size (might be lower than full vector size)
std::size_t full_size(); // actual size of the user-provided vector
void clean_up() override;
postgresql_statement_backend & statement_;
void * data_;
details::exchange_type type_;
std::size_t begin_;
std::size_t * end_;
std::size_t end_var_;
bool user_ranges_;
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) {}
void bind_by_pos(int & position,
void * data, details::exchange_type type, bool readOnly) override;
void bind_by_name(std::string const & name,
void * data, details::exchange_type type, bool readOnly) override;
void pre_use(indicator const * ind) override;
void post_use(bool gotData, indicator * ind) override;
void clean_up() override;
postgresql_statement_backend & statement_;
void * data_;
details::exchange_type type_;
int position_;
std::string name_;
char * buf_;
private:
// Allocate buf_ of appropriate size and copy string data into it.
void copy_from_string(std::string const& s);
};
struct postgresql_vector_use_type_backend : details::vector_use_type_backend
{
postgresql_vector_use_type_backend(postgresql_statement_backend & st)
: statement_(st), position_(0) {}
void bind_by_pos(int & position,
void * data, details::exchange_type type) override
{
bind_by_pos_bulk(position, data, type, 0, &end_var_);
}
void bind_by_pos_bulk(int & position,
void * data, details::exchange_type type,
std::size_t begin, std::size_t * end) override;
void bind_by_name(std::string const & name,
void * data, details::exchange_type type) override
{
bind_by_name_bulk(name, data, type, 0, &end_var_);
}
void bind_by_name_bulk(const std::string & name,
void * data, details::exchange_type type,
std::size_t begin, std::size_t * end) override;
void pre_use(indicator const * ind) override;
std::size_t size() override; // active size (might be lower than full vector size)
std::size_t full_size(); // actual size of the user-provided vector
void clean_up() override;
postgresql_statement_backend & statement_;
void * data_;
details::exchange_type type_;
std::size_t begin_;
std::size_t * end_;
std::size_t end_var_;
int position_;
std::string name_;
std::vector<char *> buffers_;
};
struct postgresql_statement_backend : details::statement_backend
{
postgresql_statement_backend(postgresql_session_backend & session,
bool single_row_mode);
~postgresql_statement_backend() override;
void alloc() override;
void clean_up() override;
void prepare(std::string const & query,
details::statement_type stType) override;
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const & query) override;
int prepare_for_describe() override;
void describe_column(int colNum,
db_type & dbtype,
std::string & columnName) override;
postgresql_standard_into_type_backend * make_into_type_backend() override;
postgresql_standard_use_type_backend * make_use_type_backend() override;
postgresql_vector_into_type_backend * make_vector_into_type_backend() override;
postgresql_vector_use_type_backend * make_vector_use_type_backend() override;
postgresql_session_backend & session_;
bool single_row_mode_;
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_;
// the following map is used to keep the results of column
// type queries with custom types
typedef std::unordered_map<unsigned long, char> CategoryByColumnOID;
CategoryByColumnOID categoryByColumnOID_;
};
struct postgresql_rowid_backend : details::rowid_backend
{
postgresql_rowid_backend(postgresql_session_backend & session);
~postgresql_rowid_backend() override;
unsigned long value_;
};
class postgresql_blob_backend : public details::blob_backend
{
public:
struct blob_details
{
// OID of the large object
unsigned long oid;
// File descriptor of the large object
int fd;
blob_details();
blob_details(unsigned long oid, int fd);
};
postgresql_blob_backend(postgresql_session_backend & session);
~postgresql_blob_backend() override;
std::size_t get_len() override;
std::size_t read_from_start(void * buf, std::size_t toRead, std::size_t offset = 0) override;
std::size_t write_from_start(const void * buf, std::size_t toWrite, std::size_t offset = 0) override;
std::size_t append(const void * buf, std::size_t toWrite) override;
void trim(std::size_t newLen) override;
const blob_details &get_blob_details() const;
void set_blob_details(const blob_details &details);
bool get_destroy_on_close() const;
void set_destroy_on_close(bool destroy);
void set_clone_before_modify(bool clone);
void init();
void reset();
private:
postgresql_session_backend & session_;
blob_details details_;
bool destroy_on_close_;
bool clone_before_modify_;
std::size_t seek(std::size_t toOffset, int from);
void clone();
};
struct postgresql_session_backend : details::session_backend
{
postgresql_session_backend(connection_parameters const & parameters,
bool single_row_mode);
~postgresql_session_backend() override;
void connect(connection_parameters const & parameters);
bool is_connected() override;
void begin() override;
void commit() override;
void rollback() override;
void deallocate_prepared_statement(const std::string & statementName);
bool get_next_sequence_value(session & s,
std::string const & sequence, long long & value) override;
std::string get_dummy_from_table() const override { return std::string(); }
std::string get_backend_name() const override { return "postgresql"; }
void clean_up();
postgresql_statement_backend * make_statement_backend() override;
postgresql_rowid_backend * make_rowid_backend() override;
postgresql_blob_backend * make_blob_backend() override;
std::string get_next_statement_name();
int statementCount_;
bool single_row_mode_;
PGconn * conn_;
connection_parameters connectionParameters_;
};
struct postgresql_backend_factory : backend_factory
{
postgresql_backend_factory() {}
postgresql_session_backend * make_session(
connection_parameters const & parameters) const override;
};
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

View 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

90
3rdparty/soci/include/soci/procedure.h vendored Normal file
View File

@@ -0,0 +1,90 @@
//
// 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)), gotData_(false) {}
~procedure() { impl_->dec_ref(); }
// copy is supported here
procedure(procedure const & other)
: impl_(other.impl_), gotData_(other.gotData_)
{
impl_->inc_ref();
}
void operator=(procedure const & other)
{
other.impl_->inc_ref();
impl_->dec_ref();
impl_ = other.impl_;
gotData_ = other.gotData_;
}
// 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

View File

@@ -0,0 +1,57 @@
//
// 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 <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:
virtual ~query_transformation_function() {}
virtual std::string operator()(std::string const&) const = 0;
};
template <typename T>
class query_transformation : public query_transformation_function
{
public:
query_transformation(T callback)
: callback_(callback)
{}
std::string operator()(std::string const& query) const override
{
return callback_(query);
}
private:
T callback_;
};
} // namespace details
} // namespace soci
#endif // SOCI_QUERY_TRANSFORMATION_H_INCLUDED

View 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() override;
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

View File

@@ -0,0 +1,102 @@
//
// Copyright (C) 2004-2016 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
{
if (tail_.empty() == false)
{
accumulate(tail_);
}
final_action();
}
catch (...)
{
delete this;
throw;
}
delete this;
}
}
template <typename T>
void accumulate(T const & t) { get_query_stream() << t; }
void set_tail(const std::string & tail) { tail_ = tail; }
void set_need_comma(bool need_comma) { need_comma_ = need_comma; }
bool get_need_comma() const { return need_comma_; }
protected:
// this function allows to break the circular dependenc
// between session and this class
std::ostringstream & get_query_stream();
int refCount_;
session & session_;
// used mainly for portable ddl
std::string tail_;
bool need_comma_;
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) {}
void final_action() override;
template <typename T>
void exchange(T &t) { st_.exchange(t); }
private:
statement st_;
};
} // namespace details
} // namespace soci
#endif

View File

@@ -0,0 +1,80 @@
//
// 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
void define(statement_impl & st, int & /* position */) override
{
st.set_row(&r_);
// actual row description is performed
// as part of the statement execute
}
void pre_exec(int /* num */) override {}
void pre_fetch() override {}
void post_fetch(bool gotData, bool /* calledFromFetch */) override
{
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();
}
}
void clean_up() override {}
std::size_t size() const override { 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

202
3rdparty/soci/include/soci/row.h vendored Normal file
View File

@@ -0,0 +1,202 @@
//
// 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/blob.h"
#include "soci/type-conversion-traits.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_; }
// DEPRECATED. USE get_db_type() INSTEAD.
data_type get_data_type() const { return dataType_; }
db_type get_db_type() const { return dbType_; }
void set_name(std::string const& name) { name_ = name; }
// DEPRECATED. USE set_db_type(db_type) INSTEAD.
void set_data_type(data_type dataType) { dataType_ = dataType; }
void set_db_type(db_type dataType) { dbType_ = dataType; }
private:
std::string name_;
// DEPRECATED. USE exchangeDataType_ INSTEAD.
data_type dataType_;
db_type dbType_;
};
class SOCI_DECL row
{
public:
row();
~row();
row(row &&other) = default;
row &operator=(row &&other) = default;
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(details::holder::make_holder(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;
static_assert(details::can_use_from_base<type_conversion<T>>(),
"Can't use row::get() with this type (not convertible/copy-assignable from base_type) - did you mean to use move_as?");
base_type const& baseVal =
holders_.at(pos)->get<base_type>(details::value_cast_tag{});
T ret;
type_conversion<T>::from_base(baseVal, *indicators_.at(pos), ret);
return ret;
}
template <typename T>
T move_as(std::size_t pos) const
{
typedef typename type_conversion<T>::base_type base_type;
static_assert(details::can_use_move_from_base<T, base_type>(),
"row::move_as() can only be called with types that can be instantiated from a base type rvalue reference");
base_type & baseVal =
holders_.at(pos)->get<base_type>(details::value_reference_tag{});
T ret;
type_conversion<T>::move_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 move_as(std::size_t pos, T const &nullValue) const
{
if (i_null == *indicators_.at(pos))
{
return nullValue;
}
return move_as<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 move_as(std::string const &name) const
{
std::size_t const pos = find_column(name);
return move_as<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>
T move_as(std::string const &name, T const &nullValue) const
{
std::size_t const pos = find_column(name);
if (i_null == *indicators_[pos])
{
return nullValue;
}
return move_as<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_;
};
template <>
blob SOCI_DECL row::move_as<blob>(std::size_t pos) const;
} // namespace soci
#endif // SOCI_ROW_H_INCLUDED

View 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
3rdparty/soci/include/soci/rowid.h vendored Normal file
View 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

241
3rdparty/soci/include/soci/rowset.h vendored Normal file
View File

@@ -0,0 +1,241 @@
//
// 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/soci-platform.h"
#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()
: refs_(1), st_(nullptr), define_(nullptr)
{
}
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. Empty rowset doesn't have any valid begin iterator.
return st_ ? iterator(*st_, *define_) : iterator();
}
iterator end() const
{
return iterator();
}
private:
unsigned int refs_;
const std::unique_ptr<statement> st_;
const std::unique_ptr<T> define_;
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_(new details::rowset_impl<T>())
{
}
// Due to the existence of conversion from session to prepare_temp_type, it
// would have been possible to construct a rowset from session if we didn't
// delete this ctor -- so do delete it because it doesn't make sense to
// provide such constructor.
rowset(session const& session) = delete;
~rowset()
{
pimpl_->decRef();
}
rowset& operator=(rowset const& rhs)
{
if (&rhs != this)
{
rhs.pimpl_->incRef();
pimpl_->decRef();
pimpl_ = rhs.pimpl_;
}
return *this;
}
void clear()
{
*this = rowset();
}
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

239
3rdparty/soci/include/soci/session.h vendored Normal file
View File

@@ -0,0 +1,239 @@
//
// Copyright (C) 2004-2016 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/soci-platform.h"
#include "soci/once-temp-type.h"
#include "soci/query_transformation.h"
#include "soci/connection-parameters.h"
#include "soci/logger.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 failover_callback;
class SOCI_DECL session
{
private:
void set_query_transformation_(std::unique_ptr<details::query_transformation_function>&& qtf);
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(session &&other);
session &operator=(session &&other);
~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();
// check if we have a working connection to the database
bool is_connected() const noexcept;
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)
{
set_query_transformation_(std::make_unique<details::query_transformation<T>>(callback));
}
// Support for custom logging of database operations.
// Set the custom logger to use.
void set_logger(logger const & logger);
// Return the currently used logger, by default, this is an instance of a
// standard SOCI logger.
logger const & get_logger() const;
// support for basic logging (use set_logger() for more control).
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 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 long & value);
// Returns once_temp_type for the internally composed query
// for the list of tables in the current schema.
// Since this query usually returns multiple results (for multiple tables),
// it makes sense to bind std::vector<std::string> for the single output field.
details::once_temp_type get_table_names();
// Returns prepare_temp_type for the internally composed query
// for the list of tables in the current schema.
// Since this is intended for use with statement objects, where results are obtained one row after another,
// it makes sense to bind std::string for the output field.
details::prepare_temp_type prepare_table_names();
// Returns prepare_temp_type for the internally composed query
// for the list of column descriptions.
// Since this is intended for use with statement objects, where results are obtained one row after another,
// it makes sense to bind either std::string for each output field or soci::column_info for the whole row.
// Note: table_name is a non-const reference to prevent temporary objects,
// this argument is bound as a regular "use" element.
details::prepare_temp_type prepare_column_descriptions(std::string & table_name);
// Functions for basic portable DDL statements.
ddl_type create_table(const std::string & tableName);
void drop_table(const std::string & tableName);
void truncate_table(const std::string & tableName);
ddl_type add_column(const std::string & tableName,
const std::string & columnName, db_type dt,
int precision = 0, int scale = 0);
ddl_type alter_column(const std::string & tableName,
const std::string & columnName, db_type dt,
int precision = 0, int scale = 0);
ddl_type drop_column(const std::string & tableName,
const std::string & columnName);
std::string empty_blob();
std::string nvl();
// And some functions to help with writing portable DML statements.
// Get the name of the dummy table that needs to be used in the FROM clause
// of a SELECT statement not operating on any tables, e.g. "dual" for
// Oracle. The returned string is empty if no such table is needed.
std::string get_dummy_from_table() const;
// Returns a possibly empty string that needs to be used as a FROM clause
// of a SELECT statement not operating on any tables, e.g. " FROM DUAL"
// (notice the leading space).
std::string get_dummy_from_clause() const;
// Sets the failover callback object.
void set_failover_callback(failover_callback & callback);
// 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;
// The functions below still work but are deprecated (but we don't give
// deprecation warnings for them because there is no real harm in using
// them).
//
// Use the overloads taking db_type instead in the new code.
ddl_type add_column(const std::string & tableName,
const std::string & columnName, data_type dt,
int precision = 0, int scale = 0)
{
return add_column(tableName, columnName, details::to_db_type(dt),
precision, scale);
}
ddl_type alter_column(const std::string & tableName,
const std::string & columnName, data_type dt,
int precision = 0, int scale = 0)
{
return alter_column(tableName, columnName, details::to_db_type(dt),
precision, scale);
}
details::statement_backend * make_statement_backend();
details::rowid_backend * make_rowid_backend();
details::blob_backend * make_blob_backend();
private:
SOCI_NOT_COPYABLE(session)
void reset_after_move();
std::ostringstream query_stream_;
std::unique_ptr<details::query_transformation_function> query_transformation_;
logger logger_;
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

View File

@@ -0,0 +1,591 @@
//
// Copyright (C) 2004-2016 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>
#include <sstream>
#include <vector>
#include <algorithm>
#include <cstring>
namespace soci
{
// data types, as seen by the user
enum db_type
{
db_string,
db_int8,
db_uint8,
db_int16,
db_uint16,
db_int32,
db_uint32,
db_int64,
db_uint64,
db_double,
db_date,
db_blob,
db_xml
};
// DEPRECATED. USE db_type INSTEAD.
enum data_type
{
dt_string, dt_date, dt_double, dt_integer, dt_long_long, dt_unsigned_long_long,
dt_blob, dt_xml
};
// the enum type for indicator variables
enum indicator { i_ok, i_null, i_truncated };
class session;
class failover_callback;
namespace details
{
// data types, as used to describe exchange format
enum exchange_type
{
x_char,
x_stdstring,
x_int8,
x_uint8,
x_int16,
x_uint16,
x_int32,
x_uint32,
x_int64,
x_uint64,
x_double,
x_stdtm,
x_statement,
x_rowid,
x_blob,
x_xmltype,
x_longstring,
// Deprecated synonyms.
x_short = x_int16,
x_integer = x_int32,
x_long_long = x_int64,
x_unsigned_long_long = x_uint64
};
// type of statement (used for optimizing statement preparation)
enum statement_type
{
st_one_time_query,
st_repeatable_query
};
// (lossless) conversion from the legacy data type enum
inline db_type to_db_type(data_type dt)
{
switch (dt)
{
case dt_string: return db_string;
case dt_date: return db_date;
case dt_double: return db_double;
case dt_integer: return db_int32;
case dt_long_long: return db_int64;
case dt_unsigned_long_long: return db_uint64;
case dt_blob: return db_blob;
case dt_xml: return db_xml;
}
// unreachable
return db_string;
}
// 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_exec(int /* num */) {}
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_bulk(
int & /* position */, void * /* data */, exchange_type /* type */,
std::size_t /* begin */, std::size_t * /* end */)
{
throw soci_error("into bulk iterators are not supported with this backend");
}
virtual void define_by_pos(int& position, void* data, exchange_type type) = 0;
virtual void pre_exec(int /* num */) {}
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_exec(int /* num */) {}
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_pos_bulk(int& /* position */, void* /* data */, exchange_type /* type */,
std::size_t /* begin */, std::size_t * /* end */)
{
throw soci_error("using bulk iterators are not supported with this backend");
}
virtual void bind_by_name(std::string const& name,
void* data, exchange_type type) = 0;
virtual void bind_by_name_bulk(std::string const& /* name */,
void* /* data */, exchange_type /* type */,
std::size_t /* begin */, std::size_t * /* end */)
{
throw soci_error("using bulk iterators are not supported with this backend");
}
virtual void pre_exec(int /* num */) {}
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,
db_type& dbtype,
std::string& column_name) = 0;
// Function converting db_type to legacy data_type: this is mostly, but not
// quite, backend-independent because different backends handled the same
// type differently before db_type introduction.
virtual data_type to_data_type(db_type dbt) const
{
switch (dbt)
{
case db_string: return dt_string;
case db_date: return dt_date;
case db_double: return dt_double;
case db_int8:
case db_uint8:
case db_int16:
case db_uint16:
case db_int32: return dt_integer;
case db_uint32:
case db_int64: return dt_long_long;
case db_uint64: return dt_unsigned_long_long;
case db_blob: return dt_blob;
case db_xml: return dt_xml;
}
// unreachable
return dt_string;
}
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_from_start(void* buf, std::size_t toRead, std::size_t offset) = 0;
virtual std::size_t write_from_start(const void* buf, std::size_t toWrite, std::size_t offset) = 0;
virtual std::size_t append(const void* buf, std::size_t toWrite) = 0;
virtual void trim(std::size_t newLen) = 0;
// Deprecated functions with backend-specific semantics preserved only for
// compatibility.
[[deprecated("Use read_from_start instead")]]
std::size_t read(std::size_t offset, void* buf, std::size_t toRead) { return do_deprecated_read(offset, buf, toRead); }
[[deprecated("Use write_from_start instead")]]
virtual std::size_t write(std::size_t offset, const void* buf, std::size_t toWrite) { return do_deprecated_write(offset, buf, toWrite); }
private:
virtual std::size_t do_deprecated_read(std::size_t offset, void* buf, std::size_t toRead) { return read_from_start(buf, toRead, offset); }
virtual std::size_t do_deprecated_write(std::size_t offset, const void* buf, std::size_t toWrite) { return write_from_start(buf, toWrite, offset); }
SOCI_NOT_COPYABLE(blob_backend)
};
// polymorphic session backend
class session_backend
{
public:
session_backend() : failoverCallback_(NULL), session_(NULL) {}
virtual ~session_backend() {}
virtual bool is_connected() = 0;
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 long&)
{
return false;
}
virtual bool get_last_insert_id(session&, std::string const&, long long&)
{
return false;
}
// There is a set of standard SQL metadata structures that can be
// queried in a portable way - backends that are standard compliant
// do not need to override the following methods, which are intended
// to return a proper query for basic metadata statements.
// Returns a parameterless query for the list of table names in the current schema.
virtual std::string get_table_names_query() const
{
return "select table_name as \"TABLE_NAME\""
" from information_schema.tables"
" where table_schema = 'public'";
}
// Returns a query with a single parameter (table name) for the list
// of columns and their properties.
virtual std::string get_column_descriptions_query() const
{
return "select column_name as \"COLUMN_NAME\","
" data_type as \"DATA_TYPE\","
" character_maximum_length as \"CHARACTER_MAXIMUM_LENGTH\","
" numeric_precision as \"NUMERIC_PRECISION\","
" numeric_scale as \"NUMERIC_SCALE\","
" is_nullable as \"IS_NULLABLE\""
" from information_schema.columns"
" where table_schema = 'public' and table_name = :t";
}
virtual std::string create_table(const std::string & tableName)
{
return "create table " + tableName + " (";
}
virtual std::string drop_table(const std::string & tableName)
{
return "drop table " + tableName;
}
virtual std::string truncate_table(const std::string & tableName)
{
return "truncate table " + tableName;
}
virtual std::string create_column_type(db_type dt,
int precision, int scale)
{
// PostgreSQL was selected as a baseline for the syntax:
std::string res;
switch (dt)
{
case db_string:
{
std::ostringstream oss;
if (precision == 0)
{
oss << "text";
}
else
{
oss << "varchar(" << precision << ")";
}
res += oss.str();
}
break;
case db_date:
res += "timestamp";
break;
case db_double:
{
std::ostringstream oss;
if (precision == 0)
{
oss << "numeric";
}
else
{
oss << "numeric(" << precision << ", " << scale << ")";
}
res += oss.str();
}
break;
case db_int16:
case db_uint16:
res += "smallint";
break;
case db_int32:
case db_uint32:
res += "integer";
break;
case db_int64:
case db_uint64:
res += "bigint";
break;
case db_blob:
res += "oid";
break;
case db_xml:
res += "xml";
break;
default:
throw soci_error("this db_type is not supported in create_column");
}
return res;
}
virtual std::string add_column(const std::string & tableName,
const std::string & columnName,
db_type dt,
int precision, int scale)
{
return "alter table " + tableName + " add column " + columnName +
" " + create_column_type(dt, precision, scale);
}
virtual std::string alter_column(const std::string & tableName,
const std::string & columnName,
db_type dt,
int precision, int scale)
{
return "alter table " + tableName + " alter column " +
columnName + " type " +
create_column_type(dt, precision, scale);
}
virtual std::string drop_column(const std::string & tableName,
const std::string & columnName)
{
return "alter table " + tableName +
" drop column " + columnName;
}
virtual std::string constraint_unique(const std::string & name,
const std::string & columnNames)
{
return "constraint " + name +
" unique (" + columnNames + ")";
}
virtual std::string constraint_primary_key(const std::string & name,
const std::string & columnNames)
{
return "constraint " + name +
" primary key (" + columnNames + ")";
}
virtual std::string constraint_foreign_key(const std::string & name,
const std::string & columnNames,
const std::string & refTableName,
const std::string & refColumnNames)
{
return "constraint " + name +
" foreign key (" + columnNames + ")" +
" references " + refTableName + " (" + refColumnNames + ")";
}
virtual std::string empty_blob()
{
return "lo_creat(-1)";
}
virtual std::string nvl()
{
return "coalesce";
}
virtual std::string get_dummy_from_table() const = 0;
void set_failover_callback(failover_callback & callback, session & sql)
{
failoverCallback_ = &callback;
session_ = &sql;
}
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;
// The functions below still work but are deprecated (but we don't give
// deprecation warnings for them because there is no real harm in using
// them).
//
// Use the overloads taking db_type instead in the new code.
std::string create_column_type(data_type dt, int precision, int scale)
{
return create_column_type(to_db_type(dt), precision, scale);
}
std::string add_column(const std::string & tableName,
const std::string & columnName, data_type dt,
int precision, int scale)
{
return add_column(tableName, columnName, to_db_type(dt), precision, scale);
}
std::string alter_column(const std::string & tableName,
const std::string & columnName, data_type dt,
int precision, int scale)
{
return alter_column(tableName, columnName, to_db_type(dt), precision, scale);
}
failover_callback * failoverCallback_;
session * session_;
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

View File

@@ -0,0 +1,16 @@
//
// 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
//
// SOCI has been build with support for:
//
//@CONFIGURED_VARIABLES@
#endif // SOCICONFIG_H_INCLUDED

View File

@@ -0,0 +1,197 @@
//
// 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>
#include <memory>
#include "soci/soci-config.h" // for SOCI_HAVE_CXX11
#if defined(_MSC_VER)
#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.
#if _MSC_VER < 1900
# define snprintf _snprintf
#endif
// 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
#ifdef _WIN32
# ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0502 //_WIN32_WINNT_WS03, VS2015 support: https://msdn.microsoft.com/de-de/library/6sehtctf.aspx
# endif
# ifdef SOCI_DLL
# define SOCI_DECL_EXPORT __declspec(dllexport)
# define SOCI_DECL_IMPORT __declspec(dllimport)
# endif
#elif defined(SOCI_HAVE_VISIBILITY_SUPPORT)
# define SOCI_DECL_EXPORT __attribute__ (( visibility("default") ))
# define SOCI_DECL_IMPORT __attribute__ (( visibility("default") ))
#endif
#ifndef SOCI_DECL_EXPORT
# define SOCI_DECL_EXPORT
# define SOCI_DECL_IMPORT
#endif
// Define SOCI_DECL
#ifdef SOCI_SOURCE
# define SOCI_DECL SOCI_DECL_EXPORT
#else
# define SOCI_DECL SOCI_DECL_IMPORT
#endif
// C++11 features are always available in MSVS as it has no separate C++98
// mode, we just need to check for the minimal compiler version supporting them
// (see https://msdn.microsoft.com/en-us/library/hh567368.aspx).
#ifdef _MSC_VER
#if _MSC_VER < 1900
#error This version of SOCI requires MSVS 2015 or later.
#endif
#if _MSVC_LANG >= 201703L
#define SOCI_HAVE_CXX17
#endif
#else
#if __cplusplus < 201402L
#error This version of SOCI requires C++14.
#endif
#if __cplusplus >= 201703L
#define SOCI_HAVE_CXX17
#endif
#endif
// Define SOCI_ALLOW_DEPRECATED_BEGIN and SOCI_ALLOW_DEPRECATED_END
// Ref.: https://www.fluentcpp.com/2019/08/30/how-to-disable-a-warning-in-cpp/
#if defined(__GNUC__) || defined(__clang__)
# define SOCI_ALLOW_DEPRECATED_BEGIN \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wdeprecated\"") \
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
# define SOCI_ALLOW_DEPRECATED_END \
_Pragma("GCC diagnostic pop")
#elif defined(_MSC_VER)
# define SOCI_ALLOW_DEPRECATED_BEGIN \
__pragma(warning(push)) \
__pragma(warning(disable: 4973 )) \
__pragma(warning(disable: 4974 )) \
__pragma(warning(disable: 4995 )) \
__pragma(warning(disable: 4996 ))
# define SOCI_ALLOW_DEPRECATED_END \
__pragma(warning(pop))
# define SOCI_DONT_WARN(statement) statement
#else
# pragma message("WARNING: SOCI_ALLOW_DEPRECATED_* not available for this compilet")
# define SOCI_ALLOW_DEPRECATED_BEGIN
# define SOCI_ALLOW_DEPRECATED_END
#endif
#define SOCI_NOT_ASSIGNABLE(classname) \
public: \
classname(const classname&) = default; \
private: \
classname& operator=(const classname&) = delete;
#define SOCI_NOT_COPYABLE(classname) \
classname(const classname&) = delete; \
classname& operator=(const classname&) = delete;
#define SOCI_UNUSED(x) (void)x;
// This macro can be used to avoid warnings from MSVC (and sometimes from gcc,
// if initialization is indirect) about "uninitialized" variables that are
// actually always initialized. Using this macro makes it clear that the
// initialization is only necessary to avoid compiler warnings and also will
// allow us to define it as doing nothing if we ever use a compiler warning
// about initializing variables unnecessarily.
#define SOCI_DUMMY_INIT(x) (x)
// And this one can be used to return after calling a "[[noreturn]]" function.
// Here the problem is that MSVC complains about unreachable code in this case
// (but only in release builds, where optimizations are enabled), while other
// compilers complain about missing return statement without it.
#if defined(_MSC_VER) && defined(NDEBUG)
#define SOCI_DUMMY_RETURN(x)
#else
#define SOCI_DUMMY_RETURN(x) return x
#endif
#define SOCI_OS_LINUX 0x0001
#define SOCI_OS_FREE_BSD 0x0002
#define SOCI_OS_APPLE 0x0003
#define SOCI_OS_WINDOWS 0x0004
#if defined(linux) || defined(__linux) || defined(__linux__)
#define SOCI_OS SOCI_OS_LINUX
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#define SOCI_OS SOCI_OS_FREE_BSD
#elif defined(__APPLE__)
#define SOCI_OS SOCI_OS_APPLE
#elif defined(_WIN32) || defined(_WIN64)
#define SOCI_OS SOCI_OS_WINDOWS
#endif
#if !defined(SOCI_OS)
#error "Unknown platform"
#endif
#endif // SOCI_PLATFORM_H_INCLUDED

244
3rdparty/soci/include/soci/soci-simple.h vendored Normal file
View File

@@ -0,0 +1,244 @@
//
// 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"
#include <cstdint>
#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);
[[deprecated("Use soci_blob_read_from_start instead")]]
SOCI_DECL int soci_blob_read(blob_handle b, int offset, char *buf, int toRead);
SOCI_DECL int soci_blob_read_from_start(blob_handle b, char *buf, int toRead, int offset = 0);
[[deprecated("Use soci_blob_write_from_start instead")]]
SOCI_DECL int soci_blob_write(blob_handle b, int offset, char const *buf, int toWrite);
SOCI_DECL int soci_blob_write_from_start(blob_handle b, char const *buf, int toWrite, int offset = 0);
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_int8 (statement_handle st);
SOCI_DECL int soci_into_uint8 (statement_handle st);
SOCI_DECL int soci_into_int16 (statement_handle st);
SOCI_DECL int soci_into_uint16 (statement_handle st);
SOCI_DECL int soci_into_int32 (statement_handle st);
SOCI_DECL int soci_into_uint32 (statement_handle st);
SOCI_DECL int soci_into_int64 (statement_handle st);
SOCI_DECL int soci_into_uint64 (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_int8_v (statement_handle st);
SOCI_DECL int soci_into_uint8_v (statement_handle st);
SOCI_DECL int soci_into_int16_v (statement_handle st);
SOCI_DECL int soci_into_uint16_v (statement_handle st);
SOCI_DECL int soci_into_int32_v (statement_handle st);
SOCI_DECL int soci_into_uint32_v (statement_handle st);
SOCI_DECL int soci_into_int64_v (statement_handle st);
SOCI_DECL int soci_into_uint64_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 int8_t soci_get_into_int8 (statement_handle st, int position);
SOCI_DECL uint8_t soci_get_into_uint8 (statement_handle st, int position);
SOCI_DECL int16_t soci_get_into_int16 (statement_handle st, int position);
SOCI_DECL uint16_t soci_get_into_uint16 (statement_handle st, int position);
SOCI_DECL int32_t soci_get_into_int32 (statement_handle st, int position);
SOCI_DECL uint32_t soci_get_into_uint32 (statement_handle st, int position);
SOCI_DECL int64_t soci_get_into_int64 (statement_handle st, int position);
SOCI_DECL uint64_t soci_get_into_uint64 (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 int8_t soci_get_into_int8_v (statement_handle st, int position, int index);
SOCI_DECL uint8_t soci_get_into_uint8_v (statement_handle st, int position, int index);
SOCI_DECL int16_t soci_get_into_int16_v (statement_handle st, int position, int index);
SOCI_DECL uint16_t soci_get_into_uint16_v (statement_handle st, int position, int index);
SOCI_DECL int32_t soci_get_into_int32_v (statement_handle st, int position, int index);
SOCI_DECL uint32_t soci_get_into_uint32_v (statement_handle st, int position, int index);
SOCI_DECL int64_t soci_get_into_int64_v (statement_handle st, int position, int index);
SOCI_DECL uint64_t soci_get_into_uint64_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_int8 (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint8 (statement_handle st, char const * name);
SOCI_DECL void soci_use_int16 (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint16 (statement_handle st, char const * name);
SOCI_DECL void soci_use_int32 (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint32 (statement_handle st, char const * name);
SOCI_DECL void soci_use_int64 (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint64 (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_int8_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint8_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_int16_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint16_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_int32_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint32_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_int64_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint64_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_int8 (statement_handle st, char const * name, int8_t val);
SOCI_DECL void soci_set_use_uint8 (statement_handle st, char const * name, uint8_t val);
SOCI_DECL void soci_set_use_int18 (statement_handle st, char const * name, int16_t val);
SOCI_DECL void soci_set_use_uint18 (statement_handle st, char const * name, uint16_t val);
SOCI_DECL void soci_set_use_int32 (statement_handle st, char const * name, int32_t val);
SOCI_DECL void soci_set_use_uint32 (statement_handle st, char const * name, uint32_t val);
SOCI_DECL void soci_set_use_int64 (statement_handle st, char const * name, int64_t val);
SOCI_DECL void soci_set_use_uint64 (statement_handle st, char const * name, uint64_t 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_int8_v(statement_handle st,
char const * name, int index, int8_t val);
SOCI_DECL void soci_set_use_uint8_v(statement_handle st,
char const * name, int index, uint8_t val);
SOCI_DECL void soci_set_use_int16_v(statement_handle st,
char const * name, int index, int16_t val);
SOCI_DECL void soci_set_use_uint16_v(statement_handle st,
char const * name, int index, uint16_t val);
SOCI_DECL void soci_set_use_int32_v(statement_handle st,
char const * name, int index, int32_t val);
SOCI_DECL void soci_set_use_uint32_v(statement_handle st,
char const * name, int index, uint32_t val);
SOCI_DECL void soci_set_use_int64_v(statement_handle st,
char const * name, int index, int64_t val);
SOCI_DECL void soci_set_use_uint64_v(statement_handle st,
char const * name, int index, uint64_t 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 int8_t soci_get_use_int8 (statement_handle st, char const * name);
SOCI_DECL uint8_t soci_get_use_uint8 (statement_handle st, char const * name);
SOCI_DECL int16_t soci_get_use_int16 (statement_handle st, char const * name);
SOCI_DECL uint16_t soci_get_use_uint16 (statement_handle st, char const * name);
SOCI_DECL int32_t soci_get_use_int32 (statement_handle st, char const * name);
SOCI_DECL uint32_t soci_get_use_uint32 (statement_handle st, char const * name);
SOCI_DECL int64_t soci_get_use_int64 (statement_handle st, char const * name);
SOCI_DECL uint64_t soci_get_use_uint64 (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

15
3rdparty/soci/include/soci/soci-types.h vendored Normal file
View File

@@ -0,0 +1,15 @@
#ifndef SOCI_TYPES_H_INCLUDED
#define SOCI_TYPES_H_INCLUDED
#include "soci/soci-platform.h"
#if defined(__GNUC__) || defined(__clang__)
#if defined(__LP64__)
#define SOCI_LONG_IS_64_BIT 1
#if SOCI_OS == SOCI_OS_LINUX || SOCI_OS == SOCI_OS_FREE_BSD
#define SOCI_INT64_IS_LONG 1
#endif
#endif
#endif
#endif // SOCI_TYPES_H_INCLUDED

63
3rdparty/soci/include/soci/soci.h vendored Normal file
View File

@@ -0,0 +1,63 @@
//
// 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/column-info.h"
#include "soci/connection-pool.h"
#include "soci/error.h"
#include "soci/exchange-traits.h"
#include "soci/fixed-size-ints.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/type-wrappers.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
// C++17
#ifdef SOCI_HAVE_CXX17
#include "soci/std-optional.h"
#endif // SOCI_HAVE_CXX17
#endif // SOCI_H_INCLUDED

View File

@@ -0,0 +1,384 @@
//
// 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
#include <soci/soci-platform.h>
#ifdef SOCI_SQLITE3_SOURCE
# define SOCI_SQLITE3_DECL SOCI_DECL_EXPORT
#else
# define SOCI_SQLITE3_DECL SOCI_DECL_IMPORT
#endif
#include <cstdarg>
#include <cstdint>
#include <vector>
#include <soci/soci-backend.h>
#include <private/soci-trivial-blob-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 SOCI_SQLITE3_DECL 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), data_(0), type_(), position_(0)
{
}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch,
indicator *ind) override;
void clean_up() override;
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), data_(0), type_(), position_(0)
{
}
void define_by_pos(int& position, void* data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator* ind) override;
void resize(std::size_t sz) override;
std::size_t size() override;
void clean_up() override;
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);
void bind_by_pos(int &position,
void *data, details::exchange_type type, bool readOnly) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type, bool readOnly) override;
void pre_use(indicator const *ind) override;
void post_use(bool gotData, indicator *ind) override;
void clean_up() override;
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), data_(0), type_(), position_(0)
{
}
void bind_by_pos(int &position,
void *data, details::exchange_type type) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type) override;
void pre_use(indicator const *ind) override;
std::size_t size() override;
void clean_up() override;
sqlite3_statement_backend &statement_;
void *data_;
details::exchange_type type_;
int position_;
std::string name_;
};
struct sqlite3_column_buffer
{
std::size_t size_;
union
{
const char *constData_;
char *data_;
};
};
struct sqlite3_column
{
bool isNull_;
// DEPRECATED. USE dataType_ INSTEAD.
data_type type_;
db_type dataType_;
union
{
sqlite3_column_buffer buffer_;
int8_t int8_;
uint8_t uint8_;
int16_t int16_;
uint16_t uint16_;
int32_t int32_;
uint32_t uint32_;
sqlite_api::sqlite3_int64 int64_;
sqlite_api::sqlite3_uint64 uint64_;
double double_;
};
};
typedef std::vector<sqlite3_column> sqlite3_row;
typedef std::vector<sqlite3_row> sqlite3_recordset;
struct sqlite3_column_info
{
// DEPRECATED. USE dataType_ INSTEAD.
data_type type_;
db_type dataType_;
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);
void alloc() override;
void clean_up() override;
void prepare(std::string const &query,
details::statement_type eType) override;
void reset_if_needed();
void reset();
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const &query) override;
int prepare_for_describe() override;
void describe_column(int colNum,
db_type &dbtype,
std::string &columnName) override;
sqlite3_standard_into_type_backend * make_into_type_backend() override;
sqlite3_standard_use_type_backend * make_use_type_backend() override;
sqlite3_vector_into_type_backend * make_vector_into_type_backend() override;
sqlite3_vector_use_type_backend * make_vector_use_type_backend() override;
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_;
bool hasVectorIntoElements_;
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() override;
unsigned long value_;
};
struct sqlite3_blob_backend : details::trivial_blob_backend
{
sqlite3_blob_backend(sqlite3_session_backend &session);
~sqlite3_blob_backend() override;
void ensure_buffer_initialized();
};
struct sqlite3_session_backend : details::session_backend
{
sqlite3_session_backend(connection_parameters const & parameters);
~sqlite3_session_backend() override;
bool is_connected() override { return true; }
void begin() override;
void commit() override;
void rollback() override;
bool get_last_insert_id(session&, std::string const&, long long&) override;
std::string empty_blob() override
{
return "x\'\'";
}
std::string get_dummy_from_table() const override { return std::string(); }
std::string get_backend_name() const override { return "sqlite3"; }
void clean_up();
sqlite3_statement_backend * make_statement_backend() override;
sqlite3_rowid_backend * make_rowid_backend() override;
sqlite3_blob_backend * make_blob_backend() override;
std::string get_table_names_query() const override
{
return "select name as \"TABLE_NAME\""
" from sqlite_master where type = 'table'";
}
std::string get_column_descriptions_query() const override
{
return "select name as 'COLUMN_NAME',"
" 0 as 'CHARACTER_MAXIMUM_LENGTH',"
" 0 as 'NUMERIC_PRECISION',"
" case when type like '%real%' or type like '%float%' or type like '%double%' then 255 else 0 end as 'NUMERIC_SCALE',"
" case"
" when type like 'text' or type like 'clob' or type like '%char%' then 'text'"
" when type like '%int%' or type like '%number%' or type like '%numeric%' then 'integer'"
" when type like '%real%' or type like '%float%' or type like '%double%' then 'number'"
" else type"
" end as 'DATA_TYPE',"
" case when \"notnull\" = 0 then 'YES' else 'NO' end as 'IS_NULLABLE'"
" from (select name, lower(type) as type, \"notnull\" from pragma_table_info(:t))";
}
std::string create_column_type(db_type dt,
int , int ) override
{
switch (dt)
{
case db_xml:
case db_string:
return "text";
case db_double:
return "real";
case db_date:
return "integer";
case db_int8:
return "tinyint";
case db_uint8:
return "unsignedtinyint";
case db_int16:
return "smallint";
case db_uint16:
return "unsignedsmallint";
case db_int32:
return "integer";
case db_uint32:
return "unsignedint";
case db_int64:
return "bigint";
case db_uint64:
return "unsignedbigint";
case db_blob:
return "blob";
default:
throw soci_error("this db_type is not supported in create_column");
}
}
sqlite_api::sqlite3 *conn_;
// This flag is set to true if the internal sqlite_sequence table exists in
// the database.
bool sequence_table_exists_;
};
struct sqlite3_backend_factory : backend_factory
{
sqlite3_backend_factory() {}
sqlite3_session_backend * make_session(
connection_parameters const & parameters) const override;
};
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

329
3rdparty/soci/include/soci/statement.h vendored Normal file
View File

@@ -0,0 +1,329 @@
//
// 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"
#include "soci/blob.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<db_type>
void bind_into();
bool alreadyDescribed_;
std::size_t intos_size();
std::size_t uses_size();
void pre_exec(int num);
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)
};
template<>
void statement_impl::into_row<blob>();
} // 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)), gotData_(false) {}
statement(details::prepare_temp_type const & prep)
: impl_(new details::statement_impl(prep)), gotData_(false) {}
~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_;
gotData_ = other.gotData_;
}
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

View File

@@ -0,0 +1,55 @@
//
// 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_STD_OPTIONAL_H_INCLUDED
#define SOCI_STD_OPTIONAL_H_INCLUDED
#include "soci/type-conversion-traits.h"
#include <optional>
namespace soci
{
// simple fall-back for std::optional
template <typename T>
struct type_conversion<std::optional<T> >
{
typedef typename type_conversion<T>::base_type base_type;
static void from_base(base_type const & in, indicator ind,
std::optional<T> & out)
{
if (ind == i_null)
{
out.reset();
}
else
{
T tmp = T();
type_conversion<T>::from_base(in, ind, tmp);
out = tmp;
}
}
static void to_base(std::optional<T> const & in,
base_type & out, indicator & ind)
{
if (in)
{
type_conversion<T>::to_base(*in, out, ind);
}
else
{
ind = i_null;
}
}
};
} // namespace soci
#endif // SOCI_STD_OPTIONAL_H_INCLUDED

View 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

View File

@@ -0,0 +1,149 @@
//
// 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"
#include "soci/is-detected.h"
#include <type_traits>
namespace soci
{
// default traits class type_conversion, acts as pass through for row::get() or row::move_as()
// when no actual conversion is needed.
template <typename T, typename Enable = void>
struct type_conversion
{
typedef T base_type;
struct from_base_check : std::integral_constant<bool, std::is_constructible<T, const base_type>::value> {};
static void from_base(base_type const& in, indicator ind, T & out)
{
static_assert(from_base_check::value,
"from_base can only be used if the target type can be constructed from an lvalue base reference");
assert_non_null(ind);
out = in;
}
struct move_from_base_check :
std::integral_constant<bool,
!std::is_const<base_type>::value
&& std::is_constructible<T, typename std::add_rvalue_reference<base_type>::type>::value
> {};
static void move_from_base(base_type & in, indicator ind, T & out)
{
static_assert(move_from_base_check::value,
"move_to_base can only be used if the target type can be constructed from an rvalue base reference");
assert_non_null(ind);
out = std::move(in);
}
static void to_base(T const & in, base_type & out, indicator & ind)
{
out = in;
ind = i_ok;
}
static void move_to_base(T & in, base_type & out, indicator & ind)
{
out = std::move(in);
ind = i_ok;
}
private:
static void assert_non_null(indicator ind)
{
if (ind == i_null)
{
throw soci_error("Null value not allowed for this type");
}
}
};
namespace details
{
#if !defined(_MSC_VER) || (_MSC_VER >= 1910)
// MSVC 2015 and earlier don't support SFINAE on return types
#define SOCI_HAS_RET_TYPE_SFINAE
#endif
template<typename T>
using from_base_check_t = decltype(T::from_base_check::value);
template<typename T>
using move_from_base_check_t = decltype(T::move_from_base_check::value);
template<typename T>
using supports_from_base_check = is_detected<from_base_check_t, T>;
template<typename T>
using supports_move_from_base_check = is_detected<move_from_base_check_t, T>;
#ifdef SOCI_HAS_RET_TYPE_SFINAE
template<typename Trait>
constexpr auto can_use_from_base()
-> typename std::enable_if<supports_from_base_check<Trait>::value, bool>::type
{
return Trait::from_base_check::value;
}
template<typename Trait>
constexpr auto can_use_from_base()
-> typename std::enable_if<!supports_from_base_check<Trait>::value, bool>::type
{
return true;
}
template<typename Trait>
constexpr auto can_use_move_from_base()
-> typename std::enable_if<supports_move_from_base_check<Trait>::value, bool>::type
{
return Trait::from_base_check::value;
}
template<typename Trait>
constexpr auto can_use_move_from_base()
-> typename std::enable_if<!supports_move_from_base_check<Trait>::value, bool>::type
{
// Default to assuming that the special move_from_base function is not implemented
// TODO: Find clever template magic to add a metaprogramming check for a suitable
// move_from_base implementation
return false;
}
#undef SOCI_HAS_RET_TYPE_SFINAE
#else
// Always return true - if it doesn't work the user will get a cryptic compiler error but at least
// it will compile properly for cases in which things do indeed work
template<typename Trait>
constexpr auto can_use_from_base()
{
return true;
}
template<typename Trait>
constexpr auto can_use_move_from_base()
{
return true;
}
#endif
}
} // namespace soci
#endif // SOCI_TYPE_CONVERSION_TRAITS_H_INCLUDED

View File

@@ -0,0 +1,509 @@
//
// Copyright (C) 2004-2016 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
{
base_value_holder()
: ownInd_(i_ok)
{}
typename type_conversion<T>::base_type val_;
indicator ownInd_;
};
// 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>(base_value_holder<T>::val_, base_value_holder<T>::ownInd_)
, value_(value)
, ind_(base_value_holder<T>::ownInd_)
{
}
conversion_into_type(T & value, indicator & ind)
: into_type<base_type>(base_value_holder<T>::val_, ind)
, value_(value)
, ind_(ind)
{
}
private:
void convert_from_base() override
{
type_conversion<T>::from_base(
base_value_holder<T>::val_, ind_, value_);
}
T & value_;
// 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 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>(base_value_holder<T>::val_, base_value_holder<T>::ownInd_, name)
, value_(value)
, ind_(base_value_holder<T>::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>(base_value_holder<T>::val_, base_value_holder<T>::ownInd_, name)
, value_(const_cast<T &>(value))
, ind_(base_value_holder<T>::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>(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>(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() override
{
// 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(
base_value_holder<T>::val_, ind_, value_);
}
}
void convert_to_base() override
{
if (ind_ == i_null)
{
// A null indicator was explicitly passed to use(val, ind).
// Therefore, NULL should be put into the database, and there is
// normally no reason to convert the value.
//
// However, if ind_ were ownInd_ itself, and if a prepared statement
// were repeatedly executed, we still need to do it in order to
// give the custom conversion a chance to update the indicator
// based on the actual value being used.
if (&ind_ != &(base_value_holder<T>::ownInd_))
{
// We really have nothing to do here, notably do not call the
// custom conversion which could overwrite the explicit i_null
// specified by the caller.
return;
}
}
type_conversion<T>::to_base(value_,
base_value_holder<T>::val_, ind_);
}
private:
T & value_;
// 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_;
const 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 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,
std::size_t begin = 0, std::size_t * end = NULL)
: base_vector_holder<T>(value.size()),
into_type<base_type>(
base_vector_holder<T>::vec_, ownInd_, begin, end),
value_(value),
ownInd_(),
ind_(ownInd_),
begin_(begin),
end_(end)
{
user_ranges_ = end != NULL;
}
conversion_into_type(std::vector<T> & value, std::vector<indicator> & ind,
std::size_t begin = 0, std::size_t * end = NULL)
: base_vector_holder<T>(value.size()),
into_type<base_type>(
base_vector_holder<T>::vec_, ind, begin, end),
value_(value),
ind_(ind),
begin_(begin),
end_(end)
{
user_ranges_ = end != NULL;
}
std::size_t size() const override
{
// 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();
base_vector_holder<T>::vec_.resize(userSize);
return into_type<base_type>::size();
}
void resize(std::size_t sz) override
{
into_type<base_type>::resize(sz);
std::size_t actual_size = base_vector_holder<T>::vec_.size();
value_.resize(actual_size);
ind_.resize(actual_size);
}
private:
void convert_from_base() override
{
if (user_ranges_)
{
for (std::size_t i = begin_; i != *end_; ++i)
{
type_conversion<T>::from_base(
base_vector_holder<T>::vec_[i], ind_[i], value_[i]);
}
}
else
{
std::size_t const sz = base_vector_holder<T>::vec_.size();
for (std::size_t i = 0; i != sz; ++i)
{
type_conversion<T>::from_base(
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_;
std::size_t begin_;
std::size_t * end_;
bool user_ranges_;
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 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(const std::vector<T> & value,
std::string const & name=std::string())
: base_vector_holder<T>(value.size()),
use_type<base_type>(
base_vector_holder<T>::vec_, ownInd_, 0, NULL, name),
value_(value),
ownInd_(),
ind_(ownInd_),
begin_(0),
end_(NULL),
user_ranges_(false)
{
}
conversion_use_type(const std::vector<T> & value,
std::size_t begin, std::size_t * end,
std::string const & name=std::string())
: base_vector_holder<T>(value.size()),
use_type<base_type>(
base_vector_holder<T>::vec_, ownInd_, begin, end, name),
value_(value),
ownInd_(),
ind_(ownInd_),
begin_(begin),
end_(end)
{
user_ranges_ = end != NULL;
}
conversion_use_type(const std::vector<T> & value,
std::vector<indicator> & ind,
std::string const & name = std::string())
: base_vector_holder<T>(value.size()),
use_type<base_type>(
base_vector_holder<T>::vec_, ind, 0, NULL, name),
value_(value),
ind_(ind),
begin_(0),
end_(NULL),
user_ranges_(false)
{
}
conversion_use_type(const std::vector<T> & value,
std::vector<indicator> & ind,
std::size_t begin, std::size_t * end,
std::string const & name = std::string())
: base_vector_holder<T>(value.size()),
use_type<base_type>(
base_vector_holder<T>::vec_, ind, begin, end, name),
value_(value),
ind_(ind),
begin_(begin),
end_(end)
{
user_ranges_ = end != NULL;
}
private:
void convert_to_base() override
{
std::size_t const sz = value_.size();
base_vector_holder<T>::vec_.resize(sz);
ind_.resize(sz);
if (user_ranges_)
{
for (std::size_t i = begin_; i != *end_; ++i)
{
type_conversion<T>::to_base(value_[i],
base_vector_holder<T>::vec_[i], ind_[i]);
}
}
else
{
for (std::size_t i = 0; i != sz; ++i)
{
type_conversion<T>::to_base(value_[i],
base_vector_holder<T>::vec_[i], ind_[i]);
}
}
}
const 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_;
std::size_t begin_;
std::size_t * end_;
bool user_ranges_;
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>
into_type_ptr do_into(std::vector<T> & t,
std::size_t begin, size_t * end, user_type_tag)
{
return into_type_ptr(
new conversion_into_type<std::vector<T> >(t, begin, end));
}
template <typename T>
into_type_ptr do_into(std::vector<T> & t, std::vector<indicator> & ind,
user_type_tag)
{
return into_type_ptr(new conversion_into_type<std::vector<T> >(t, ind));
}
template <typename T>
into_type_ptr do_into(std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, size_t * end, user_type_tag)
{
return into_type_ptr(
new conversion_into_type<std::vector<T> >(t, ind, begin, end));
}
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));
}
template <typename T>
use_type_ptr do_use(std::vector<T> & t,
std::size_t begin, size_t * end,
std::string const & name, user_type_tag)
{
return use_type_ptr(
new conversion_use_type<std::vector<T> >(t, begin, end, name));
}
template <typename T>
use_type_ptr do_use(const std::vector<T> & t,
std::size_t begin, size_t * end,
std::string const & name, user_type_tag)
{
return use_type_ptr(
new conversion_use_type<std::vector<T> >(t, begin, end, name));
}
template <typename T>
use_type_ptr do_use(std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, size_t * end,
std::string const & name, user_type_tag)
{
return use_type_ptr(
new conversion_use_type<std::vector<T> >(t, ind, begin, end, name));
}
template <typename T>
use_type_ptr do_use(const std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, size_t * end,
std::string const & name, user_type_tag)
{
return use_type_ptr(
new conversion_use_type<std::vector<T> >(t, ind, begin, end, name));
}
} // namespace details
} // namespace soci
#endif // SOCI_TYPE_CONVERSION_H_INCLUDED

449
3rdparty/soci/include/soci/type-holder.h vendored Normal file
View File

@@ -0,0 +1,449 @@
//
// 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
#include "soci/blob.h"
#include "soci/error.h"
#include "soci/soci-backend.h"
#include "soci/soci-types.h"
#include <cstdint>
#include <ctime>
#include <limits>
#include <sstream>
#include <type_traits>
#include <typeinfo>
namespace soci
{
namespace details
{
// Returns U* as T*, if the dynamic type of the pointer is really T.
//
// This should be used instead of dynamic_cast<> because using it doesn't work
// when using libc++ and ELF visibility together. Luckily, when we don't need
// the full power of the cast, but only need to check if the types are the
// same, it can be done by comparing their type info objects.
//
// This function does _not_ replace dynamic_cast<> in all cases and notably
// doesn't allow the input pointer to be null.
template <typename T, typename U>
T* checked_ptr_cast(U* ptr)
{
// Check if they're identical first, as an optimization, and then compare
// their names to make it actually work with libc++.
std::type_info const& ti_ptr = typeid(*ptr);
std::type_info const& ti_ret = typeid(T);
if (&ti_ptr != &ti_ret && std::strcmp(ti_ptr.name(), ti_ret.name()) != 0)
{
return NULL;
}
return static_cast<T*>(ptr);
}
template <typename T, typename U, typename Enable = void>
struct soci_return_same
{
static inline T& value(U&)
{
throw std::bad_cast();
}
};
template <typename T, typename U>
struct soci_return_same<
T, U,
typename std::enable_if<std::is_same<T, U>::value>::type>
{
static inline T& value(U& val)
{
return val;
}
};
// Type safe conversion that throws if the types are mismatched
template <typename T, typename U, typename Enable = void>
struct soci_cast
{
static inline T cast(U)
{
throw std::bad_cast();
}
};
// Type safe conversion that is a noop
template <typename T, typename U>
struct soci_cast<
T, U,
typename std::enable_if<std::is_same<T, U>::value>::type>
{
static inline T cast(U val)
{
return val;
}
};
// Type safe conversion that is widening the type
template <typename T, typename U>
struct soci_cast<
T, U,
typename std::enable_if<(
!std::is_same<T, U>::value &&
std::is_integral<T>::value &&
std::is_integral<U>::value
)>::type>
{
static inline T cast(U val) {
intmax_t t_min = static_cast<intmax_t>((std::numeric_limits<T>::min)());
intmax_t u_min = static_cast<intmax_t>((std::numeric_limits<U>::min)());
uintmax_t t_max = static_cast<uintmax_t>((std::numeric_limits<T>::max)());
uintmax_t u_max = static_cast<uintmax_t>((std::numeric_limits<U>::max)());
#ifdef _MSC_VER
// As long as we don't require C++17, we must disable the warning
// "conditional expression is constant" as it can give false positives here.
#pragma warning(push)
#pragma warning(disable:4127)
#endif
if ((t_min > u_min && val < static_cast<U>(t_min)) ||
(t_max < u_max && val > static_cast<U>(t_max)))
{
throw std::bad_cast();
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif
return static_cast<T>(val);
}
};
union type_holder
{
std::string* s;
int8_t* i8;
int16_t* i16;
int32_t* i32;
int64_t* i64;
uint8_t* u8;
uint16_t* u16;
uint32_t* u32;
uint64_t* u64;
double* d;
std::tm* t;
blob* b;
};
template <typename T>
struct type_holder_trait;
template <>
struct type_holder_trait<std::string>
{
static const db_type type = db_string;
};
template <>
struct type_holder_trait<int8_t>
{
static const db_type type = db_int8;
};
template <>
struct type_holder_trait<int16_t>
{
static const db_type type = db_int16;
};
template <>
struct type_holder_trait<int32_t>
{
static const db_type type = db_int32;
};
template <>
struct type_holder_trait<int64_t>
{
static const db_type type = db_int64;
};
template <>
struct type_holder_trait<uint8_t>
{
static const db_type type = db_uint8;
};
template <>
struct type_holder_trait<uint16_t>
{
static const db_type type = db_uint16;
};
template <>
struct type_holder_trait<uint32_t>
{
static const db_type type = db_uint32;
};
template <>
struct type_holder_trait<uint64_t>
{
static const db_type type = db_uint64;
};
#if defined(SOCI_INT64_IS_LONG)
template <>
struct type_holder_trait<long long> : type_holder_trait<int64_t>
{
};
template <>
struct type_holder_trait<unsigned long long> : type_holder_trait<uint64_t>
{
};
#elif defined(SOCI_LONG_IS_64_BIT)
template <>
struct type_holder_trait<long> : type_holder_trait<int64_t>
{
};
template <>
struct type_holder_trait<unsigned long> : type_holder_trait<uint64_t>
{
};
#else
template <>
struct type_holder_trait<long> : type_holder_trait<int32_t>
{
};
template <>
struct type_holder_trait<unsigned long> : type_holder_trait<uint32_t>
{
};
#endif
template <>
struct type_holder_trait<double>
{
static const db_type type = db_double;
};
template <>
struct type_holder_trait<std::tm>
{
static const db_type type = db_date;
};
template <>
struct type_holder_trait<blob>
{
static const db_type type = db_blob;
};
struct value_cast_tag{};
struct value_reference_tag{};
// Class for storing type data instances in a container of holder objects
class holder
{
public:
template <typename T>
static holder* make_holder(T* val)
{
return new holder(type_holder_trait<T>::type, val);
}
~holder()
{
switch (dt_)
{
case db_double:
delete val_.d;
break;
case db_int8:
delete val_.i8;
break;
case db_int16:
delete val_.i16;
break;
case db_int32:
delete val_.i32;
break;
case db_int64:
delete val_.i64;
break;
case db_uint8:
delete val_.u8;
break;
case db_uint16:
delete val_.u16;
break;
case db_uint32:
delete val_.u32;
break;
case db_uint64:
delete val_.u64;
break;
case db_date:
delete val_.t;
break;
case db_blob:
delete val_.b;
break;
case db_xml:
case db_string:
delete val_.s;
break;
}
}
#ifdef _MSC_VER
// MSVC complains about "unreachable code" even though all
// code here can be reached.
#pragma warning(push)
#pragma warning(disable:4702)
#endif
template <typename T>
T get(value_cast_tag)
{
switch (dt_)
{
case db_int8:
return soci_cast<T, int8_t>::cast(*val_.i8);
case db_int16:
return soci_cast<T, int16_t>::cast(*val_.i16);
case db_int32:
return soci_cast<T, int32_t>::cast(*val_.i32);
case db_int64:
return soci_cast<T, int64_t>::cast(*val_.i64);
case db_uint8:
return soci_cast<T, uint8_t>::cast(*val_.u8);
case db_uint16:
return soci_cast<T, uint16_t>::cast(*val_.u16);
case db_uint32:
return soci_cast<T, uint32_t>::cast(*val_.u32);
case db_uint64:
return soci_cast<T, uint64_t>::cast(*val_.u64);
case db_double:
return soci_cast<T, double>::cast(*val_.d);
case db_date:
return soci_cast<T, std::tm>::cast(*val_.t);
case db_blob:
// blob is not copyable
break;
case db_xml:
case db_string:
return soci_cast<T, std::string>::cast(*val_.s);
}
throw std::bad_cast();
}
template <typename T>
T& get(value_reference_tag)
{
switch (dt_)
{
case db_int8:
return soci_return_same<T, int8_t>::value(*val_.i8);
case db_int16:
return soci_return_same<T, int16_t>::value(*val_.i16);
case db_int32:
return soci_return_same<T, int32_t>::value(*val_.i32);
case db_int64:
return soci_return_same<T, int64_t>::value(*val_.i64);
case db_uint8:
return soci_return_same<T, uint8_t>::value(*val_.u8);
case db_uint16:
return soci_return_same<T, uint16_t>::value(*val_.u16);
case db_uint32:
return soci_return_same<T, uint32_t>::value(*val_.u32);
case db_uint64:
return soci_return_same<T, uint64_t>::value(*val_.u64);
case db_double:
return soci_return_same<T, double>::value(*val_.d);
case db_date:
return soci_return_same<T, std::tm>::value(*val_.t);
case db_blob:
return soci_return_same<T, blob>::value(*val_.b);
case db_xml:
case db_string:
return soci_return_same<T, std::string>::value(*val_.s);
}
throw std::bad_cast();
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif
private:
holder(db_type dt, void* val) : dt_(dt)
{
switch (dt_)
{
case db_double:
val_.d = static_cast<double*>(val);
return;
case db_int8:
val_.i8 = static_cast<int8_t*>(val);
return;
case db_int16:
val_.i16 = static_cast<int16_t*>(val);
return;
case db_int32:
val_.i32 = static_cast<int32_t*>(val);
return;
case db_int64:
val_.i64 = static_cast<int64_t*>(val);
return;
case db_uint8:
val_.u8 = static_cast<uint8_t*>(val);
return;
case db_uint16:
val_.u16 = static_cast<uint16_t*>(val);
return;
case db_uint32:
val_.u32 = static_cast<uint32_t*>(val);
return;
case db_uint64:
val_.u64 = static_cast<uint64_t*>(val);
return;
case db_date:
val_.t = static_cast<std::tm*>(val);
return;
case db_blob:
val_.b = static_cast<blob*>(val);
return;
case db_xml:
case db_string:
val_.s = static_cast<std::string*>(val);
return;
}
// This should be unreachable
std::ostringstream ss;
ss << "Created holder with unsupported type " << std::to_string(dt);
throw soci_error(ss.str());
}
const db_type dt_;
type_holder val_;
};
} // namespace details
} // namespace soci
#endif // SOCI_TYPE_HOLDER_H_INCLUDED

30
3rdparty/soci/include/soci/type-ptr.h vendored Normal file
View 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

View File

@@ -0,0 +1,33 @@
//
// Copyright (C) 2016 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_TYPE_WRAPPERS_H_INCLUDED
#define SOCI_TYPE_WRAPPERS_H_INCLUDED
namespace soci
{
// These wrapper types can be used by the application
// with 'into' and 'use' elements in order to guide the library
// in selecting specialized methods for binding and transferring data;
// if the target database does not provide any such specialized methods,
// it is expected to handle these wrappers as equivalent
// to their contained field types.
struct xml_type
{
std::string value;
};
struct long_string
{
std::string value;
};
} // namespace soci
#endif // SOCI_TYPE_WRAPPERS_H_INCLUDED

340
3rdparty/soci/include/soci/use-type.h vendored Normal file
View File

@@ -0,0 +1,340 @@
//
// Copyright (C) 2004-2016 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_exec(int num) = 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();
}
~standard_use_type() override;
void bind(statement_impl & st, int & position) override;
std::string get_name() const override { return name_; }
void dump_value(std::ostream& os) const override;
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:
void pre_use() override;
private:
void pre_exec(int num) override;
void post_use(bool gotData) override;
void clean_up() override;
std::size_t size() const override { 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)
, begin_(0)
, end_(NULL)
, name_(name)
, backEnd_(NULL)
{}
vector_use_type(void* data, exchange_type type,
std::size_t begin, std::size_t * end,
std::string const& name = std::string())
: data_(data)
, type_(type)
, ind_(NULL)
, begin_(begin)
, end_(end)
, 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)
, begin_(0)
, end_(NULL)
, name_(name)
, backEnd_(NULL)
{}
vector_use_type(void* data, exchange_type type,
std::vector<indicator> const& ind,
std::size_t begin, std::size_t * end,
std::string const& name = std::string())
: data_(data)
, type_(type)
, ind_(&ind)
, begin_(begin)
, end_(end)
, name_(name)
, backEnd_(NULL)
{}
~vector_use_type() override;
private:
void bind(statement_impl& st, int & position) override;
std::string get_name() const override { return name_; }
void dump_value(std::ostream& os) const override;
void pre_exec(int num) override;
void pre_use() override;
void post_use(bool) override { /* nothing to do */ }
void clean_up() override;
std::size_t size() const override;
void* data_;
exchange_type type_;
std::vector<indicator> const* ind_;
std::size_t begin_;
std::size_t * end_;
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, true, 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>& v, std::size_t begin, std::size_t * end,
std::string const& name = std::string())
: vector_use_type(&v,
static_cast<exchange_type>(exchange_traits<T>::x_type), begin, end, 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> const& v, std::size_t begin, std::size_t * end,
std::string const& name = std::string())
: vector_use_type(const_cast<std::vector<T>*>(&v),
static_cast<exchange_type>(exchange_traits<T>::x_type), begin, end, 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>& v, std::vector<indicator> const& ind,
std::size_t begin, std::size_t * end, std::string const& name = std::string())
: vector_use_type(&v,
static_cast<exchange_type>(exchange_traits<T>::x_type), ind, begin, end, 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)
{}
use_type(std::vector<T> const& v, std::vector<indicator> const& ind,
std::size_t begin, std::size_t * end, 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, begin, end, 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));
}
template <typename T>
use_type_ptr do_use(std::vector<T> & t,
std::size_t begin, std::size_t * end,
std::string const & name, basic_type_tag)
{
return use_type_ptr(
new use_type<std::vector<T> >(t, begin, end, name));
}
template <typename T>
use_type_ptr do_use(const std::vector<T> & t,
std::size_t begin, std::size_t * end,
std::string const & name, basic_type_tag)
{
return use_type_ptr(
new use_type<std::vector<T> >(t, begin, end, name));
}
template <typename T>
use_type_ptr do_use(std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, std::size_t * end,
std::string const & name, basic_type_tag)
{
return use_type_ptr(
new use_type<std::vector<T> >(t, ind, begin, end, name));
}
template <typename T>
use_type_ptr do_use(const std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, std::size_t * end,
std::string const & name, basic_type_tag)
{
return use_type_ptr(
new use_type<std::vector<T> >(t, ind, begin, end, name));
}
} // namespace details
} // namesapce soci
#endif // SOCI_USE_TYPE_H_INCLUDED

123
3rdparty/soci/include/soci/use.h vendored Normal file
View File

@@ -0,0 +1,123 @@
//
// Copyright (C) 2004-2016 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
// soci::use is deleted for rvalues because it will likely lead to subtle stack-use-after-scope bugs.
template <typename T>
details::use_container<T, details::no_indicator> use(T &&t, const std::string &name = std::string()) = delete;
template <typename T>
details::use_container<const T, indicator> use(T &&t, indicator & ind, std::string const &name = std::string()) = delete;
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); }
// vectors with index ranges
template <typename T>
details::use_type_ptr use(std::vector<T> & t,
std::size_t begin, std::size_t & end,
const std::string &name = std::string())
{
return details::do_use(t, begin, &end, name,
typename details::exchange_traits<std::vector<T> >::type_family());
}
template <typename T>
details::use_type_ptr use(const std::vector<T> & t,
std::size_t begin, std::size_t & end,
const std::string &name = std::string())
{
return details::do_use(t, begin, &end, name,
typename details::exchange_traits<std::vector<T> >::type_family());
}
template <typename T>
details::use_type_ptr use(std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, std::size_t & end,
const std::string &name = std::string())
{
return details::do_use(t, ind, begin, &end, name,
typename details::exchange_traits<std::vector<T> >::type_family());
}
template <typename T>
details::use_type_ptr use(const std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, std::size_t & end,
const std::string &name = std::string())
{
return details::do_use(t, ind, begin, &end, name,
typename details::exchange_traits<std::vector<T> >::type_family());
}
} // namespace soci
#endif // SOCI_USE_H_INCLUDED

View File

@@ -0,0 +1,150 @@
//
// 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)
{}
void bind(details::statement_impl & st, int & /*position*/) override
{
v_.uppercase_column_names(st.session_.get_uppercase_column_names());
convert_to_base();
st.bind(v_);
}
std::string get_name() const override
{
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();
}
void dump_value(std::ostream& os) const override
{
// TODO: Dump all columns.
os << "<value>";
}
void pre_exec(int /* num */) override {}
void post_use(bool /*gotData*/) override
{
v_.reset_get_counter();
convert_from_base();
}
void pre_use() override {convert_to_base();}
void clean_up() override {v_.clean_up();}
std::size_t size() const override { 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() override
{
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

351
3rdparty/soci/include/soci/values.h vendored Normal file
View File

@@ -0,0 +1,351 @@
//
// 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{};
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 (details::checked_ptr_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
3rdparty/soci/include/soci/version.h vendored Normal file
View 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 400100
//
// 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_1_0"
#endif // SOCI_VERSION_HPP

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -13,7 +13,7 @@ namespace ylib
void close();
std::string read(const std::string& name,const std::string& key,const std::string& default_value = "") const;
bool write(const std::string& name,const std::string& key,const std::string& value);
#ifndef _WIN32
#ifndef _WIN321
bool del(const std::string& name, const std::string& key);
// 一级NAME

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -17,7 +17,7 @@ auto_update_sec=3
[website]
; 网站静态文件目录
static_dir=${base}/root
static_dir=${base}/www
; 默认页面-404
default_404=page/404.html
; 默认首页(index.html,index.htm,index.lua)
@@ -30,7 +30,8 @@ session_timeout_sec=86400
Initialization_script=${base}/scripts/init.lua
; 拦截器
interceptor_scripts= [["${base}/scripts/interceptor.lua","/scripts/*.*"]]
; 调试模式,开启后控制台输出异常错误信息 (0=关闭 1=开启)
debug=1
[server]
; TCP服务监听地址
address=0.0.0.0

View File

@@ -25,12 +25,17 @@
<ClCompile Include="src\core\global.cpp" />
<ClCompile Include="src\core\main.cpp" />
<ClCompile Include="src\core\statemanager.cpp" />
<ClCompile Include="src\module\codec.cpp" />
<ClCompile Include="src\module\globalfuns.cpp" />
<ClCompile Include="src\module\http\httpclient.cpp" />
<ClCompile Include="src\module\http\request.cpp" />
<ClCompile Include="src\module\http\response.cpp" />
<ClCompile Include="src\module\http\session.cpp" />
<ClCompile Include="src\module\localstorage.cpp" />
<ClCompile Include="src\module\mssql.cpp" />
<ClCompile Include="src\module\mutex.cpp" />
<ClCompile Include="src\module\mysql.cpp" />
<ClCompile Include="src\module\time.cpp" />
<ClCompile Include="src\utils\logutils.cpp" />
<ClCompile Include="src\utils\luautils.cpp" />
</ItemGroup>
@@ -42,13 +47,18 @@
<ClInclude Include="src\core\global.h" />
<ClInclude Include="src\core\statemanager.h" />
<ClInclude Include="src\core\structs.h" />
<ClInclude Include="src\module\codec.h" />
<ClInclude Include="src\module\globalfuns.h" />
<ClInclude Include="src\module\http\httpclient.h" />
<ClInclude Include="src\module\http\request.h" />
<ClInclude Include="src\module\http\response.h" />
<ClInclude Include="src\module\http\session.h" />
<ClInclude Include="src\module\imodule.h" />
<ClInclude Include="src\module\localstorage.h" />
<ClInclude Include="src\module\mssql.h" />
<ClInclude Include="src\module\mutex.h" />
<ClInclude Include="src\module\mysql.h" />
<ClInclude Include="src\module\time.h" />
<ClInclude Include="src\utils\logutils.h" />
<ClInclude Include="src\utils\luautils.h" />
</ItemGroup>
@@ -56,11 +66,6 @@
<None Include=".gitignore" />
<None Include="config.ini" />
<None Include="README.md" />
<None Include="scripts\app\index.lua" />
<None Include="scripts\init.lua" />
<None Include="scripts\interceptor.lua" />
<None Include="scripts\lib\dkjson.lua" />
<None Include="scripts\lib\website.lua" />
</ItemGroup>
<ItemGroup>
<Text Include="LICENSE.txt" />
@@ -156,18 +161,18 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty;$(SolutionDir)3rdparty\lua;$(SolutionDir)3rdparty\ylib\include;$(SolutionDir)3rdparty\HP-Socket\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\soci\include;$(SolutionDir)src;$(SolutionDir)3rdparty;$(SolutionDir)3rdparty\lua;D:\lib\ylib\include;$(SolutionDir)3rdparty\HP-Socket\include</AdditionalIncludeDirectories>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>User32.lib;Advapi32.lib;IPHLPAPI.lib;WS2_32.lib;Shell32.lib;leveldb.lib;libzip.lib;lua.lib;sqlite3.lib;ylib.lib;zlib.lib;mysqlcppconn.lib;HPSocket_D.lib;libcrypto_static.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)3rdparty\ylib\lib\$(Configuration);$(SolutionDir)3rdparty\mysql\lib\$(Configuration);$(SolutionDir)3rdparty\HP-Socket\lib;$(SolutionDir)3rdparty</AdditionalLibraryDirectories>
<AdditionalDependencies>libsoci_core_4_1.lib;libsoci_empty_4_1.lib;libsoci_odbc_4_1.lib;soci_core_4_1.lib;soci_empty_4_1.lib;soci_odbc_4_1.lib;odbc32.lib;User32.lib;Advapi32.lib;IPHLPAPI.lib;WS2_32.lib;Shell32.lib;leveldb.lib;libzip.lib;lua.lib;sqlite3.lib;D:\lib\ylib_vs_build\lib\Debug\ylib.lib;zlib.lib;mysqlcppconn.lib;HPSocket_D.lib;libcrypto_static.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)3rdparty\ylib\lib\$(Configuration);$(SolutionDir)3rdparty\mysql\lib\$(Configuration);$(SolutionDir)3rdparty\HP-Socket\lib;$(SolutionDir)3rdparty;$(SolutionDir)3rdparty\soci\lib\$(Configuration)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -175,10 +180,10 @@
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty;$(SolutionDir)3rdparty\lua;$(SolutionDir)3rdparty\ylib\include;$(SolutionDir)3rdparty\HP-Socket\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\soci\include;$(SolutionDir)src;$(SolutionDir)3rdparty;$(SolutionDir)3rdparty\lua;D:\lib\ylib\include;$(SolutionDir)3rdparty\HP-Socket\include</AdditionalIncludeDirectories>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
@@ -187,8 +192,8 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>User32.lib;Advapi32.lib;IPHLPAPI.lib;WS2_32.lib;Shell32.lib;leveldb.lib;libzip.lib;lua.lib;sqlite3.lib;ylib.lib;zlib.lib;mysqlcppconn.lib;HPSocket.lib;libcrypto_static.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)3rdparty\ylib\lib\$(Configuration);$(SolutionDir)3rdparty\mysql\lib\$(Configuration);$(SolutionDir)3rdparty\HP-Socket\lib;$(SolutionDir)3rdparty</AdditionalLibraryDirectories>
<AdditionalDependencies>libsoci_core_4_1.lib;libsoci_empty_4_1.lib;libsoci_odbc_4_1.lib;soci_core_4_1.lib;soci_empty_4_1.lib;soci_odbc_4_1.lib;odbc32.lib;User32.lib;Advapi32.lib;IPHLPAPI.lib;WS2_32.lib;Shell32.lib;leveldb.lib;libzip.lib;lua.lib;sqlite3.lib;ylib.lib;zlib.lib;mysqlcppconn.lib;HPSocket.lib;libcrypto_static.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)3rdparty\ylib\lib\$(Configuration);$(SolutionDir)3rdparty\mysql\lib\$(Configuration);$(SolutionDir)3rdparty\HP-Socket\lib;$(SolutionDir)3rdparty;$(SolutionDir)3rdparty\soci\lib\$(Configuration)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@@ -10,15 +10,6 @@
<Filter Include="src\module">
<UniqueIdentifier>{feb78a4c-cec1-4b7c-850b-6d1451e57962}</UniqueIdentifier>
</Filter>
<Filter Include="scripts">
<UniqueIdentifier>{6f9c72e6-2a8a-4407-a277-1c83c92fd6b9}</UniqueIdentifier>
</Filter>
<Filter Include="scripts\app">
<UniqueIdentifier>{cfc62d45-db7b-4cb5-9d11-8caf2977dfb2}</UniqueIdentifier>
</Filter>
<Filter Include="scripts\lib">
<UniqueIdentifier>{573b85d6-db05-4a81-af04-172fe83306e5}</UniqueIdentifier>
</Filter>
<Filter Include="src\utils">
<UniqueIdentifier>{2b04f1f8-4027-4d87-a828-f18f2b918b8f}</UniqueIdentifier>
</Filter>
@@ -69,6 +60,21 @@
<ClCompile Include="src\module\globalfuns.cpp">
<Filter>src\module</Filter>
</ClCompile>
<ClCompile Include="src\module\mutex.cpp">
<Filter>src\module</Filter>
</ClCompile>
<ClCompile Include="src\module\codec.cpp">
<Filter>src\module</Filter>
</ClCompile>
<ClCompile Include="src\module\mssql.cpp">
<Filter>src\module</Filter>
</ClCompile>
<ClCompile Include="src\module\time.cpp">
<Filter>src\module</Filter>
</ClCompile>
<ClCompile Include="src\module\http\httpclient.cpp">
<Filter>src\module\http</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\core\fastweb.h">
@@ -119,24 +125,24 @@
<ClInclude Include="src\module\globalfuns.h">
<Filter>src\module</Filter>
</ClInclude>
<ClInclude Include="src\module\mutex.h">
<Filter>src\module</Filter>
</ClInclude>
<ClInclude Include="src\module\codec.h">
<Filter>src\module</Filter>
</ClInclude>
<ClInclude Include="src\module\mssql.h">
<Filter>src\module</Filter>
</ClInclude>
<ClInclude Include="src\module\time.h">
<Filter>src\module</Filter>
</ClInclude>
<ClInclude Include="src\module\http\httpclient.h">
<Filter>src\module\http</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="config.ini" />
<None Include="scripts\app\index.lua">
<Filter>scripts\app</Filter>
</None>
<None Include="scripts\lib\dkjson.lua">
<Filter>scripts\lib</Filter>
</None>
<None Include="scripts\lib\website.lua">
<Filter>scripts\lib</Filter>
</None>
<None Include="scripts\init.lua">
<Filter>scripts</Filter>
</None>
<None Include="scripts\interceptor.lua">
<Filter>scripts</Filter>
</None>
<None Include="README.md" />
<None Include=".gitignore" />
</ItemGroup>

Some files were not shown because too many files have changed in this diff Show More