Update POCO library.

This commit is contained in:
Sandu Liviu Catalin committed 2023-03-23 20:19:11 +02:00
1 parent 8d15f4b6e9
commit 233fc103f9
2521 files changed
+257092 -72789

No files matched your search

+1 -2
View File
@@ -213,8 +213,7 @@ void Binder::bind(std::size_t pos, const Time& val, Direction dir)
void Binder::bind(std::size_t pos, const UUID& val, Direction dir)
{
std::string str = val.toString();
bind(pos, str, dir);
bind(pos, toString(val), dir);
}
+5 -1
View File
@@ -16,7 +16,11 @@
#include "Poco/Data/MySQL/SessionImpl.h"
#include "Poco/Data/SessionFactory.h"
#include "Poco/Exception.h"
#include <mysql/mysql.h>
#if defined(__MINGW32__) || defined(__MINGW64__)
#include <mysql/mysql.h>
#else
#include <mysql.h>
#endif
namespace Poco {
+50 -1
View File
@@ -128,8 +128,18 @@ bool Extractor::extract(std::size_t pos, std::string& val)
//mysql reports TEXT types as FDT_BLOB when being extracted
MetaColumn::ColumnDataType columnType = _metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type();
#ifdef POCO_MYSQL_JSON
if (columnType != Poco::Data::MetaColumn::FDT_STRING && columnType != Poco::Data::MetaColumn::FDT_BLOB && columnType != Poco::Data::MetaColumn::FDT_JSON)
#else
if (columnType != Poco::Data::MetaColumn::FDT_STRING && columnType != Poco::Data::MetaColumn::FDT_BLOB)
#endif
throw MySQLException("Extractor: not a string");
#ifdef POCO_MYSQL_JSON
if (columnType == Poco::Data::MetaColumn::FDT_JSON && !extractJSON(pos))
return false;
#endif
if (columnType == Poco::Data::MetaColumn::FDT_BLOB && !extractLongLOB(pos))
return false;
val.assign(reinterpret_cast<const char*>(_metadata.rawData(pos)), _metadata.length(pos));
return true;
@@ -142,11 +152,14 @@ bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val)
throw MySQLException("Extractor: attempt to extract more parameters, than query result contain");
if (_metadata.isNull(static_cast<Poco::UInt32>(pos)))
return false;
return false;
if (_metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type() != Poco::Data::MetaColumn::FDT_BLOB)
throw MySQLException("Extractor: not a blob");
if (_metadata.metaColumn(static_cast<Poco::UInt32>(pos)).length() == 0 && !extractLongLOB(pos))
return false;
val.assignRaw(_metadata.rawData(pos), _metadata.length(pos));
return true;
}
@@ -163,6 +176,9 @@ bool Extractor::extract(std::size_t pos, Poco::Data::CLOB& val)
if (_metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type() != Poco::Data::MetaColumn::FDT_BLOB)
throw MySQLException("Extractor: not a blob");
if (_metadata.metaColumn(static_cast<Poco::UInt32>(pos)).length() == 0 && !extractLongLOB(pos))
return false;
val.assignRaw(reinterpret_cast<const char*>(_metadata.rawData(pos)), _metadata.length(pos));
return true;
}
@@ -263,6 +279,39 @@ bool Extractor::realExtractFixed(std::size_t pos, enum_field_types type, void* b
return isNull == 0;
}
bool Extractor::extractLongLOB(std::size_t pos)
{
// Large LOBs (LONGBLOB and LONGTEXT) are fetched
// with a zero-length buffer to avoid allocating
// huge amounts of memory. Therefore, when extracting
// the buffers need to be adjusted.
_metadata.adjustColumnSizeToFit(pos);
MYSQL_BIND* row = _metadata.row();
if (!_stmt.fetchColumn(pos, &row[pos]))
return false;
return true;
}
#ifdef POCO_MYSQL_JSON
bool Extractor::extractJSON(std::size_t pos)
{
// JSON columns are fetched with a zero-length
// buffer to avoid allocating huge amounts of memory.
// Therefore, when extracting the buffers need to be adjusted.
_metadata.adjustColumnSizeToFit(pos);
MYSQL_BIND* row = _metadata.row();
row->buffer_type = MYSQL_TYPE_JSON;
if (!_stmt.fetchColumn(pos, &row[pos]))
return false;
return true;
}
#endif
//////////////
// Not implemented
+3 -8
View File
@@ -18,8 +18,7 @@
#include "Poco/Data/MySQL/MySQLException.h"
#include <mysql/mysql.h>
#include <stdio.h>
#include "Poco/NumberFormatter.h"
namespace Poco {
@@ -71,9 +70,7 @@ std::string ConnectionException::compose(const std::string& text, MYSQL* h)
str += mysql_error(h);
str += "\t[mysql_errno]: ";
char buff[30];
sprintf(buff, "%d", mysql_errno(h));
str += buff;
Poco::NumberFormatter::append(str, mysql_errno(h));
str += "\t[mysql_sqlstate]: ";
str += mysql_sqlstate(h);
@@ -125,9 +122,7 @@ std::string StatementException::compose(const std::string& text, MYSQL_STMT* h,
str += mysql_stmt_error(h);
str += "\t[mysql_stmt_errno]: ";
char buff[30];
sprintf(buff, "%d", mysql_stmt_errno(h));
str += buff;
Poco::NumberFormatter::append(str, mysql_stmt_errno(h));
str += "\t[mysql_stmt_sqlstate]: ";
str += mysql_stmt_sqlstate(h);
+53 -24
View File
@@ -61,6 +61,7 @@ namespace
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_TIME:
case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_TIMESTAMP:
return sizeof(MYSQL_TIME);
case MYSQL_TYPE_DECIMAL:
@@ -71,21 +72,24 @@ namespace
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
#ifdef POCO_MYSQL_JSON
case MYSQL_TYPE_JSON:
#endif
return field.length;
default:
throw Poco::Data::MySQL::StatementException("unknown field type");
}
}
}
Poco::Data::MetaColumn::ColumnDataType fieldType(const MYSQL_FIELD& field)
/// Convert field MySQL-type to Poco-type
/// Convert field MySQL-type to Poco-type
{
bool unsig = ((field.flags & UNSIGNED_FLAG) == UNSIGNED_FLAG);
switch (field.type)
{
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_TINY:
if (unsig) return Poco::Data::MetaColumn::FDT_UINT8;
return Poco::Data::MetaColumn::FDT_INT8;
@@ -94,31 +98,32 @@ namespace
return Poco::Data::MetaColumn::FDT_INT16;
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_LONG:
if (unsig) return Poco::Data::MetaColumn::FDT_UINT32;
return Poco::Data::MetaColumn::FDT_INT32;
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_FLOAT:
return Poco::Data::MetaColumn::FDT_FLOAT;
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_DOUBLE:
return Poco::Data::MetaColumn::FDT_DOUBLE;
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_LONGLONG:
if (unsig) return Poco::Data::MetaColumn::FDT_UINT64;
return Poco::Data::MetaColumn::FDT_INT64;
case MYSQL_TYPE_DATE:
return Poco::Data::MetaColumn::FDT_DATE;
case MYSQL_TYPE_TIME:
return Poco::Data::MetaColumn::FDT_TIME;
case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_TIMESTAMP:
return Poco::Data::MetaColumn::FDT_TIMESTAMP;
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VAR_STRING:
return Poco::Data::MetaColumn::FDT_STRING;
@@ -128,6 +133,10 @@ namespace
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
return Poco::Data::MetaColumn::FDT_BLOB;
#ifdef POCO_MYSQL_JSON
case MYSQL_TYPE_JSON:
return Poco::Data::MetaColumn::FDT_JSON;
#endif
default:
return Poco::Data::MetaColumn::FDT_UNKNOWN;
}
@@ -140,8 +149,15 @@ namespace Data {
namespace MySQL {
ResultMetadata::~ResultMetadata()
{
freeMemory();
}
void ResultMetadata::reset()
{
freeMemory();
_columns.resize(0);
_row.resize(0);
_buffer.resize(0);
@@ -150,14 +166,20 @@ void ResultMetadata::reset()
}
void ResultMetadata::freeMemory()
{
for (std::vector<char*>::iterator it = _buffer.begin(); it != _buffer.end(); ++it)
std::free(*it);
}
void ResultMetadata::init(MYSQL_STMT* stmt)
{
ResultMetadataHandle h(stmt);
if (!h)
{
// all right, it is normal
// querys such an "INSERT INTO" just does not have result at all
// some queries (eg. INSERT) don't have result
reset();
return;
}
@@ -165,7 +187,6 @@ void ResultMetadata::init(MYSQL_STMT* stmt)
std::size_t count = mysql_num_fields(h);
MYSQL_FIELD* fields = mysql_fetch_fields(h);
std::size_t commonSize = 0;
_columns.reserve(count);
for (std::size_t i = 0; i < count; i++)
@@ -181,29 +202,24 @@ void ResultMetadata::init(MYSQL_STMT* stmt)
0, // TODO: precision
!IS_NOT_NULL(fields[i].flags) // nullable
));
commonSize += _columns[i].length();
}
_buffer.resize(commonSize);
_buffer.resize(count);
_row.resize(count);
_lengths.resize(count);
_isNull.resize(count);
std::size_t offset = 0;
for (std::size_t i = 0; i < count; i++)
{
std::memset(&_row[i], 0, sizeof(MYSQL_BIND));
unsigned int len = static_cast<unsigned int>(_columns[i].length());
_buffer[i] = (char*) std::calloc(len, sizeof(char));
_row[i].buffer_type = fields[i].type;
_row[i].buffer_length = len;
_row[i].buffer = (len > 0) ? (&_buffer[0] + offset) : 0;
_row[i].buffer = _buffer[i];
_row[i].length = &_lengths[i];
_row[i].is_null = reinterpret_cast<my_bool*>(&_isNull[i]); // workaround to make it work with both MySQL 8 and earlier
_row[i].is_unsigned = (fields[i].flags & UNSIGNED_FLAG) > 0;
offset += _row[i].buffer_length;
}
}
@@ -232,16 +248,29 @@ std::size_t ResultMetadata::length(std::size_t pos) const
}
const unsigned char* ResultMetadata::rawData(std::size_t pos) const
const unsigned char* ResultMetadata::rawData(std::size_t pos) const
{
if ((_lengths[pos] == 0) && (_row[pos].buffer == nullptr))
return reinterpret_cast<const unsigned char*>("");
else
poco_check_ptr (_row[pos].buffer);
return reinterpret_cast<const unsigned char*>(_row[pos].buffer);
}
bool ResultMetadata::isNull(std::size_t pos) const
bool ResultMetadata::isNull(std::size_t pos) const
{
return (_isNull[pos] != 0);
}
void ResultMetadata::adjustColumnSizeToFit(std::size_t pos)
{
std::free(_buffer[pos]);
_buffer[pos] = (char*) std::calloc(_lengths[pos], sizeof(char));
_row[pos].buffer = _buffer[pos];
_row[pos].buffer_length = _lengths[pos];
}
} } } // namespace Poco::Data::MySQL
+1 -2
View File
@@ -183,8 +183,7 @@ void SessionHandle::rollback()
void SessionHandle::reset()
{
//#if ((defined (MYSQL_VERSION_ID)) && (MYSQL_VERSION_ID >= 50700)) || ((defined (MARIADB_PACKAGE_VERSION_ID)) && (MARIADB_PACKAGE_VERSION_ID >= 30000))
#if ((POCO_OS == POCO_OS_LINUX) && defined (HAVE_MYSQL_RESET_CONNECTION)) && (((defined (MYSQL_VERSION_ID)) && (MYSQL_VERSION_ID >= 50700)) || ((defined (MARIADB_PACKAGE_VERSION_ID)) && (MARIADB_PACKAGE_VERSION_ID >= 30000)))
#if ((defined (MYSQL_VERSION_ID)) && (MYSQL_VERSION_ID >= 50700)) || ((defined (MARIADB_PACKAGE_VERSION_ID)) && (MARIADB_PACKAGE_VERSION_ID >= 30000))
if (mysql_reset_connection(_pHandle) != 0)
#else
if (mysql_refresh(_pHandle, REFRESH_TABLES | REFRESH_STATUS | REFRESH_THREADS | REFRESH_READ_LOCK) != 0)
+23 -1
View File
@@ -14,6 +14,7 @@
#include "Poco/Data/MySQL/SessionImpl.h"
#include "Poco/Data/MySQL/MySQLStatementImpl.h"
#include "Poco/Data/MySQL/Utility.h"
#include "Poco/Data/Session.h"
#include "Poco/NumberParser.h"
#include "Poco/String.h"
@@ -254,8 +255,29 @@ void SessionImpl::setTransactionIsolation(Poco::UInt32 ti)
Poco::UInt32 SessionImpl::getTransactionIsolation() const
{
const std::string MARIADB_SERVERINFO = "MariaDB";
std::string isolation;
getSetting("tx_isolation", isolation);
std::string serverInfo = Utility::serverInfo(_handle);
unsigned long version = Utility::serverVersion(_handle);
if (serverInfo.find(MARIADB_SERVERINFO) != std::string::npos) //MariaDB
{
getSetting("tx_isolation", isolation);
isolation = isolation.c_str();
}
else //MySQL
{
if (version >= 80000)
{
getSetting("transaction_isolation", isolation);
isolation = isolation.c_str();
}
else
{
getSetting("tx_isolation", isolation);
}
}
Poco::replaceInPlace(isolation, "-", " ");
if (MYSQL_READ_UNCOMMITTED == isolation)
return Session::TRANSACTION_READ_UNCOMMITTED;
+5 -1
View File
@@ -14,7 +14,11 @@
#include "Poco/Data/MySQL/StatementExecutor.h"
#include "Poco/Format.h"
#include <mysql/mysql.h>
#if defined(__MINGW32__) || defined(__MINGW64__)
#include <mysql/mysql.h>
#else
#include <mysql.h>
#endif
namespace Poco {
+5 -1
View File
@@ -15,7 +15,11 @@
#include "Poco/Data/MySQL/Utility.h"
#include <mysql/mysql.h>
#if defined(__MINGW32__) || defined(__MINGW64__)
#include <mysql/mysql.h>
#else
#include <mysql.h>
#endif
namespace Poco {