mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
remove curl
This commit is contained in:
parent
86a83e3e00
commit
e7ca744da0
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -3,4 +3,8 @@
|
|||||||
url = https://github.com/jibsen/tinf.git
|
url = https://github.com/jibsen/tinf.git
|
||||||
[submodule "dependencies/iroha-ed25519"]
|
[submodule "dependencies/iroha-ed25519"]
|
||||||
path = dependencies/iroha-ed25519
|
path = dependencies/iroha-ed25519
|
||||||
url = https://github.com/hyperledger/iroha-ed25519.git
|
url = ssh://git@***REMOVED***/~/Forks/iroha-ed25519
|
||||||
|
[submodule "dependencies/mariadb-connector-c"]
|
||||||
|
path = dependencies/mariadb-connector-c
|
||||||
|
url = https://github.com/MariaDB/mariadb-connector-c.git
|
||||||
|
|
||||||
|
|||||||
1
dependencies/mariadb-connector-c
vendored
Submodule
1
dependencies/mariadb-connector-c
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 9ba8e32f6d0fe449114d8eb369cf29303257b460
|
||||||
0
src/cpp/Crypto/KeyPair.cpp
Normal file
0
src/cpp/Crypto/KeyPair.cpp
Normal file
0
src/cpp/Crypto/KeyPair.h
Normal file
0
src/cpp/Crypto/KeyPair.h
Normal file
0
src/cpp/Crypto/Obfus_array.cpp
Normal file
0
src/cpp/Crypto/Obfus_array.cpp
Normal file
0
src/cpp/Crypto/Obfus_array.h
Normal file
0
src/cpp/Crypto/Obfus_array.h
Normal file
59
src/cpp/HTTPInterface/LoginPage.cpp
Normal file
59
src/cpp/HTTPInterface/LoginPage.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#include "LoginPage.h"
|
||||||
|
#include "Poco/Net/HTTPServerRequest.h"
|
||||||
|
#include "Poco/Net/HTTPServerResponse.h"
|
||||||
|
#include "Poco/Net/HTMLForm.h"
|
||||||
|
#include "Poco/DeflatingStream.h"
|
||||||
|
|
||||||
|
|
||||||
|
#line 4 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\login.cpsp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response)
|
||||||
|
{
|
||||||
|
response.setChunkedTransferEncoding(true);
|
||||||
|
response.setContentType("text/html");
|
||||||
|
bool _compressResponse(request.hasToken("Accept-Encoding", "gzip"));
|
||||||
|
if (_compressResponse) response.set("Content-Encoding", "gzip");
|
||||||
|
|
||||||
|
Poco::Net::HTMLForm form(request, request.stream());
|
||||||
|
std::ostream& _responseStream = response.send();
|
||||||
|
Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1);
|
||||||
|
std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream;
|
||||||
|
responseStream << "\n";
|
||||||
|
responseStream << "<!DOCTYPE html>\n";
|
||||||
|
responseStream << "<html>\n";
|
||||||
|
responseStream << "<head>\n";
|
||||||
|
responseStream << "<meta charset=\"UTF-8\">\n";
|
||||||
|
responseStream << "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n";
|
||||||
|
responseStream << "<title>Gradido Login Server: Login</title>\n";
|
||||||
|
responseStream << "<!--<link rel=\"stylesheet\" type=\"text/css\" href=\"css/styles.min.css\">-->\n";
|
||||||
|
responseStream << "<link rel=\"stylesheet\" type=\"text/css\" href=\"https://gradido2.dario-rekowski.de/css/styles.css\">\n";
|
||||||
|
responseStream << "</head>\n";
|
||||||
|
responseStream << "<body>\n";
|
||||||
|
responseStream << "<h1>Login</h1>\n";
|
||||||
|
responseStream << "<form method=\"POST\">\n";
|
||||||
|
responseStream << "\t<div class=\"grd_container\">\n";
|
||||||
|
responseStream << "\t\t<fieldset class=\"grd_container_small\">\n";
|
||||||
|
responseStream << "\t\t\t<legend>Login</legend>\n";
|
||||||
|
responseStream << "\t\t\t<p>Bitte gebe deine Zugangsdaten ein um dich einzuloggen.</p>\n";
|
||||||
|
responseStream << "\t\t\t<p class=\"grd_small\">\n";
|
||||||
|
responseStream << "\t\t\t\t<label for=\"login-email\">E-Mail</label>\n";
|
||||||
|
responseStream << "\t\t\t\t<input id=\"login-email\" type=\"text\" name=\"login-email\"/>\n";
|
||||||
|
responseStream << "\t\t\t</p>\n";
|
||||||
|
responseStream << "\t\t\t<p class=\"grd_small\">\n";
|
||||||
|
responseStream << "\t\t\t\t<label for=\"login-password\">Passwort</label>\n";
|
||||||
|
responseStream << "\t\t\t\t<input id=\"login-password\" type=\"password\" name=\"login-password\"/>\n";
|
||||||
|
responseStream << "\t\t\t</p>\n";
|
||||||
|
responseStream << "\t\t\t\n";
|
||||||
|
responseStream << "\t\t</fieldset>\n";
|
||||||
|
responseStream << "\t\t<input class=\"grd_bn_succeed\" type=\"submit\" name=\"submit\" value=\"Einloggen\">\n";
|
||||||
|
responseStream << "\t\t<p>Du hast noch keinen Account? Dann folge dem Link um dir einen anzulegen</p>\n";
|
||||||
|
responseStream << "\t\t<a href=\"/register\">Neuen Account anlegen</a>\n";
|
||||||
|
responseStream << "\t</div>\n";
|
||||||
|
responseStream << "</form>\n";
|
||||||
|
responseStream << "</body>\n";
|
||||||
|
responseStream << "</html>\n";
|
||||||
|
if (_compressResponse) _gzipStream.close();
|
||||||
|
}
|
||||||
15
src/cpp/HTTPInterface/LoginPage.h
Normal file
15
src/cpp/HTTPInterface/LoginPage.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef LoginPage_INCLUDED
|
||||||
|
#define LoginPage_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Net/HTTPRequestHandler.h"
|
||||||
|
|
||||||
|
|
||||||
|
class LoginPage: public Poco::Net::HTTPRequestHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // LoginPage_INCLUDED
|
||||||
112
src/cpp/HTTPInterface/RegisterPage.cpp
Normal file
112
src/cpp/HTTPInterface/RegisterPage.cpp
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#include "RegisterPage.h"
|
||||||
|
#include "Poco/Net/HTTPServerRequest.h"
|
||||||
|
#include "Poco/Net/HTTPServerResponse.h"
|
||||||
|
#include "Poco/Net/HTMLForm.h"
|
||||||
|
#include "Poco/DeflatingStream.h"
|
||||||
|
|
||||||
|
|
||||||
|
#line 4 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\register.cpsp"
|
||||||
|
|
||||||
|
#include "../SingletonManager/SessionManager.h"
|
||||||
|
|
||||||
|
|
||||||
|
void RegisterPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response)
|
||||||
|
{
|
||||||
|
response.setChunkedTransferEncoding(true);
|
||||||
|
response.setContentType("text/html");
|
||||||
|
bool _compressResponse(request.hasToken("Accept-Encoding", "gzip"));
|
||||||
|
if (_compressResponse) response.set("Content-Encoding", "gzip");
|
||||||
|
|
||||||
|
Poco::Net::HTMLForm form(request, request.stream());
|
||||||
|
std::ostream& _responseStream = response.send();
|
||||||
|
Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1);
|
||||||
|
std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream;
|
||||||
|
responseStream << "\n";
|
||||||
|
#line 7 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\register.cpsp"
|
||||||
|
|
||||||
|
auto session = SessionManager::getInstance()->getNewSession();
|
||||||
|
bool userReturned = false;
|
||||||
|
if(!form.empty()) {
|
||||||
|
userReturned = session->createUser(
|
||||||
|
form.get("register-name"),
|
||||||
|
form.get("register-email"),
|
||||||
|
form.get("register-password"),
|
||||||
|
form.get("register-key-existing")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
responseStream << "\n";
|
||||||
|
responseStream << "<!DOCTYPE html>\n";
|
||||||
|
responseStream << "<html>\n";
|
||||||
|
responseStream << "<head>\n";
|
||||||
|
responseStream << "<meta charset=\"UTF-8\">\n";
|
||||||
|
responseStream << "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n";
|
||||||
|
responseStream << "<title>Gradido Login Server: Register</title>\n";
|
||||||
|
responseStream << "<!--<link rel=\"stylesheet\" type=\"text/css\" href=\"css/styles.min.css\">-->\n";
|
||||||
|
responseStream << "<link rel=\"stylesheet\" type=\"text/css\" href=\"https://gradido2.dario-rekowski.de/css/styles.css\">\n";
|
||||||
|
responseStream << "<style type=\"text/css\" >\n";
|
||||||
|
responseStream << "input:not([type='radio']) {\n";
|
||||||
|
responseStream << "\twidth:200px;\n";
|
||||||
|
responseStream << "}\n";
|
||||||
|
responseStream << "label:not(.grd_radio_label) {\n";
|
||||||
|
responseStream << "\twidth:80px;\n";
|
||||||
|
responseStream << "\tdisplay:inline-block;\n";
|
||||||
|
responseStream << "}\n";
|
||||||
|
responseStream << "</style>\n";
|
||||||
|
responseStream << "</head>\n";
|
||||||
|
responseStream << "<body>\n";
|
||||||
|
responseStream << "<h1>Einen neuen Account anlegen</h1>\n";
|
||||||
|
responseStream << "\n";
|
||||||
|
responseStream << "<form method=\"POST\">\n";
|
||||||
|
responseStream << "\t<div class=\"grd_container\">\n";
|
||||||
|
responseStream << "\t";
|
||||||
|
#line 42 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\register.cpsp"
|
||||||
|
if(!form.empty() && !userReturned) { responseStream << "\n";
|
||||||
|
responseStream << "\t\t";
|
||||||
|
#line 43 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\register.cpsp"
|
||||||
|
responseStream << ( session->getErrorsHtml() );
|
||||||
|
responseStream << "\n";
|
||||||
|
responseStream << "\t";
|
||||||
|
#line 44 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\register.cpsp"
|
||||||
|
} responseStream << "\n";
|
||||||
|
responseStream << "\t\t<fieldset class=\"grd_container_small\">\n";
|
||||||
|
responseStream << "\t\t\t<legend>Account anlegen</legend>\n";
|
||||||
|
responseStream << "\t\t\t<p>Bitte gebe deine Daten um einen Account anzulegen</p>\n";
|
||||||
|
responseStream << "\t\t\t<p class=\"grd_small\">\n";
|
||||||
|
responseStream << "\t\t\t\t<label for=\"register-name\">Vorname</label>\n";
|
||||||
|
responseStream << "\t\t\t\t<input id=\"register-name\" type=\"text\" name=\"register-name\" value=\"";
|
||||||
|
#line 50 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\register.cpsp"
|
||||||
|
responseStream << ( !form.empty() ? form.get("register-name") : "" );
|
||||||
|
responseStream << "\"/>\n";
|
||||||
|
responseStream << "\t\t\t</p>\n";
|
||||||
|
responseStream << "\t\t\t<p class=\"grd_small\">\n";
|
||||||
|
responseStream << "\t\t\t\t<label for=\"register-email\">E-Mail</label>\n";
|
||||||
|
responseStream << "\t\t\t\t<input id=\"register-email\" type=\"email\" name=\"register-email\" value=\"";
|
||||||
|
#line 54 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\register.cpsp"
|
||||||
|
responseStream << ( !form.empty() ? form.get("register-email") : "" );
|
||||||
|
responseStream << "\"/>\n";
|
||||||
|
responseStream << "\t\t\t</p>\n";
|
||||||
|
responseStream << "\t\t\t<p class=\"grd_small\">\n";
|
||||||
|
responseStream << "\t\t\t\t<label for=\"register-password\">Passwort</label>\n";
|
||||||
|
responseStream << "\t\t\t\t<input id=\"register-password\" type=\"password\" name=\"register-password\"/>\n";
|
||||||
|
responseStream << "\t\t\t</p>\n";
|
||||||
|
responseStream << "\t\t\t<p>Hast du bereits schonmal ein Gradido Konto besessen?</p>\n";
|
||||||
|
responseStream << "\t\t\t<p class=\"grd_small\">\n";
|
||||||
|
responseStream << "\t\t\t\t<input id=\"register-key-new-yes\" type=\"radio\" name=\"register-key\" value=\"yes\" checked/>\n";
|
||||||
|
responseStream << "\t\t\t\t<label class=\"grd_radio_label\" for=\"register-key-new-yes\">Nein, bitte ein neues erstellen!</label>\n";
|
||||||
|
responseStream << "\t\t\t</p>\n";
|
||||||
|
responseStream << "\t\t\t<p class=\"grd_small\">\n";
|
||||||
|
responseStream << "\t\t\t\t<input id=\"register-key-new-no\" type=\"radio\" name=\"register-key\" value=\"no\"/>\n";
|
||||||
|
responseStream << "\t\t\t\t<label class=\"grd_radio_label\" for=\"register-key-new-no\">Ja, bitte wiederherstellen!</label>\n";
|
||||||
|
responseStream << "\t\t\t</p>\n";
|
||||||
|
responseStream << "\t\t\t<textarea style=\"width:100%;height:100px\" name=\"register-key-existing\">";
|
||||||
|
#line 69 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\register.cpsp"
|
||||||
|
responseStream << ( !form.empty() ? form.get("register-key-existing") : "" );
|
||||||
|
responseStream << "</textarea>\n";
|
||||||
|
responseStream << "\t\t</fieldset>\n";
|
||||||
|
responseStream << "\t\t<input class=\"grd_bn_succeed\" type=\"submit\" name=\"submit\" value=\"Einloggen\">\n";
|
||||||
|
responseStream << "\t</div>\n";
|
||||||
|
responseStream << "</form>\n";
|
||||||
|
responseStream << "</body>\n";
|
||||||
|
responseStream << "</html>\n";
|
||||||
|
if (_compressResponse) _gzipStream.close();
|
||||||
|
}
|
||||||
15
src/cpp/HTTPInterface/RegisterPage.h
Normal file
15
src/cpp/HTTPInterface/RegisterPage.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef RegisterPage_INCLUDED
|
||||||
|
#define RegisterPage_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Net/HTTPRequestHandler.h"
|
||||||
|
|
||||||
|
|
||||||
|
class RegisterPage: public Poco::Net::HTTPRequestHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // RegisterPage_INCLUDED
|
||||||
638
src/cpp/MySQL/Binder.cpp
Normal file
638
src/cpp/MySQL/Binder.cpp
Normal file
@ -0,0 +1,638 @@
|
|||||||
|
//
|
||||||
|
// MySQLException.cpp
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: Binder
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/Binder.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
|
||||||
|
Binder::Binder()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Binder::~Binder()
|
||||||
|
{
|
||||||
|
for (std::vector<MYSQL_TIME*>::iterator it = _dates.begin(); it != _dates.end(); ++it)
|
||||||
|
{
|
||||||
|
delete *it;
|
||||||
|
*it = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const Poco::Int8& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_TINY, &val, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const Poco::UInt8& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_TINY, &val, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const Poco::Int16& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_SHORT, &val, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const Poco::UInt16& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_SHORT, &val, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const Poco::Int32& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_LONG, &val, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const Poco::UInt32& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_LONG, &val, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const Poco::Int64& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_LONGLONG, &val, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const Poco::UInt64& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_LONGLONG, &val, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef POCO_LONG_IS_64_BIT
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const long& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_LONG, &val, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const unsigned long& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_LONG, &val, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // POCO_LONG_IS_64_BIT
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const bool& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_TINY, &val, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const float& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_FLOAT, &val, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const double& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_DOUBLE, &val, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const char& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_TINY, &val, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_STRING, val.c_str(), static_cast<int>(val.length()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_BLOB, val.rawContent(), static_cast<int>(val.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const Poco::Data::CLOB& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_BLOB, val.rawContent(), static_cast<int>(val.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const DateTime& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
MYSQL_TIME mt = {0};
|
||||||
|
|
||||||
|
mt.year = val.year();
|
||||||
|
mt.month = val.month();
|
||||||
|
mt.day = val.day();
|
||||||
|
mt.hour = val.hour();
|
||||||
|
mt.minute = val.minute();
|
||||||
|
mt.second = val.second();
|
||||||
|
mt.second_part = val.millisecond() * 1000 + val.microsecond();
|
||||||
|
|
||||||
|
mt.time_type = MYSQL_TIMESTAMP_DATETIME;
|
||||||
|
|
||||||
|
_dates.push_back(new MYSQL_TIME(mt));
|
||||||
|
|
||||||
|
realBind(pos, MYSQL_TYPE_DATETIME, _dates.back(), sizeof(MYSQL_TIME));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const Date& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
MYSQL_TIME mt = {0};
|
||||||
|
|
||||||
|
mt.year = val.year();
|
||||||
|
mt.month = val.month();
|
||||||
|
mt.day = val.day();
|
||||||
|
|
||||||
|
mt.time_type = MYSQL_TIMESTAMP_DATE;
|
||||||
|
|
||||||
|
_dates.push_back(new MYSQL_TIME(mt));
|
||||||
|
|
||||||
|
realBind(pos, MYSQL_TYPE_DATE, _dates.back(), sizeof(MYSQL_TIME));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const Time& val, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
MYSQL_TIME mt = {0};
|
||||||
|
|
||||||
|
mt.hour = val.hour();
|
||||||
|
mt.minute = val.minute();
|
||||||
|
mt.second = val.second();
|
||||||
|
|
||||||
|
mt.time_type = MYSQL_TIMESTAMP_TIME;
|
||||||
|
|
||||||
|
_dates.push_back(new MYSQL_TIME(mt));
|
||||||
|
|
||||||
|
realBind(pos, MYSQL_TYPE_TIME, _dates.back(), sizeof(MYSQL_TIME));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const NullData&, Direction dir)
|
||||||
|
{
|
||||||
|
poco_assert(dir == PD_IN);
|
||||||
|
realBind(pos, MYSQL_TYPE_NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t Binder::size() const
|
||||||
|
{
|
||||||
|
return static_cast<std::size_t>(_bindArray.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MYSQL_BIND* Binder::getBindArray() const
|
||||||
|
{
|
||||||
|
if (_bindArray.size() == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return const_cast<MYSQL_BIND*>(&_bindArray[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*void Binder::updateDates()
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < _dates.size(); i++)
|
||||||
|
{
|
||||||
|
switch (_dates[i].mt.time_type)
|
||||||
|
{
|
||||||
|
case MYSQL_TIMESTAMP_DATE:
|
||||||
|
_dates[i].mt.year = _dates[i].link.date->year();
|
||||||
|
_dates[i].mt.month = _dates[i].link.date->month();
|
||||||
|
_dates[i].mt.day = _dates[i].link.date->day();
|
||||||
|
break;
|
||||||
|
case MYSQL_TIMESTAMP_DATETIME:
|
||||||
|
_dates[i].mt.year = _dates[i].link.dateTime->year();
|
||||||
|
_dates[i].mt.month = _dates[i].link.dateTime->month();
|
||||||
|
_dates[i].mt.day = _dates[i].link.dateTime->day();
|
||||||
|
_dates[i].mt.hour = _dates[i].link.dateTime->hour();
|
||||||
|
_dates[i].mt.minute = _dates[i].link.dateTime->minute();
|
||||||
|
_dates[i].mt.second = _dates[i].link.dateTime->second();
|
||||||
|
_dates[i].mt.second_part = _dates[i].link.dateTime->millisecond();
|
||||||
|
break;
|
||||||
|
case MYSQL_TIMESTAMP_TIME:
|
||||||
|
_dates[i].mt.hour = _dates[i].link.time->hour();
|
||||||
|
_dates[i].mt.minute = _dates[i].link.time->minute();
|
||||||
|
_dates[i].mt.second = _dates[i].link.time->second();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
///////////////////
|
||||||
|
//
|
||||||
|
// Private
|
||||||
|
//
|
||||||
|
////////////////////
|
||||||
|
|
||||||
|
void Binder::realBind(std::size_t pos, enum_field_types type, const void* buffer, int length, bool isUnsigned)
|
||||||
|
{
|
||||||
|
if (pos >= _bindArray.size())
|
||||||
|
{
|
||||||
|
std::size_t s = static_cast<std::size_t>(_bindArray.size());
|
||||||
|
_bindArray.resize(pos + 1);
|
||||||
|
|
||||||
|
std::memset(&_bindArray[s], 0, sizeof(MYSQL_BIND) * (_bindArray.size() - s));
|
||||||
|
}
|
||||||
|
|
||||||
|
MYSQL_BIND b = {0};
|
||||||
|
|
||||||
|
b.buffer_type = type;
|
||||||
|
b.buffer = const_cast<void*>(buffer);
|
||||||
|
b.buffer_length = length;
|
||||||
|
b.is_unsigned = isUnsigned;
|
||||||
|
|
||||||
|
_bindArray[pos] = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<Poco::Int8>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<Poco::Int8>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<Poco::Int8>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<Poco::UInt8>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<Poco::UInt8>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<Poco::UInt8>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<Poco::Int16>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<Poco::Int16>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<Poco::Int16>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<Poco::UInt16>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<Poco::UInt16>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<Poco::UInt16>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<Poco::Int32>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<Poco::Int32>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<Poco::Int32>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<Poco::UInt32>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<Poco::UInt32>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<Poco::UInt32>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<Poco::Int64>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<Poco::Int64>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<Poco::Int64>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<Poco::UInt64>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<Poco::UInt64>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<Poco::UInt64>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<bool>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<bool>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<bool>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<float>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<float>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<float>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<double>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<double>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<double>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<char>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<char>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<char>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<Poco::Data::BLOB>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<Poco::Data::BLOB>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<Poco::Data::BLOB>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<Poco::Data::CLOB>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<Poco::Data::CLOB>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<Poco::Data::CLOB>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<Poco::DateTime>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<Poco::DateTime>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<Poco::DateTime>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<Poco::Data::Date>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<Poco::Data::Date>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<Poco::Data::Date>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<Poco::Data::Time>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<Poco::Data::Time>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<Poco::Data::Time>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<Poco::Data::NullData>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<Poco::Data::NullData>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<Poco::Data::NullData>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::vector<std::string>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::deque<std::string>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Binder::bind(std::size_t pos, const std::list<std::string>& val, Direction dir)
|
||||||
|
{
|
||||||
|
throw NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} } } // namespace Poco::Data::MySQL
|
||||||
72
src/cpp/MySQL/Connector.cpp
Normal file
72
src/cpp/MySQL/Connector.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
//
|
||||||
|
// MySQLException.cpp
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: Connector
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/Connector.h"
|
||||||
|
#include "Poco/Data/MySQL/SessionImpl.h"
|
||||||
|
#include "Poco/Data/SessionFactory.h"
|
||||||
|
#include "Poco/Exception.h"
|
||||||
|
#include <mysql.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
|
||||||
|
std::string Connector::KEY("mysql");
|
||||||
|
|
||||||
|
|
||||||
|
Connector::Connector()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Connector::~Connector()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::string& Connector::name() const
|
||||||
|
{
|
||||||
|
return KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Poco::AutoPtr<Poco::Data::SessionImpl> Connector::createSession(const std::string& connectionString,
|
||||||
|
std::size_t timeout)
|
||||||
|
{
|
||||||
|
return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(connectionString, timeout));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Connector::registerConnector()
|
||||||
|
{
|
||||||
|
if (mysql_library_init(0, 0, 0) != 0)
|
||||||
|
{
|
||||||
|
throw Exception("mysql_library_init error");
|
||||||
|
}
|
||||||
|
|
||||||
|
Poco::Data::SessionFactory::instance().add(new Connector());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Connector::unregisterConnector()
|
||||||
|
{
|
||||||
|
Poco::Data::SessionFactory::instance().remove(KEY);
|
||||||
|
mysql_library_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} } } // namespace Poco::Data::MySQL
|
||||||
|
|
||||||
641
src/cpp/MySQL/Extractor.cpp
Normal file
641
src/cpp/MySQL/Extractor.cpp
Normal file
@ -0,0 +1,641 @@
|
|||||||
|
//
|
||||||
|
// MySQLException.cpp
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: Extractor
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/Extractor.h"
|
||||||
|
|
||||||
|
#include "Poco/Data/Date.h"
|
||||||
|
#include "Poco/Data/Time.h"
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
|
||||||
|
Extractor::Extractor(StatementExecutor& st, ResultMetadata& md): _stmt(st), _metadata(md)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Extractor::~Extractor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, Poco::Int8& val)
|
||||||
|
{
|
||||||
|
return realExtractFixed(pos, MYSQL_TYPE_TINY, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, Poco::UInt8& val)
|
||||||
|
{
|
||||||
|
return realExtractFixed(pos, MYSQL_TYPE_TINY, &val, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, Poco::Int16& val)
|
||||||
|
{
|
||||||
|
return realExtractFixed(pos, MYSQL_TYPE_SHORT, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, Poco::UInt16& val)
|
||||||
|
{
|
||||||
|
return realExtractFixed(pos, MYSQL_TYPE_SHORT, &val, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, Poco::Int32& val)
|
||||||
|
{
|
||||||
|
return realExtractFixed(pos, MYSQL_TYPE_LONG, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, Poco::UInt32& val)
|
||||||
|
{
|
||||||
|
return realExtractFixed(pos, MYSQL_TYPE_LONG, &val, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, Poco::Int64& val)
|
||||||
|
{
|
||||||
|
return realExtractFixed(pos, MYSQL_TYPE_LONGLONG, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, Poco::UInt64& val)
|
||||||
|
{
|
||||||
|
return realExtractFixed(pos, MYSQL_TYPE_LONGLONG, &val, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef POCO_LONG_IS_64_BIT
|
||||||
|
bool Extractor::extract(std::size_t pos, long& val)
|
||||||
|
{
|
||||||
|
return realExtractFixed(pos, MYSQL_TYPE_LONG, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, unsigned long& val)
|
||||||
|
{
|
||||||
|
return realExtractFixed(pos, MYSQL_TYPE_LONG, &val, true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, bool& val)
|
||||||
|
{
|
||||||
|
return realExtractFixed(pos, MYSQL_TYPE_TINY, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, float& val)
|
||||||
|
{
|
||||||
|
return realExtractFixed(pos, MYSQL_TYPE_FLOAT, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, double& val)
|
||||||
|
{
|
||||||
|
return realExtractFixed(pos, MYSQL_TYPE_DOUBLE, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, char& val)
|
||||||
|
{
|
||||||
|
return realExtractFixed(pos, MYSQL_TYPE_TINY, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, std::string& val)
|
||||||
|
{
|
||||||
|
if (_metadata.columnsReturned() <= pos)
|
||||||
|
throw MySQLException("Extractor: attempt to extract more parameters, than query result contain");
|
||||||
|
|
||||||
|
if (_metadata.isNull(static_cast<Poco::UInt32>(pos)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//mysql reports TEXT types as FDT_BLOB when being extracted
|
||||||
|
MetaColumn::ColumnDataType columnType = _metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type();
|
||||||
|
if (columnType != Poco::Data::MetaColumn::FDT_STRING && columnType != Poco::Data::MetaColumn::FDT_BLOB)
|
||||||
|
throw MySQLException("Extractor: not a string");
|
||||||
|
|
||||||
|
val.assign(reinterpret_cast<const char*>(_metadata.rawData(pos)), _metadata.length(pos));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val)
|
||||||
|
{
|
||||||
|
if (_metadata.columnsReturned() <= pos)
|
||||||
|
throw MySQLException("Extractor: attempt to extract more parameters, than query result contain");
|
||||||
|
|
||||||
|
if (_metadata.isNull(static_cast<Poco::UInt32>(pos)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type() != Poco::Data::MetaColumn::FDT_BLOB)
|
||||||
|
throw MySQLException("Extractor: not a blob");
|
||||||
|
|
||||||
|
val.assignRaw(_metadata.rawData(pos), _metadata.length(pos));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, Poco::Data::CLOB& val)
|
||||||
|
{
|
||||||
|
if (_metadata.columnsReturned() <= pos)
|
||||||
|
throw MySQLException("Extractor: attempt to extract more parameters, than query result contain");
|
||||||
|
|
||||||
|
if (_metadata.isNull(static_cast<Poco::UInt32>(pos)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type() != Poco::Data::MetaColumn::FDT_BLOB)
|
||||||
|
throw MySQLException("Extractor: not a blob");
|
||||||
|
|
||||||
|
val.assignRaw(reinterpret_cast<const char*>(_metadata.rawData(pos)), _metadata.length(pos));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, DateTime& val)
|
||||||
|
{
|
||||||
|
MYSQL_TIME mt = {0};
|
||||||
|
|
||||||
|
if (!realExtractFixed(pos, MYSQL_TYPE_DATETIME, &mt))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
val.assign(mt.year, mt.month, mt.day, mt.hour, mt.minute, mt.second, mt.second_part / 1000, mt.second_part % 1000);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, Date& val)
|
||||||
|
{
|
||||||
|
MYSQL_TIME mt = {0};
|
||||||
|
|
||||||
|
if (!realExtractFixed(pos, MYSQL_TYPE_DATE, &mt))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
val.assign(mt.year, mt.month, mt.day);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, Time& val)
|
||||||
|
{
|
||||||
|
MYSQL_TIME mt = {0};
|
||||||
|
|
||||||
|
if (!realExtractFixed(pos, MYSQL_TYPE_TIME, &mt))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
val.assign(mt.hour, mt.minute, mt.second);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, Any& val)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, Dynamic::Var& val)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::isNull(std::size_t col, std::size_t row)
|
||||||
|
{
|
||||||
|
poco_assert(row == POCO_DATA_INVALID_ROW);
|
||||||
|
|
||||||
|
if (_metadata.columnsReturned() <= col)
|
||||||
|
throw MySQLException("Extractor: attempt to extract more parameters, than query result contain");
|
||||||
|
|
||||||
|
if (_metadata.isNull(static_cast<Poco::UInt32>(col)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Extractor::reset()
|
||||||
|
{
|
||||||
|
AbstractExtractor::reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::realExtractFixed(std::size_t pos, enum_field_types type, void* buffer, bool isUnsigned)
|
||||||
|
{
|
||||||
|
MYSQL_BIND bind = {0};
|
||||||
|
my_bool isNull = 0;
|
||||||
|
|
||||||
|
bind.is_null = &isNull;
|
||||||
|
bind.buffer_type = type;
|
||||||
|
bind.buffer = buffer;
|
||||||
|
bind.is_unsigned = isUnsigned;
|
||||||
|
|
||||||
|
if (!_stmt.fetchColumn(pos, &bind))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return isNull == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
// Not implemented
|
||||||
|
//////////////
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<Poco::Int8>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<Poco::Int8>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<Poco::Int8>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<Poco::UInt8>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<Poco::UInt8>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<Poco::UInt8>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<Poco::Int16>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<Poco::Int16>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<Poco::Int16>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<Poco::UInt16>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<Poco::UInt16>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<Poco::UInt16>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<Poco::Int32>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<Poco::Int32>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<Poco::Int32>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<Poco::UInt32>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<Poco::UInt32>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<Poco::UInt32>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<Poco::Int64>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<Poco::Int64>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<Poco::Int64>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<Poco::UInt64>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<Poco::UInt64>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<Poco::UInt64>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef POCO_LONG_IS_64_BIT
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<long>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<long>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<long>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<bool>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<bool>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<bool>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<float>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<float>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<float>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<double>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<double>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<double>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<char>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<char>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<char>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<std::string>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<std::string>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<std::string>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<BLOB>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<BLOB>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<BLOB>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<CLOB>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<CLOB>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<CLOB>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<DateTime>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<DateTime>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<DateTime>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<Date>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<Date>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<Date>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<Time>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<Time>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<Time>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<Any>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<Any>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<Any>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::vector<Dynamic::Var>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::deque<Dynamic::Var>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t , std::list<Dynamic::Var>& )
|
||||||
|
{
|
||||||
|
throw NotImplementedException("std::list extractor must be implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} } } // namespace Poco::Data::MySQL
|
||||||
138
src/cpp/MySQL/MySQLException.cpp
Normal file
138
src/cpp/MySQL/MySQLException.cpp
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
//
|
||||||
|
// MySQLException.cpp
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: MySQLException
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/MySQLException.h"
|
||||||
|
#include <mysql.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
|
||||||
|
MySQLException::MySQLException(const std::string& msg) : Poco::Data::DataException(std::string("[MySQL]: ") + msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MySQLException::MySQLException(const MySQLException& exc) : Poco::Data::DataException(exc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MySQLException::~MySQLException() throw()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////
|
||||||
|
//
|
||||||
|
// ConnectionException
|
||||||
|
//
|
||||||
|
/////
|
||||||
|
|
||||||
|
|
||||||
|
ConnectionException::ConnectionException(const std::string& msg) : MySQLException(msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ConnectionException::ConnectionException(const std::string& text, MYSQL* h) : MySQLException(compose(text, h))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string ConnectionException::compose(const std::string& text, MYSQL* h)
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
str += "[Comment]: ";
|
||||||
|
str += text;
|
||||||
|
str += "\t[mysql_error]: ";
|
||||||
|
str += mysql_error(h);
|
||||||
|
|
||||||
|
str += "\t[mysql_errno]: ";
|
||||||
|
char buff[30];
|
||||||
|
sprintf(buff, "%d", mysql_errno(h));
|
||||||
|
str += buff;
|
||||||
|
|
||||||
|
str += "\t[mysql_sqlstate]: ";
|
||||||
|
str += mysql_sqlstate(h);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////
|
||||||
|
//
|
||||||
|
// TransactionException
|
||||||
|
//
|
||||||
|
/////
|
||||||
|
|
||||||
|
|
||||||
|
TransactionException::TransactionException(const std::string& msg) : ConnectionException(msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TransactionException::TransactionException(const std::string& text, MYSQL* h) : ConnectionException(text, h)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////
|
||||||
|
//
|
||||||
|
// StatementException
|
||||||
|
//
|
||||||
|
/////
|
||||||
|
|
||||||
|
|
||||||
|
StatementException::StatementException(const std::string& msg) : MySQLException(msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StatementException::StatementException(const std::string& text, MYSQL_STMT* h, const std::string& stmt) : MySQLException(compose(text, h, stmt))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string StatementException::compose(const std::string& text, MYSQL_STMT* h, const std::string& stmt)
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
str += "[Comment]: ";
|
||||||
|
str += text;
|
||||||
|
|
||||||
|
if (h != 0)
|
||||||
|
{
|
||||||
|
str += "\t[mysql_stmt_error]: ";
|
||||||
|
str += mysql_stmt_error(h);
|
||||||
|
|
||||||
|
str += "\t[mysql_stmt_errno]: ";
|
||||||
|
char buff[30];
|
||||||
|
sprintf(buff, "%d", mysql_stmt_errno(h));
|
||||||
|
str += buff;
|
||||||
|
|
||||||
|
str += "\t[mysql_stmt_sqlstate]: ";
|
||||||
|
str += mysql_stmt_sqlstate(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stmt.length() > 0)
|
||||||
|
{
|
||||||
|
str += "\t[statemnt]: ";
|
||||||
|
str += stmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
} } } // namespace Poco::Data::MySQL
|
||||||
160
src/cpp/MySQL/MySQLStatementImpl.cpp
Normal file
160
src/cpp/MySQL/MySQLStatementImpl.cpp
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
//
|
||||||
|
// MySQLException.cpp
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: MySQLStatementImpl
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/MySQLStatementImpl.h"
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
|
||||||
|
MySQLStatementImpl::MySQLStatementImpl(SessionImpl& h) :
|
||||||
|
Poco::Data::StatementImpl(h),
|
||||||
|
_stmt(h.handle()),
|
||||||
|
_pBinder(new Binder),
|
||||||
|
_pExtractor(new Extractor(_stmt, _metadata)),
|
||||||
|
_hasNext(NEXT_DONTKNOW)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MySQLStatementImpl::~MySQLStatementImpl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t MySQLStatementImpl::columnsReturned() const
|
||||||
|
{
|
||||||
|
return _metadata.columnsReturned();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int MySQLStatementImpl::affectedRowCount() const
|
||||||
|
{
|
||||||
|
return _stmt.getAffectedRowCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const MetaColumn& MySQLStatementImpl::metaColumn(std::size_t pos) const
|
||||||
|
{
|
||||||
|
return _metadata.metaColumn(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MySQLStatementImpl::hasNext()
|
||||||
|
{
|
||||||
|
if (_hasNext == NEXT_DONTKNOW)
|
||||||
|
{
|
||||||
|
if (_metadata.columnsReturned() == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_stmt.fetch())
|
||||||
|
{
|
||||||
|
_hasNext = NEXT_TRUE;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_hasNext = NEXT_FALSE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (_hasNext == NEXT_TRUE)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t MySQLStatementImpl::next()
|
||||||
|
{
|
||||||
|
if (!hasNext())
|
||||||
|
throw StatementException("No data received");
|
||||||
|
|
||||||
|
Poco::Data::AbstractExtractionVec::iterator it = extractions().begin();
|
||||||
|
Poco::Data::AbstractExtractionVec::iterator itEnd = extractions().end();
|
||||||
|
std::size_t pos = 0;
|
||||||
|
|
||||||
|
for (; it != itEnd; ++it)
|
||||||
|
{
|
||||||
|
(*it)->extract(pos);
|
||||||
|
pos += (*it)->numOfColumnsHandled();
|
||||||
|
}
|
||||||
|
|
||||||
|
_hasNext = NEXT_DONTKNOW;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MySQLStatementImpl::canBind() const
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
if ((_stmt.state() >= StatementExecutor::STMT_COMPILED) && !bindings().empty())
|
||||||
|
ret = (*bindings().begin())->canBind();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MySQLStatementImpl::canCompile() const
|
||||||
|
{
|
||||||
|
return (_stmt.state() < StatementExecutor::STMT_COMPILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MySQLStatementImpl::compileImpl()
|
||||||
|
{
|
||||||
|
_metadata.reset();
|
||||||
|
_stmt.prepare(toString());
|
||||||
|
_metadata.init(_stmt);
|
||||||
|
|
||||||
|
if (_metadata.columnsReturned() > 0)
|
||||||
|
_stmt.bindResult(_metadata.row());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MySQLStatementImpl::bindImpl()
|
||||||
|
{
|
||||||
|
Poco::Data::AbstractBindingVec& binds = bindings();
|
||||||
|
std::size_t pos = 0;
|
||||||
|
Poco::Data::AbstractBindingVec::iterator it = binds.begin();
|
||||||
|
Poco::Data::AbstractBindingVec::iterator itEnd = binds.end();
|
||||||
|
for (; it != itEnd && (*it)->canBind(); ++it)
|
||||||
|
{
|
||||||
|
(*it)->bind(pos);
|
||||||
|
pos += (*it)->numOfColumnsHandled();
|
||||||
|
}
|
||||||
|
|
||||||
|
_stmt.bindParams(_pBinder->getBindArray(), _pBinder->size());
|
||||||
|
_stmt.execute();
|
||||||
|
_hasNext = NEXT_DONTKNOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Poco::Data::AbstractExtractor::Ptr MySQLStatementImpl::extractor()
|
||||||
|
{
|
||||||
|
return _pExtractor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Poco::Data::AbstractBinder::Ptr MySQLStatementImpl::binder()
|
||||||
|
{
|
||||||
|
return _pBinder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} } } // namespace Poco::Data::MySQL
|
||||||
262
src/cpp/MySQL/Poco/Binder.h
Normal file
262
src/cpp/MySQL/Poco/Binder.h
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
//
|
||||||
|
// Binder.h
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: Binder
|
||||||
|
//
|
||||||
|
// Definition of the Binder class.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Data_MySQL_Binder_INCLUDED
|
||||||
|
#define Data_MySQL_Binder_INCLUDED
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/MySQL.h"
|
||||||
|
#include "Poco/Data/AbstractBinder.h"
|
||||||
|
#include "Poco/Data/LOB.h"
|
||||||
|
#include "Poco/Data/MySQL/MySQLException.h"
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma comment(lib, "Ws2_32.lib")
|
||||||
|
#pragma comment(lib, "shlwapi.lib")
|
||||||
|
#endif
|
||||||
|
#include <mysql.h>
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
|
||||||
|
class MySQL_API Binder: public Poco::Data::AbstractBinder
|
||||||
|
/// Binds placeholders in the sql query to the provided values. Performs data types mapping.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef SharedPtr<Binder> Ptr;
|
||||||
|
|
||||||
|
Binder();
|
||||||
|
/// Creates the Binder.
|
||||||
|
|
||||||
|
virtual ~Binder();
|
||||||
|
/// Destroys the Binder.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const Poco::Int8& val, Direction dir);
|
||||||
|
/// Binds an Int8.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const Poco::UInt8& val, Direction dir);
|
||||||
|
/// Binds an UInt8.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const Poco::Int16& val, Direction dir);
|
||||||
|
/// Binds an Int16.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const Poco::UInt16& val, Direction dir);
|
||||||
|
/// Binds an UInt16.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const Poco::Int32& val, Direction dir);
|
||||||
|
/// Binds an Int32.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const Poco::UInt32& val, Direction dir);
|
||||||
|
/// Binds an UInt32.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const Poco::Int64& val, Direction dir);
|
||||||
|
/// Binds an Int64.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const Poco::UInt64& val, Direction dir);
|
||||||
|
/// Binds an UInt64.
|
||||||
|
|
||||||
|
#ifndef POCO_LONG_IS_64_BIT
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const long& val, Direction dir = PD_IN);
|
||||||
|
/// Binds a long.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const unsigned long& val, Direction dir = PD_IN);
|
||||||
|
/// Binds an unsigned long.
|
||||||
|
|
||||||
|
#endif // POCO_LONG_IS_64_BIT
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const bool& val, Direction dir);
|
||||||
|
/// Binds a boolean.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const float& val, Direction dir);
|
||||||
|
/// Binds a float.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const double& val, Direction dir);
|
||||||
|
/// Binds a double.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const char& val, Direction dir);
|
||||||
|
/// Binds a single character.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::string& val, Direction dir);
|
||||||
|
/// Binds a string.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir);
|
||||||
|
/// Binds a BLOB.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const Poco::Data::CLOB& val, Direction dir);
|
||||||
|
/// Binds a CLOB.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const DateTime& val, Direction dir);
|
||||||
|
/// Binds a DateTime.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const Date& val, Direction dir);
|
||||||
|
/// Binds a Date.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const Time& val, Direction dir);
|
||||||
|
/// Binds a Time.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const NullData& val, Direction dir);
|
||||||
|
/// Binds a null.
|
||||||
|
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<Poco::Int8>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<Poco::Int8>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<Poco::Int8>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<Poco::UInt8>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<Poco::UInt8>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<Poco::UInt8>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<Poco::Int16>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<Poco::Int16>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<Poco::Int16>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<Poco::UInt16>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<Poco::UInt16>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<Poco::UInt16>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<Poco::Int32>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<Poco::Int32>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<Poco::Int32>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<Poco::UInt32>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<Poco::UInt32>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<Poco::UInt32>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<Poco::Int64>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<Poco::Int64>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<Poco::Int64>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<Poco::UInt64>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<Poco::UInt64>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<Poco::UInt64>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<bool>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<bool>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<bool>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<float>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<float>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<float>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<double>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<double>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<double>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<char>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<char>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<char>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<BLOB>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<BLOB>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<BLOB>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<CLOB>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<CLOB>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<CLOB>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<DateTime>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<DateTime>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<DateTime>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<Date>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<Date>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<Date>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<Time>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<Time>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<Time>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<NullData>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<NullData>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<NullData>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<std::string>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<std::string>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<std::string>& val, Direction dir = PD_IN);
|
||||||
|
|
||||||
|
std::size_t size() const;
|
||||||
|
/// Return count of binded parameters
|
||||||
|
|
||||||
|
MYSQL_BIND* getBindArray() const;
|
||||||
|
/// Return array
|
||||||
|
|
||||||
|
//void updateDates();
|
||||||
|
/// Update linked times
|
||||||
|
|
||||||
|
private:
|
||||||
|
Binder(const Binder&);
|
||||||
|
/// Don't copy the binder
|
||||||
|
|
||||||
|
virtual void bind(std::size_t, const char* const&, Direction)
|
||||||
|
/// Binds a const char ptr.
|
||||||
|
/// This is a private no-op in this implementation
|
||||||
|
/// due to security risk.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void realBind(std::size_t pos, enum_field_types type, const void* buffer, int length, bool isUnsigned = false);
|
||||||
|
/// Common bind implementation
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::vector<MYSQL_BIND> _bindArray;
|
||||||
|
std::vector<MYSQL_TIME*> _dates;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} } } // namespace Poco::Data::MySQL
|
||||||
|
|
||||||
|
|
||||||
|
#endif // Data_MySQL_Binder_INCLUDED
|
||||||
61
src/cpp/MySQL/Poco/Connector.h
Normal file
61
src/cpp/MySQL/Poco/Connector.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
//
|
||||||
|
// Connector.h
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: Connector
|
||||||
|
//
|
||||||
|
// Definition of the Connector class.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Data_MySQL_Connector_INCLUDED
|
||||||
|
#define Data_MySQL_Connector_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/MySQL.h"
|
||||||
|
#include "Poco/Data/Connector.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
|
||||||
|
class MySQL_API Connector: public Poco::Data::Connector
|
||||||
|
/// Connector instantiates MySQL SessionImpl objects.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static std::string KEY;
|
||||||
|
|
||||||
|
Connector();
|
||||||
|
/// Creates the Connector.
|
||||||
|
|
||||||
|
virtual ~Connector();
|
||||||
|
/// Destroys the Connector.
|
||||||
|
|
||||||
|
virtual const std::string& name() const;
|
||||||
|
/// Returns the name associated with this connector.
|
||||||
|
|
||||||
|
virtual Poco::AutoPtr<Poco::Data::SessionImpl> createSession(const std::string& connectionString,
|
||||||
|
std::size_t timeout = Poco::Data::SessionImpl::LOGIN_TIMEOUT_DEFAULT);
|
||||||
|
/// Creates a MySQL SessionImpl object and initializes it with the given connectionString.
|
||||||
|
|
||||||
|
static void registerConnector();
|
||||||
|
/// Registers the Connector under the Keyword Connector::KEY at the Poco::Data::SessionFactory
|
||||||
|
|
||||||
|
static void unregisterConnector();
|
||||||
|
/// Unregisters the Connector under the Keyword Connector::KEY at the Poco::Data::SessionFactory
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} } } // namespace Poco::Data::MySQL
|
||||||
|
|
||||||
|
|
||||||
|
#endif // Data_MySQL_Connector_INCLUDED
|
||||||
336
src/cpp/MySQL/Poco/Extractor.h
Normal file
336
src/cpp/MySQL/Poco/Extractor.h
Normal file
@ -0,0 +1,336 @@
|
|||||||
|
//
|
||||||
|
// Extractor.h
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: Extractor
|
||||||
|
//
|
||||||
|
// Definition of the Extractor class.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Data_MySQL_Extractor_INCLUDED
|
||||||
|
#define Data_MySQL_Extractor_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/MySQL.h"
|
||||||
|
#include "Poco/Data/MySQL/StatementExecutor.h"
|
||||||
|
#include "Poco/Data/MySQL/ResultMetadata.h"
|
||||||
|
#include "Poco/Data/AbstractExtractor.h"
|
||||||
|
#include "Poco/Data/LOB.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
|
||||||
|
namespace Dynamic {
|
||||||
|
class Var;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
|
||||||
|
class MySQL_API Extractor: public Poco::Data::AbstractExtractor
|
||||||
|
/// Extracts and converts data values from the result row returned by MySQL.
|
||||||
|
/// If NULL is received, the incoming val value is not changed and false is returned
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef SharedPtr<Extractor> Ptr;
|
||||||
|
|
||||||
|
Extractor(StatementExecutor& st, ResultMetadata& md);
|
||||||
|
/// Creates the Extractor.
|
||||||
|
|
||||||
|
virtual ~Extractor();
|
||||||
|
/// Destroys the Extractor.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, Poco::Int8& val);
|
||||||
|
/// Extracts an Int8.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, Poco::UInt8& val);
|
||||||
|
/// Extracts an UInt8.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, Poco::Int16& val);
|
||||||
|
/// Extracts an Int16.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, Poco::UInt16& val);
|
||||||
|
/// Extracts an UInt16.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, Poco::Int32& val);
|
||||||
|
/// Extracts an Int32.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, Poco::UInt32& val);
|
||||||
|
/// Extracts an UInt32.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, Poco::Int64& val);
|
||||||
|
/// Extracts an Int64.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, Poco::UInt64& val);
|
||||||
|
/// Extracts an UInt64.
|
||||||
|
|
||||||
|
#ifndef POCO_LONG_IS_64_BIT
|
||||||
|
virtual bool extract(std::size_t pos, long& val);
|
||||||
|
/// Extracts a long. Returns false if null was received.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, unsigned long& val);
|
||||||
|
/// Extracts an unsigned long. Returns false if null was received.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, bool& val);
|
||||||
|
/// Extracts a boolean.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, float& val);
|
||||||
|
/// Extracts a float.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, double& val);
|
||||||
|
/// Extracts a double.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, char& val);
|
||||||
|
/// Extracts a single character.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::string& val);
|
||||||
|
/// Extracts a string.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, Poco::Data::BLOB& val);
|
||||||
|
/// Extracts a BLOB.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, Poco::Data::CLOB& val);
|
||||||
|
/// Extracts a CLOB.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, DateTime& val);
|
||||||
|
/// Extracts a DateTime. Returns false if null was received.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, Date& val);
|
||||||
|
/// Extracts a Date. Returns false if null was received.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, Time& val);
|
||||||
|
/// Extracts a Time. Returns false if null was received.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, Any& val);
|
||||||
|
/// Extracts an Any. Returns false if null was received.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, Dynamic::Var& val);
|
||||||
|
/// Extracts a Dynamic::Var. Returns false if null was received.
|
||||||
|
|
||||||
|
virtual bool isNull(std::size_t col, std::size_t row);
|
||||||
|
/// Returns true if the value at [col,row] position is null.
|
||||||
|
|
||||||
|
virtual void reset();
|
||||||
|
/// Resets any information internally cached by the extractor.
|
||||||
|
|
||||||
|
////////////
|
||||||
|
// Not implemented extract functions
|
||||||
|
////////////
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<Poco::Int8>& val);
|
||||||
|
/// Extracts an Int8 vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<Poco::Int8>& val);
|
||||||
|
/// Extracts an Int8 deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<Poco::Int8>& val);
|
||||||
|
/// Extracts an Int8 list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<Poco::UInt8>& val);
|
||||||
|
/// Extracts an UInt8 vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<Poco::UInt8>& val);
|
||||||
|
/// Extracts an UInt8 deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<Poco::UInt8>& val);
|
||||||
|
/// Extracts an UInt8 list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<Poco::Int16>& val);
|
||||||
|
/// Extracts an Int16 vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<Poco::Int16>& val);
|
||||||
|
/// Extracts an Int16 deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<Poco::Int16>& val);
|
||||||
|
/// Extracts an Int16 list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<Poco::UInt16>& val);
|
||||||
|
/// Extracts an UInt16 vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<Poco::UInt16>& val);
|
||||||
|
/// Extracts an UInt16 deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<Poco::UInt16>& val);
|
||||||
|
/// Extracts an UInt16 list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<Poco::Int32>& val);
|
||||||
|
/// Extracts an Int32 vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<Poco::Int32>& val);
|
||||||
|
/// Extracts an Int32 deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<Poco::Int32>& val);
|
||||||
|
/// Extracts an Int32 list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<Poco::UInt32>& val);
|
||||||
|
/// Extracts an UInt32 vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<Poco::UInt32>& val);
|
||||||
|
/// Extracts an UInt32 deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<Poco::UInt32>& val);
|
||||||
|
/// Extracts an UInt32 list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<Poco::Int64>& val);
|
||||||
|
/// Extracts an Int64 vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<Poco::Int64>& val);
|
||||||
|
/// Extracts an Int64 deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<Poco::Int64>& val);
|
||||||
|
/// Extracts an Int64 list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<Poco::UInt64>& val);
|
||||||
|
/// Extracts an UInt64 vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<Poco::UInt64>& val);
|
||||||
|
/// Extracts an UInt64 deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<Poco::UInt64>& val);
|
||||||
|
/// Extracts an UInt64 list.
|
||||||
|
|
||||||
|
#ifndef POCO_LONG_IS_64_BIT
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<long>& val);
|
||||||
|
/// Extracts a long vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<long>& val);
|
||||||
|
/// Extracts a long deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<long>& val);
|
||||||
|
/// Extracts a long list.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<bool>& val);
|
||||||
|
/// Extracts a boolean vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<bool>& val);
|
||||||
|
/// Extracts a boolean deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<bool>& val);
|
||||||
|
/// Extracts a boolean list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<float>& val);
|
||||||
|
/// Extracts a float vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<float>& val);
|
||||||
|
/// Extracts a float deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<float>& val);
|
||||||
|
/// Extracts a float list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<double>& val);
|
||||||
|
/// Extracts a double vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<double>& val);
|
||||||
|
/// Extracts a double deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<double>& val);
|
||||||
|
/// Extracts a double list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<char>& val);
|
||||||
|
/// Extracts a character vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<char>& val);
|
||||||
|
/// Extracts a character deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<char>& val);
|
||||||
|
/// Extracts a character list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<std::string>& val);
|
||||||
|
/// Extracts a string vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<std::string>& val);
|
||||||
|
/// Extracts a string deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<std::string>& val);
|
||||||
|
/// Extracts a string list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<BLOB>& val);
|
||||||
|
/// Extracts a BLOB vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<BLOB>& val);
|
||||||
|
/// Extracts a BLOB deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<BLOB>& val);
|
||||||
|
/// Extracts a BLOB list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<CLOB>& val);
|
||||||
|
/// Extracts a CLOB vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<CLOB>& val);
|
||||||
|
/// Extracts a CLOB deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<CLOB>& val);
|
||||||
|
/// Extracts a CLOB list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<DateTime>& val);
|
||||||
|
/// Extracts a DateTime vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<DateTime>& val);
|
||||||
|
/// Extracts a DateTime deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<DateTime>& val);
|
||||||
|
/// Extracts a DateTime list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<Date>& val);
|
||||||
|
/// Extracts a Date vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<Date>& val);
|
||||||
|
/// Extracts a Date deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<Date>& val);
|
||||||
|
/// Extracts a Date list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<Time>& val);
|
||||||
|
/// Extracts a Time vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<Time>& val);
|
||||||
|
/// Extracts a Time deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<Time>& val);
|
||||||
|
/// Extracts a Time list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<Any>& val);
|
||||||
|
/// Extracts an Any vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<Any>& val);
|
||||||
|
/// Extracts an Any deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<Any>& val);
|
||||||
|
/// Extracts an Any list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<Dynamic::Var>& val);
|
||||||
|
/// Extracts a Dynamic::Var vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<Dynamic::Var>& val);
|
||||||
|
/// Extracts a Dynamic::Var deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<Dynamic::Var>& val);
|
||||||
|
/// Extracts a Dynamic::Var list.
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool realExtractFixed(std::size_t pos, enum_field_types type, void* buffer, bool isUnsigned = false);
|
||||||
|
|
||||||
|
// Prevent VC8 warning "operator= could not be generated"
|
||||||
|
Extractor& operator=(const Extractor&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
StatementExecutor& _stmt;
|
||||||
|
ResultMetadata& _metadata;
|
||||||
|
};
|
||||||
|
|
||||||
|
} } } // namespace Poco::Data::MySQL
|
||||||
|
|
||||||
|
|
||||||
|
#endif // Data_MySQL_Extractor_INCLUDED
|
||||||
60
src/cpp/MySQL/Poco/MySQL.h
Normal file
60
src/cpp/MySQL/Poco/MySQL.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
//
|
||||||
|
// MySQL.h
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: MySQL
|
||||||
|
//
|
||||||
|
// Basic definitions for the MySQL library.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MySQL_MySQL_INCLUDED
|
||||||
|
#define MySQL_MySQL_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Foundation.h"
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// The following block is the standard way of creating macros which make exporting
|
||||||
|
// from a DLL simpler. All files within this DLL are compiled with the ODBC_EXPORTS
|
||||||
|
// symbol defined on the command line. this symbol should not be defined on any project
|
||||||
|
// that uses this DLL. This way any other project whose source files include this file see
|
||||||
|
// ODBC_API functions as being imported from a DLL, wheras this DLL sees symbols
|
||||||
|
// defined with this macro as being exported.
|
||||||
|
//
|
||||||
|
#if defined(_WIN32) && defined(POCO_DLL)
|
||||||
|
#if defined(MySQL_EXPORTS)
|
||||||
|
#define MySQL_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define MySQL_API __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(MySQL_API)
|
||||||
|
#if !defined(POCO_NO_GCC_API_ATTRIBUTE) && defined (__GNUC__) && (__GNUC__ >= 4)
|
||||||
|
#define MySQL_API __attribute__ ((visibility ("default")))
|
||||||
|
#else
|
||||||
|
#define MySQL_API
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Automatically link Data library.
|
||||||
|
//
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#if !defined(POCO_NO_AUTOMATIC_LIBS) && !defined(MySQL_EXPORTS)
|
||||||
|
#pragma comment(lib, "PocoDataMySQL" POCO_LIB_SUFFIX)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif // MySQL_MySQL_INCLUDED
|
||||||
156
src/cpp/MySQL/Poco/MySQLException.h
Normal file
156
src/cpp/MySQL/Poco/MySQLException.h
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
//
|
||||||
|
// MySQLException.h
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: MySQLException
|
||||||
|
//
|
||||||
|
// Definition of the MySQLException class.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Data_MySQL_MySQLException_INCLUDED
|
||||||
|
#define Data_MySQL_MySQLException_INCLUDED
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/MySQL.h"
|
||||||
|
#include "Poco/Data/DataException.h"
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct st_mysql MYSQL;
|
||||||
|
typedef struct st_mysql_stmt MYSQL_STMT;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
// End-user include this file and use in code ConnectionException/StatementException
|
||||||
|
// So it need not know
|
||||||
|
|
||||||
|
class MySQL_API MySQLException: public Poco::Data::DataException
|
||||||
|
/// Base class for all MySQL exceptions
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
MySQLException(const std::string& msg);
|
||||||
|
/// Creates MySQLException.
|
||||||
|
|
||||||
|
MySQLException(const MySQLException& exc);
|
||||||
|
/// Creates MySQLException.
|
||||||
|
|
||||||
|
~MySQLException() throw();
|
||||||
|
/// Destroys MySQLexception.
|
||||||
|
|
||||||
|
MySQLException& operator=(const MySQLException& exc);
|
||||||
|
/// Assignment operator.
|
||||||
|
|
||||||
|
const char* name() const throw();
|
||||||
|
/// Returns exception name.
|
||||||
|
|
||||||
|
const char* className() const throw();
|
||||||
|
/// Returns the name of the exception class.
|
||||||
|
|
||||||
|
Poco::Exception* clone() const;
|
||||||
|
/// Creates an exact copy of the exception.
|
||||||
|
///
|
||||||
|
/// The copy can later be thrown again by
|
||||||
|
/// invoking rethrow() on it.
|
||||||
|
|
||||||
|
void rethrow() const;
|
||||||
|
/// (Re)Throws the exception.
|
||||||
|
///
|
||||||
|
/// This is useful for temporarily storing a
|
||||||
|
/// copy of an exception (see clone()), then
|
||||||
|
/// throwing it again.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ConnectionException : public MySQLException
|
||||||
|
/// ConnectionException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
ConnectionException(const std::string& msg);
|
||||||
|
/// Creates ConnectionException from string.
|
||||||
|
|
||||||
|
ConnectionException(const std::string& text, MYSQL* h);
|
||||||
|
/// Creates ConnectionException from string and handle.
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static std::string compose(const std::string& text, MYSQL* h);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class TransactionException : public ConnectionException
|
||||||
|
/// TrabsactionException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
TransactionException(const std::string& msg);
|
||||||
|
/// Creates TransactionException from string.
|
||||||
|
|
||||||
|
TransactionException(const std::string& text, MYSQL* h);
|
||||||
|
/// Creates TransactionException from string and handle.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class StatementException : public MySQLException
|
||||||
|
/// StatementException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
StatementException(const std::string& msg);
|
||||||
|
/// Creates StatementException from string.
|
||||||
|
|
||||||
|
StatementException(const std::string& text, MYSQL_STMT* h, const std::string& stmt = "");
|
||||||
|
/// Creates StatementException from string and handle.
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static std::string compose(const std::string& text, MYSQL_STMT* h, const std::string& stmt);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
|
||||||
|
inline MySQLException& MySQLException::operator=(const MySQLException& exc)
|
||||||
|
{
|
||||||
|
Poco::Data::DataException::operator=(exc);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char* MySQLException::name() const throw()
|
||||||
|
{
|
||||||
|
return "MySQL";
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char* MySQLException::className() const throw()
|
||||||
|
{
|
||||||
|
return typeid(*this).name();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Poco::Exception* MySQLException::clone() const
|
||||||
|
{
|
||||||
|
return new MySQLException(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void MySQLException::rethrow() const
|
||||||
|
{
|
||||||
|
throw *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} } } // namespace Poco::Data::MySQL
|
||||||
|
|
||||||
|
#endif //Data_MySQL_MySQLException_INCLUDED
|
||||||
102
src/cpp/MySQL/Poco/MySQLStatementImpl.h
Normal file
102
src/cpp/MySQL/Poco/MySQLStatementImpl.h
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
//
|
||||||
|
// MySQLstatementImpl.h
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: MySQLstatementImpl
|
||||||
|
//
|
||||||
|
// Definition of the MySQLStatementImpl class.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Data_MySQL_MySQLStatementImpl_INCLUDED
|
||||||
|
#define Data_MySQL_MySQLStatementImpl_INCLUDED
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/MySQL.h"
|
||||||
|
#include "Poco/Data/MySQL/SessionImpl.h"
|
||||||
|
#include "Poco/Data/MySQL/Binder.h"
|
||||||
|
#include "Poco/Data/MySQL/Extractor.h"
|
||||||
|
#include "Poco/Data/MySQL/StatementExecutor.h"
|
||||||
|
#include "Poco/Data/MySQL/ResultMetadata.h"
|
||||||
|
#include "Poco/Data/StatementImpl.h"
|
||||||
|
#include "Poco/SharedPtr.h"
|
||||||
|
#include "Poco/Format.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
|
||||||
|
class MySQL_API MySQLStatementImpl: public Poco::Data::StatementImpl
|
||||||
|
/// Implements statement functionality needed for MySQL
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MySQLStatementImpl(SessionImpl& s);
|
||||||
|
/// Creates the MySQLStatementImpl.
|
||||||
|
|
||||||
|
~MySQLStatementImpl();
|
||||||
|
/// Destroys the MySQLStatementImpl.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual std::size_t columnsReturned() const;
|
||||||
|
/// Returns number of columns returned by query.
|
||||||
|
|
||||||
|
virtual int affectedRowCount() const;
|
||||||
|
/// Returns the number of affected rows.
|
||||||
|
/// Used to find out the number of rows affected by insert, delete or update.
|
||||||
|
|
||||||
|
virtual const MetaColumn& metaColumn(std::size_t pos) const;
|
||||||
|
/// Returns column meta data.
|
||||||
|
|
||||||
|
virtual bool hasNext();
|
||||||
|
/// Returns true if a call to next() will return data.
|
||||||
|
|
||||||
|
virtual std::size_t next();
|
||||||
|
/// Retrieves the next row from the resultset.
|
||||||
|
/// Will throw, if the resultset is empty.
|
||||||
|
|
||||||
|
virtual bool canBind() const;
|
||||||
|
/// Returns true if a valid statement is set and we can bind.
|
||||||
|
|
||||||
|
virtual bool canCompile() const;
|
||||||
|
/// Returns true if another compile is possible.
|
||||||
|
|
||||||
|
virtual void compileImpl();
|
||||||
|
/// Compiles the statement, doesn't bind yet
|
||||||
|
|
||||||
|
virtual void bindImpl();
|
||||||
|
/// Binds parameters
|
||||||
|
|
||||||
|
virtual Poco::Data::AbstractExtractor::Ptr extractor();
|
||||||
|
/// Returns the concrete extractor used by the statement.
|
||||||
|
|
||||||
|
virtual Poco::Data::AbstractBinder::Ptr binder();
|
||||||
|
/// Returns the concrete binder used by the statement.
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
NEXT_DONTKNOW,
|
||||||
|
NEXT_TRUE,
|
||||||
|
NEXT_FALSE
|
||||||
|
};
|
||||||
|
|
||||||
|
StatementExecutor _stmt;
|
||||||
|
ResultMetadata _metadata;
|
||||||
|
Binder::Ptr _pBinder;
|
||||||
|
Extractor::Ptr _pExtractor;
|
||||||
|
int _hasNext;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} } } // namespace Poco::Data::MySQL
|
||||||
|
|
||||||
|
|
||||||
|
#endif // Data_MySQL_MySQLStatementImpl_INCLUDED
|
||||||
67
src/cpp/MySQL/Poco/ResultMetadata.h
Normal file
67
src/cpp/MySQL/Poco/ResultMetadata.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
//
|
||||||
|
// ResultMetadata.h
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: ResultMetadata
|
||||||
|
//
|
||||||
|
// Definition of the ResultMetadata class.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Data_MySQL_ResultMetadata_INCLUDED
|
||||||
|
#define Data_MySQL_ResultMetadata_INCLUDED
|
||||||
|
|
||||||
|
#include <mysql.h>
|
||||||
|
#include <vector>
|
||||||
|
#include "Poco/Data/MetaColumn.h"
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
class ResultMetadata
|
||||||
|
/// MySQL result metadata
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
/// Resets the metadata.
|
||||||
|
|
||||||
|
void init(MYSQL_STMT* stmt);
|
||||||
|
/// Initializes the metadata.
|
||||||
|
|
||||||
|
std::size_t columnsReturned() const;
|
||||||
|
/// Returns the number of columns in resultset.
|
||||||
|
|
||||||
|
const MetaColumn& metaColumn(std::size_t pos) const;
|
||||||
|
/// Returns the reference to the specified metacolumn.
|
||||||
|
|
||||||
|
MYSQL_BIND* row();
|
||||||
|
/// Returns pointer to native row.
|
||||||
|
|
||||||
|
std::size_t length(std::size_t pos) const;
|
||||||
|
/// Returns the length.
|
||||||
|
|
||||||
|
const unsigned char* rawData(std::size_t pos) const;
|
||||||
|
/// Returns raw data.
|
||||||
|
|
||||||
|
bool isNull(std::size_t pos) const;
|
||||||
|
/// Returns true if value at pos is null.
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<MetaColumn> _columns;
|
||||||
|
std::vector<MYSQL_BIND> _row;
|
||||||
|
std::vector<char> _buffer;
|
||||||
|
std::vector<unsigned long> _lengths;
|
||||||
|
std::vector<my_bool> _isNull;
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
|
#endif //Data_MySQL_ResultMetadata_INCLUDED
|
||||||
93
src/cpp/MySQL/Poco/SessionHandle.h
Normal file
93
src/cpp/MySQL/Poco/SessionHandle.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
//
|
||||||
|
// SesssionHandle.h
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: SessionHandle
|
||||||
|
//
|
||||||
|
// Definition of the SessionHandle class.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Data_MySQL_SessionHandle_INCLUDED
|
||||||
|
#define Data_MySQL_SessionHandle_INCLUDED
|
||||||
|
|
||||||
|
#include <mysql.h>
|
||||||
|
#include "Poco/Data/MySQL/MySQLException.h"
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
class SessionHandle
|
||||||
|
/// MySQL session handle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit SessionHandle(MYSQL* mysql);
|
||||||
|
/// Creates session handle
|
||||||
|
|
||||||
|
~SessionHandle();
|
||||||
|
/// Destroy handle, close connection
|
||||||
|
|
||||||
|
void init(MYSQL* mysql = 0);
|
||||||
|
/// Initializes the handle iff not initialized.
|
||||||
|
|
||||||
|
void options(mysql_option opt);
|
||||||
|
/// Set connection options
|
||||||
|
|
||||||
|
void options(mysql_option opt, bool b);
|
||||||
|
/// Set connection options
|
||||||
|
|
||||||
|
void options(mysql_option opt, const char* c);
|
||||||
|
/// Set connection options
|
||||||
|
|
||||||
|
void options(mysql_option opt, unsigned int i);
|
||||||
|
/// Set connection options
|
||||||
|
|
||||||
|
void connect(const char* host, const char* user, const char* password, const char* db, unsigned int port);
|
||||||
|
/// Connect to server
|
||||||
|
|
||||||
|
void close();
|
||||||
|
/// Close connection
|
||||||
|
|
||||||
|
void startTransaction();
|
||||||
|
/// Start transaction
|
||||||
|
|
||||||
|
void commit();
|
||||||
|
/// Commit transaction
|
||||||
|
|
||||||
|
void rollback();
|
||||||
|
/// Rollback transaction
|
||||||
|
|
||||||
|
operator MYSQL* ();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
SessionHandle(const SessionHandle&);
|
||||||
|
SessionHandle& operator=(const SessionHandle&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
MYSQL* _pHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
|
||||||
|
inline SessionHandle::operator MYSQL* ()
|
||||||
|
{
|
||||||
|
return _pHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
|
#endif // Data_MySQL_SessionHandle_INCLUDED
|
||||||
230
src/cpp/MySQL/Poco/SessionImpl.h
Normal file
230
src/cpp/MySQL/Poco/SessionImpl.h
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
//
|
||||||
|
// SessionImpl.h
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: SessionImpl
|
||||||
|
//
|
||||||
|
// Definition of the SessionImpl class.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Data_MySQL_SessionImpl_INCLUDED
|
||||||
|
#define Data_MySQL_SessionImpl_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/MySQL.h"
|
||||||
|
#include "Poco/Data/AbstractSessionImpl.h"
|
||||||
|
#include "Poco/Data/MySQL/SessionHandle.h"
|
||||||
|
#include "Poco/Data/MySQL/StatementExecutor.h"
|
||||||
|
#include "Poco/Data/MySQL/ResultMetadata.h"
|
||||||
|
#include "Poco/Mutex.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
|
||||||
|
class MySQL_API SessionImpl: public Poco::Data::AbstractSessionImpl<SessionImpl>
|
||||||
|
/// Implements SessionImpl interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const std::string MYSQL_READ_UNCOMMITTED;
|
||||||
|
static const std::string MYSQL_READ_COMMITTED;
|
||||||
|
static const std::string MYSQL_REPEATABLE_READ;
|
||||||
|
static const std::string MYSQL_SERIALIZABLE;
|
||||||
|
|
||||||
|
SessionImpl(const std::string& connectionString,
|
||||||
|
std::size_t loginTimeout = LOGIN_TIMEOUT_DEFAULT);
|
||||||
|
/// Creates the SessionImpl. Opens a connection to the database
|
||||||
|
///
|
||||||
|
/// Connection string format:
|
||||||
|
/// <str> == <assignment> | <assignment> ';' <str>
|
||||||
|
/// <assignment> == <name> '=' <value>
|
||||||
|
/// <name> == 'host' | 'port' | 'user' | 'password' | 'db' } 'compress' | 'auto-reconnect'
|
||||||
|
/// <value> == [~;]*
|
||||||
|
///
|
||||||
|
/// for compress and auto-reconnect correct values are true/false
|
||||||
|
/// for port - numeric in decimal notation
|
||||||
|
///
|
||||||
|
|
||||||
|
~SessionImpl();
|
||||||
|
/// Destroys the SessionImpl.
|
||||||
|
|
||||||
|
Poco::Data::StatementImpl* createStatementImpl();
|
||||||
|
/// Returns an MySQL StatementImpl
|
||||||
|
|
||||||
|
void open(const std::string& connection = "");
|
||||||
|
/// Opens a connection to the database.
|
||||||
|
|
||||||
|
void close();
|
||||||
|
/// Closes the connection.
|
||||||
|
|
||||||
|
bool isConnected();
|
||||||
|
/// Returns true if connected, false otherwise.
|
||||||
|
|
||||||
|
void setConnectionTimeout(std::size_t timeout);
|
||||||
|
/// Sets the session connection timeout value.
|
||||||
|
|
||||||
|
std::size_t getConnectionTimeout();
|
||||||
|
/// Returns the session connection timeout value.
|
||||||
|
|
||||||
|
void begin();
|
||||||
|
/// Starts a transaction
|
||||||
|
|
||||||
|
void commit();
|
||||||
|
/// Commits and ends a transaction
|
||||||
|
|
||||||
|
void rollback();
|
||||||
|
/// Aborts a transaction
|
||||||
|
|
||||||
|
bool canTransact();
|
||||||
|
/// Returns true if session has transaction capabilities.
|
||||||
|
|
||||||
|
bool isTransaction();
|
||||||
|
/// Returns true iff a transaction is a transaction is in progress, false otherwise.
|
||||||
|
|
||||||
|
void setTransactionIsolation(Poco::UInt32 ti);
|
||||||
|
/// Sets the transaction isolation level.
|
||||||
|
|
||||||
|
Poco::UInt32 getTransactionIsolation();
|
||||||
|
/// Returns the transaction isolation level.
|
||||||
|
|
||||||
|
bool hasTransactionIsolation(Poco::UInt32 ti);
|
||||||
|
/// Returns true iff the transaction isolation level corresponding
|
||||||
|
/// to the supplied bitmask is supported.
|
||||||
|
|
||||||
|
bool isTransactionIsolation(Poco::UInt32 ti);
|
||||||
|
/// Returns true iff the transaction isolation level corresponds
|
||||||
|
/// to the supplied bitmask.
|
||||||
|
|
||||||
|
void autoCommit(const std::string&, bool val);
|
||||||
|
/// Sets autocommit property for the session.
|
||||||
|
|
||||||
|
bool isAutoCommit(const std::string& name="");
|
||||||
|
/// Returns autocommit property value.
|
||||||
|
|
||||||
|
void setInsertId(const std::string&, const Poco::Any&);
|
||||||
|
/// Try to set insert id - do nothing.
|
||||||
|
|
||||||
|
Poco::Any getInsertId(const std::string&);
|
||||||
|
/// Get insert id
|
||||||
|
|
||||||
|
SessionHandle& handle();
|
||||||
|
// Get handle
|
||||||
|
|
||||||
|
const std::string& connectorName() const;
|
||||||
|
/// Returns the name of the connector.
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T& getValue(MYSQL_BIND* pResult, T& val)
|
||||||
|
{
|
||||||
|
return val = *((T*) pResult->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T& getSetting(const std::string& name, T& val)
|
||||||
|
/// Returns required setting.
|
||||||
|
/// Limited to one setting at a time.
|
||||||
|
{
|
||||||
|
StatementExecutor ex(_handle);
|
||||||
|
ResultMetadata metadata;
|
||||||
|
metadata.reset();
|
||||||
|
ex.prepare(Poco::format("SELECT @@%s", name));
|
||||||
|
metadata.init(ex);
|
||||||
|
|
||||||
|
if (metadata.columnsReturned() > 0)
|
||||||
|
ex.bindResult(metadata.row());
|
||||||
|
else
|
||||||
|
throw InvalidArgumentException("No data returned.");
|
||||||
|
|
||||||
|
ex.execute(); ex.fetch();
|
||||||
|
MYSQL_BIND* pResult = metadata.row();
|
||||||
|
return getValue<T>(pResult, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string _connector;
|
||||||
|
SessionHandle _handle;
|
||||||
|
bool _connected;
|
||||||
|
bool _inTransaction;
|
||||||
|
std::size_t _timeout;
|
||||||
|
Poco::FastMutex _mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline bool SessionImpl::canTransact()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void SessionImpl::setInsertId(const std::string&, const Poco::Any&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Poco::Any SessionImpl::getInsertId(const std::string&)
|
||||||
|
{
|
||||||
|
return Poco::Any(Poco::UInt64(mysql_insert_id(_handle)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline SessionHandle& SessionImpl::handle()
|
||||||
|
{
|
||||||
|
return _handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const std::string& SessionImpl::connectorName() const
|
||||||
|
{
|
||||||
|
return _connector;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool SessionImpl::isTransaction()
|
||||||
|
{
|
||||||
|
return _inTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool SessionImpl::isTransactionIsolation(Poco::UInt32 ti)
|
||||||
|
{
|
||||||
|
return getTransactionIsolation() == ti;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool SessionImpl::isConnected()
|
||||||
|
{
|
||||||
|
return _connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::size_t SessionImpl::getConnectionTimeout()
|
||||||
|
{
|
||||||
|
return _timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline std::string& SessionImpl::getValue(MYSQL_BIND* pResult, std::string& val)
|
||||||
|
{
|
||||||
|
val.assign((char*) pResult->buffer, pResult->buffer_length);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} } } // namespace Poco::Data::MySQL
|
||||||
|
|
||||||
|
|
||||||
|
#endif // Data_MySQL_SessionImpl_INCLUDED
|
||||||
97
src/cpp/MySQL/Poco/StatementExecutor.h
Normal file
97
src/cpp/MySQL/Poco/StatementExecutor.h
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
//
|
||||||
|
// StatementExecutor.h
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: StatementExecutor
|
||||||
|
//
|
||||||
|
// Definition of the StatementExecutor class.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Data_MySQL_StatementHandle_INCLUDED
|
||||||
|
#define Data_MySQL_StatementHandle_INCLUDED
|
||||||
|
|
||||||
|
#include <mysql.h>
|
||||||
|
#include "Poco/Data/MySQL/MySQLException.h"
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
class StatementExecutor
|
||||||
|
/// MySQL statement executor.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum State
|
||||||
|
{
|
||||||
|
STMT_INITED,
|
||||||
|
STMT_COMPILED,
|
||||||
|
STMT_EXECUTED
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit StatementExecutor(MYSQL* mysql);
|
||||||
|
/// Creates the StatementExecutor.
|
||||||
|
|
||||||
|
~StatementExecutor();
|
||||||
|
/// Destroys the StatementExecutor.
|
||||||
|
|
||||||
|
int state() const;
|
||||||
|
/// Returns the current state.
|
||||||
|
|
||||||
|
void prepare(const std::string& query);
|
||||||
|
/// Prepares the statement for execution.
|
||||||
|
|
||||||
|
void bindParams(MYSQL_BIND* params, std::size_t count);
|
||||||
|
/// Binds the params.
|
||||||
|
|
||||||
|
void bindResult(MYSQL_BIND* result);
|
||||||
|
/// Binds result.
|
||||||
|
|
||||||
|
void execute();
|
||||||
|
/// Executes the statement.
|
||||||
|
|
||||||
|
bool fetch();
|
||||||
|
/// Fetches the data.
|
||||||
|
|
||||||
|
bool fetchColumn(std::size_t n, MYSQL_BIND *bind);
|
||||||
|
/// Fetches the column.
|
||||||
|
|
||||||
|
int getAffectedRowCount() const;
|
||||||
|
|
||||||
|
operator MYSQL_STMT* ();
|
||||||
|
/// Cast operator to native handle type.
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
StatementExecutor(const StatementExecutor&);
|
||||||
|
StatementExecutor& operator=(const StatementExecutor&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
MYSQL* _pSessionHandle;
|
||||||
|
MYSQL_STMT* _pHandle;
|
||||||
|
int _state;
|
||||||
|
int _affectedRowCount;
|
||||||
|
std::string _query;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
|
||||||
|
inline StatementExecutor::operator MYSQL_STMT* ()
|
||||||
|
{
|
||||||
|
return _pHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // Data_MySQL_StatementHandle_INCLUDED
|
||||||
79
src/cpp/MySQL/Poco/Utility.h
Normal file
79
src/cpp/MySQL/Poco/Utility.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
//
|
||||||
|
// Utility.h
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: Utility
|
||||||
|
//
|
||||||
|
// Definition of Utility.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MySQL_Utility_INCLUDED
|
||||||
|
#define MySQL_Utility_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/MySQL.h"
|
||||||
|
#include "Poco/Data/Session.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct st_mysql;
|
||||||
|
typedef struct st_mysql MYSQL;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
|
||||||
|
class MySQL_API Utility
|
||||||
|
/// Various utility functions for MySQL.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static std::string serverInfo(MYSQL* pHandle);
|
||||||
|
/// Returns server info.
|
||||||
|
|
||||||
|
static std::string serverInfo(Poco::Data::Session& session);
|
||||||
|
/// Returns server info.
|
||||||
|
|
||||||
|
static unsigned long serverVersion(MYSQL* pHandle);
|
||||||
|
/// Returns server version.
|
||||||
|
|
||||||
|
static unsigned long serverVersion(Poco::Data::Session& session);
|
||||||
|
/// Returns server version.
|
||||||
|
|
||||||
|
static std::string hostInfo(MYSQL* pHandle);
|
||||||
|
/// Returns host info.
|
||||||
|
|
||||||
|
static std::string hostInfo(Poco::Data::Session& session);
|
||||||
|
/// Returns host info.
|
||||||
|
|
||||||
|
static bool hasMicrosecond();
|
||||||
|
/// Rturns true if microseconds are suported.
|
||||||
|
|
||||||
|
static MYSQL* handle(Poco::Data::Session& session);
|
||||||
|
/// Returns native MySQL handle for the session.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
inline MYSQL* Utility::handle(Session& session)
|
||||||
|
{
|
||||||
|
return Poco::AnyCast<MYSQL*>(session.getProperty("handle"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} } } // namespace Poco::Data::MySQL
|
||||||
|
|
||||||
|
|
||||||
|
#endif // MySQL_Utility_INCLUDED
|
||||||
239
src/cpp/MySQL/ResultMetadata.cpp
Normal file
239
src/cpp/MySQL/ResultMetadata.cpp
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
//
|
||||||
|
// MySQLException.cpp
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: ResultMetadata
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/ResultMetadata.h"
|
||||||
|
#include "Poco/Data/MySQL/MySQLException.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class ResultMetadataHandle
|
||||||
|
/// Simple exception-safe wrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit ResultMetadataHandle(MYSQL_STMT* stmt)
|
||||||
|
{
|
||||||
|
h = mysql_stmt_result_metadata(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ResultMetadataHandle()
|
||||||
|
{
|
||||||
|
if (h)
|
||||||
|
{
|
||||||
|
mysql_free_result(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator MYSQL_RES* ()
|
||||||
|
{
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
MYSQL_RES* h;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::size_t fieldSize(const MYSQL_FIELD& field)
|
||||||
|
/// Convert field MySQL-type and field MySQL-length to actual field length
|
||||||
|
{
|
||||||
|
switch (field.type)
|
||||||
|
{
|
||||||
|
case MYSQL_TYPE_TINY: return sizeof(char);
|
||||||
|
case MYSQL_TYPE_SHORT: return sizeof(short);
|
||||||
|
case MYSQL_TYPE_INT24:
|
||||||
|
case MYSQL_TYPE_LONG: return sizeof(Poco::Int32);
|
||||||
|
case MYSQL_TYPE_FLOAT: return sizeof(float);
|
||||||
|
case MYSQL_TYPE_DOUBLE: return sizeof(double);
|
||||||
|
case MYSQL_TYPE_LONGLONG: return sizeof(Poco::Int64);
|
||||||
|
|
||||||
|
case MYSQL_TYPE_DATE:
|
||||||
|
case MYSQL_TYPE_TIME:
|
||||||
|
case MYSQL_TYPE_DATETIME:
|
||||||
|
return sizeof(MYSQL_TIME);
|
||||||
|
|
||||||
|
case MYSQL_TYPE_DECIMAL:
|
||||||
|
case MYSQL_TYPE_NEWDECIMAL:
|
||||||
|
case MYSQL_TYPE_STRING:
|
||||||
|
case MYSQL_TYPE_VAR_STRING:
|
||||||
|
case MYSQL_TYPE_TINY_BLOB:
|
||||||
|
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||||
|
case MYSQL_TYPE_LONG_BLOB:
|
||||||
|
case MYSQL_TYPE_BLOB:
|
||||||
|
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
|
||||||
|
{
|
||||||
|
bool unsig = ((field.flags & UNSIGNED_FLAG) == UNSIGNED_FLAG);
|
||||||
|
|
||||||
|
switch (field.type)
|
||||||
|
{
|
||||||
|
case MYSQL_TYPE_TINY:
|
||||||
|
if (unsig) return Poco::Data::MetaColumn::FDT_UINT8;
|
||||||
|
return Poco::Data::MetaColumn::FDT_INT8;
|
||||||
|
|
||||||
|
case MYSQL_TYPE_SHORT:
|
||||||
|
if (unsig) return Poco::Data::MetaColumn::FDT_UINT16;
|
||||||
|
return Poco::Data::MetaColumn::FDT_INT16;
|
||||||
|
|
||||||
|
case MYSQL_TYPE_INT24:
|
||||||
|
case MYSQL_TYPE_LONG:
|
||||||
|
if (unsig) return Poco::Data::MetaColumn::FDT_UINT32;
|
||||||
|
return Poco::Data::MetaColumn::FDT_INT32;
|
||||||
|
|
||||||
|
case MYSQL_TYPE_FLOAT:
|
||||||
|
return Poco::Data::MetaColumn::FDT_FLOAT;
|
||||||
|
|
||||||
|
case MYSQL_TYPE_DECIMAL:
|
||||||
|
case MYSQL_TYPE_NEWDECIMAL:
|
||||||
|
case MYSQL_TYPE_DOUBLE:
|
||||||
|
return Poco::Data::MetaColumn::FDT_DOUBLE;
|
||||||
|
|
||||||
|
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:
|
||||||
|
return Poco::Data::MetaColumn::FDT_TIMESTAMP;
|
||||||
|
|
||||||
|
case MYSQL_TYPE_STRING:
|
||||||
|
case MYSQL_TYPE_VAR_STRING:
|
||||||
|
return Poco::Data::MetaColumn::FDT_STRING;
|
||||||
|
|
||||||
|
case MYSQL_TYPE_TINY_BLOB:
|
||||||
|
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||||
|
case MYSQL_TYPE_LONG_BLOB:
|
||||||
|
case MYSQL_TYPE_BLOB:
|
||||||
|
return Poco::Data::MetaColumn::FDT_BLOB;
|
||||||
|
default:
|
||||||
|
return Poco::Data::MetaColumn::FDT_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
void ResultMetadata::reset()
|
||||||
|
{
|
||||||
|
_columns.resize(0);
|
||||||
|
_row.resize(0);
|
||||||
|
_buffer.resize(0);
|
||||||
|
_lengths.resize(0);
|
||||||
|
_isNull.resize(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
std::size_t size = fieldSize(fields[i]);
|
||||||
|
if (size == 0xFFFFFFFF) size = 0;
|
||||||
|
|
||||||
|
_columns.push_back(MetaColumn(
|
||||||
|
i, // position
|
||||||
|
fields[i].name, // name
|
||||||
|
fieldType(fields[i]), // type
|
||||||
|
size, // length
|
||||||
|
0, // TODO: precision
|
||||||
|
!IS_NOT_NULL(fields[i].flags) // nullable
|
||||||
|
));
|
||||||
|
|
||||||
|
commonSize += _columns[i].length();
|
||||||
|
}}
|
||||||
|
|
||||||
|
_buffer.resize(commonSize);
|
||||||
|
_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());
|
||||||
|
_row[i].buffer_type = fields[i].type;
|
||||||
|
_row[i].buffer_length = len;
|
||||||
|
_row[i].buffer = (len > 0) ? (&_buffer[0] + offset) : 0;
|
||||||
|
_row[i].length = &_lengths[i];
|
||||||
|
_row[i].is_null = &_isNull[i];
|
||||||
|
_row[i].is_unsigned = (fields[i].flags & UNSIGNED_FLAG) > 0;
|
||||||
|
|
||||||
|
offset += _row[i].buffer_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t ResultMetadata::columnsReturned() const
|
||||||
|
{
|
||||||
|
return static_cast<std::size_t>(_columns.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
const MetaColumn& ResultMetadata::metaColumn(std::size_t pos) const
|
||||||
|
{
|
||||||
|
return _columns[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
MYSQL_BIND* ResultMetadata::row()
|
||||||
|
{
|
||||||
|
return &_row[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t ResultMetadata::length(std::size_t pos) const
|
||||||
|
{
|
||||||
|
return _lengths[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned char* ResultMetadata::rawData(std::size_t pos) const
|
||||||
|
{
|
||||||
|
return reinterpret_cast<const unsigned char*>(_row[pos].buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResultMetadata::isNull(std::size_t pos) const
|
||||||
|
{
|
||||||
|
return (_isNull[pos] != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}}} // namespace Poco::Data::MySQL
|
||||||
179
src/cpp/MySQL/SessionHandle.cpp
Normal file
179
src/cpp/MySQL/SessionHandle.cpp
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
//
|
||||||
|
// SesssionHandle.cpp
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: SessionHandle
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/SessionHandle.h"
|
||||||
|
#include "Poco/Data/DataException.h"
|
||||||
|
#include "Poco/SingletonHolder.h"
|
||||||
|
#ifdef POCO_OS_FAMILY_UNIX
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define POCO_MYSQL_VERSION_NUMBER ((NDB_VERSION_MAJOR<<16) | (NDB_VERSION_MINOR<<8) | (NDB_VERSION_BUILD&0xFF))
|
||||||
|
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef POCO_OS_FAMILY_UNIX
|
||||||
|
class ThreadCleanupHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ThreadCleanupHelper()
|
||||||
|
{
|
||||||
|
if (pthread_key_create(&_key, &ThreadCleanupHelper::cleanup) != 0)
|
||||||
|
throw Poco::SystemException("cannot create TLS key for mysql cleanup");
|
||||||
|
}
|
||||||
|
|
||||||
|
void init()
|
||||||
|
{
|
||||||
|
if (pthread_setspecific(_key, reinterpret_cast<void*>(1)))
|
||||||
|
throw Poco::SystemException("cannot set TLS key for mysql cleanup");
|
||||||
|
}
|
||||||
|
|
||||||
|
static ThreadCleanupHelper& instance()
|
||||||
|
{
|
||||||
|
return *_sh.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cleanup(void* data)
|
||||||
|
{
|
||||||
|
mysql_thread_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
pthread_key_t _key;
|
||||||
|
static Poco::SingletonHolder<ThreadCleanupHelper> _sh;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Poco::SingletonHolder<ThreadCleanupHelper> ThreadCleanupHelper::_sh;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
SessionHandle::SessionHandle(MYSQL* mysql): _pHandle(0)
|
||||||
|
{
|
||||||
|
init(mysql);
|
||||||
|
#ifdef POCO_OS_FAMILY_UNIX
|
||||||
|
ThreadCleanupHelper::instance().init();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionHandle::init(MYSQL* mysql)
|
||||||
|
{
|
||||||
|
if (!_pHandle)
|
||||||
|
{
|
||||||
|
_pHandle = mysql_init(mysql);
|
||||||
|
if (!_pHandle)
|
||||||
|
throw ConnectionException("mysql_init error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SessionHandle::~SessionHandle()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionHandle::options(mysql_option opt)
|
||||||
|
{
|
||||||
|
if (mysql_options(_pHandle, opt, 0) != 0)
|
||||||
|
throw ConnectionException("mysql_options error", _pHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionHandle::options(mysql_option opt, bool b)
|
||||||
|
{
|
||||||
|
my_bool tmp = b;
|
||||||
|
if (mysql_options(_pHandle, opt, &tmp) != 0)
|
||||||
|
throw ConnectionException("mysql_options error", _pHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionHandle::options(mysql_option opt, const char* c)
|
||||||
|
{
|
||||||
|
if (mysql_options(_pHandle, opt, c) != 0)
|
||||||
|
throw ConnectionException("mysql_options error", _pHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionHandle::options(mysql_option opt, unsigned int i)
|
||||||
|
{
|
||||||
|
#if (POCO_MYSQL_VERSION_NUMBER < 0x050108)
|
||||||
|
const char* tmp = (const char *)&i;
|
||||||
|
#else
|
||||||
|
const void* tmp = (const void *)&i;
|
||||||
|
#endif
|
||||||
|
if (mysql_options(_pHandle, opt, tmp) != 0)
|
||||||
|
throw ConnectionException("mysql_options error", _pHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionHandle::connect(const char* host, const char* user, const char* password, const char* db, unsigned int port)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_MYSQL_REAL_CONNECT
|
||||||
|
if (!mysql_real_connect(_pHandle, host, user, password, db, port, 0, 0))
|
||||||
|
throw ConnectionFailedException(mysql_error(_pHandle));
|
||||||
|
#else
|
||||||
|
if (!mysql_connect(_pHandle, host, user, password))
|
||||||
|
throw ConnectionFailedException(mysql_error(_pHandle))
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionHandle::close()
|
||||||
|
{
|
||||||
|
if (_pHandle)
|
||||||
|
{
|
||||||
|
mysql_close(_pHandle);
|
||||||
|
_pHandle = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionHandle::startTransaction()
|
||||||
|
{
|
||||||
|
int rc = mysql_autocommit(_pHandle, false);
|
||||||
|
if (rc != 0)
|
||||||
|
{
|
||||||
|
// retry if connection lost
|
||||||
|
int err = mysql_errno(_pHandle);
|
||||||
|
if (err == 2006 /* CR_SERVER_GONE_ERROR */ || err == 2013 /* CR_SERVER_LOST */)
|
||||||
|
{
|
||||||
|
rc = mysql_autocommit(_pHandle, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rc != 0) throw TransactionException("Start transaction failed.", _pHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionHandle::commit()
|
||||||
|
{
|
||||||
|
if (mysql_commit(_pHandle) != 0)
|
||||||
|
throw TransactionException("Commit failed.", _pHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionHandle::rollback()
|
||||||
|
{
|
||||||
|
if (mysql_rollback(_pHandle) != 0)
|
||||||
|
throw TransactionException("Rollback failed.", _pHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}}} // Poco::Data::MySQL
|
||||||
277
src/cpp/MySQL/SessionImpl.cpp
Normal file
277
src/cpp/MySQL/SessionImpl.cpp
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
//
|
||||||
|
// SessionImpl.cpp
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: SessionImpl
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/SessionImpl.h"
|
||||||
|
#include "Poco/Data/MySQL/MySQLStatementImpl.h"
|
||||||
|
#include "Poco/Data/Session.h"
|
||||||
|
#include "Poco/NumberParser.h"
|
||||||
|
#include "Poco/String.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
std::string copyStripped(std::string::const_iterator from, std::string::const_iterator to)
|
||||||
|
{
|
||||||
|
// skip leading spaces
|
||||||
|
while ((from != to) && isspace(*from)) from++;
|
||||||
|
// skip trailing spaces
|
||||||
|
while ((from != to) && isspace(*(to - 1))) to--;
|
||||||
|
|
||||||
|
return std::string(from, to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
|
||||||
|
const std::string SessionImpl::MYSQL_READ_UNCOMMITTED = "READ UNCOMMITTED";
|
||||||
|
const std::string SessionImpl::MYSQL_READ_COMMITTED = "READ COMMITTED";
|
||||||
|
const std::string SessionImpl::MYSQL_REPEATABLE_READ = "REPEATABLE READ";
|
||||||
|
const std::string SessionImpl::MYSQL_SERIALIZABLE = "SERIALIZABLE";
|
||||||
|
|
||||||
|
|
||||||
|
SessionImpl::SessionImpl(const std::string& connectionString, std::size_t loginTimeout) :
|
||||||
|
Poco::Data::AbstractSessionImpl<SessionImpl>(connectionString, loginTimeout),
|
||||||
|
_handle(0),
|
||||||
|
_connected(false),
|
||||||
|
_inTransaction(false)
|
||||||
|
{
|
||||||
|
addProperty("insertId", &SessionImpl::setInsertId, &SessionImpl::getInsertId);
|
||||||
|
setProperty("handle", static_cast<MYSQL*>(_handle));
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionImpl::open(const std::string& connect)
|
||||||
|
{
|
||||||
|
if (connect != connectionString())
|
||||||
|
{
|
||||||
|
if (isConnected())
|
||||||
|
throw InvalidAccessException("Session already connected");
|
||||||
|
|
||||||
|
if (!connect.empty())
|
||||||
|
setConnectionString(connect);
|
||||||
|
}
|
||||||
|
|
||||||
|
poco_assert_dbg (!connectionString().empty());
|
||||||
|
|
||||||
|
_handle.init();
|
||||||
|
|
||||||
|
unsigned int timeout = static_cast<unsigned int>(getLoginTimeout());
|
||||||
|
_handle.options(MYSQL_OPT_CONNECT_TIMEOUT, timeout);
|
||||||
|
|
||||||
|
std::map<std::string, std::string> options;
|
||||||
|
|
||||||
|
// Default values
|
||||||
|
options["host"] = "localhost";
|
||||||
|
options["port"] = "3306";
|
||||||
|
options["user"] = "";
|
||||||
|
options["password"] = "";
|
||||||
|
options["db"] = "";
|
||||||
|
options["compress"] = "";
|
||||||
|
options["auto-reconnect"] = "";
|
||||||
|
options["secure-auth"] = "";
|
||||||
|
options["character-set"] = "utf8";
|
||||||
|
|
||||||
|
const std::string& connString = connectionString();
|
||||||
|
for (std::string::const_iterator start = connString.begin();;)
|
||||||
|
{
|
||||||
|
std::string::const_iterator finish = std::find(start, connString.end(), ';');
|
||||||
|
std::string::const_iterator middle = std::find(start, finish, '=');
|
||||||
|
|
||||||
|
if (middle == finish)
|
||||||
|
throw MySQLException("create session: bad connection string format, can not find '='");
|
||||||
|
|
||||||
|
options[copyStripped(start, middle)] = copyStripped(middle + 1, finish);
|
||||||
|
|
||||||
|
if ((finish == connString.end()) || (finish + 1 == connString.end())) break;
|
||||||
|
|
||||||
|
start = finish + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options["user"].empty())
|
||||||
|
throw MySQLException("create session: specify user name");
|
||||||
|
|
||||||
|
const char * db = NULL;
|
||||||
|
if (!options["db"].empty())
|
||||||
|
db = options["db"].c_str();
|
||||||
|
|
||||||
|
unsigned int port = 0;
|
||||||
|
if (!NumberParser::tryParseUnsigned(options["port"], port) || 0 == port || port > 65535)
|
||||||
|
throw MySQLException("create session: specify correct port (numeric in decimal notation)");
|
||||||
|
|
||||||
|
if (options["compress"] == "true")
|
||||||
|
_handle.options(MYSQL_OPT_COMPRESS);
|
||||||
|
else if (options["compress"] == "false")
|
||||||
|
;
|
||||||
|
else if (!options["compress"].empty())
|
||||||
|
throw MySQLException("create session: specify correct compress option (true or false) or skip it");
|
||||||
|
|
||||||
|
if (options["auto-reconnect"] == "true")
|
||||||
|
_handle.options(MYSQL_OPT_RECONNECT, true);
|
||||||
|
else if (options["auto-reconnect"] == "false")
|
||||||
|
_handle.options(MYSQL_OPT_RECONNECT, false);
|
||||||
|
else if (!options["auto-reconnect"].empty())
|
||||||
|
throw MySQLException("create session: specify correct auto-reconnect option (true or false) or skip it");
|
||||||
|
|
||||||
|
if (options["secure-auth"] == "true")
|
||||||
|
_handle.options(MYSQL_SECURE_AUTH, true);
|
||||||
|
else if (options["secure-auth"] == "false")
|
||||||
|
_handle.options(MYSQL_SECURE_AUTH, false);
|
||||||
|
else if (!options["secure-auth"].empty())
|
||||||
|
throw MySQLException("create session: specify correct secure-auth option (true or false) or skip it");
|
||||||
|
|
||||||
|
if (!options["character-set"].empty())
|
||||||
|
_handle.options(MYSQL_SET_CHARSET_NAME, options["character-set"].c_str());
|
||||||
|
|
||||||
|
// Real connect
|
||||||
|
_handle.connect(options["host"].c_str(),
|
||||||
|
options["user"].c_str(),
|
||||||
|
options["password"].c_str(),
|
||||||
|
db,
|
||||||
|
port);
|
||||||
|
|
||||||
|
addFeature("autoCommit",
|
||||||
|
&SessionImpl::autoCommit,
|
||||||
|
&SessionImpl::isAutoCommit);
|
||||||
|
|
||||||
|
_connected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SessionImpl::~SessionImpl()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Poco::Data::StatementImpl* SessionImpl::createStatementImpl()
|
||||||
|
{
|
||||||
|
return new MySQLStatementImpl(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionImpl::begin()
|
||||||
|
{
|
||||||
|
Poco::FastMutex::ScopedLock l(_mutex);
|
||||||
|
|
||||||
|
if (_inTransaction)
|
||||||
|
throw Poco::InvalidAccessException("Already in transaction.");
|
||||||
|
|
||||||
|
_handle.startTransaction();
|
||||||
|
_inTransaction = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionImpl::commit()
|
||||||
|
{
|
||||||
|
_handle.commit();
|
||||||
|
_inTransaction = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionImpl::rollback()
|
||||||
|
{
|
||||||
|
_handle.rollback();
|
||||||
|
_inTransaction = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionImpl::autoCommit(const std::string&, bool val)
|
||||||
|
{
|
||||||
|
StatementExecutor ex(_handle);
|
||||||
|
ex.prepare(Poco::format("SET autocommit=%d", val ? 1 : 0));
|
||||||
|
ex.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SessionImpl::isAutoCommit(const std::string&)
|
||||||
|
{
|
||||||
|
int ac = 0;
|
||||||
|
return 1 == getSetting("autocommit", ac);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionImpl::setTransactionIsolation(Poco::UInt32 ti)
|
||||||
|
{
|
||||||
|
std::string isolation;
|
||||||
|
switch (ti)
|
||||||
|
{
|
||||||
|
case Session::TRANSACTION_READ_UNCOMMITTED:
|
||||||
|
isolation = MYSQL_READ_UNCOMMITTED; break;
|
||||||
|
case Session::TRANSACTION_READ_COMMITTED:
|
||||||
|
isolation = MYSQL_READ_COMMITTED; break;
|
||||||
|
case Session::TRANSACTION_REPEATABLE_READ:
|
||||||
|
isolation = MYSQL_REPEATABLE_READ; break;
|
||||||
|
case Session::TRANSACTION_SERIALIZABLE:
|
||||||
|
isolation = MYSQL_SERIALIZABLE; break;
|
||||||
|
default:
|
||||||
|
throw Poco::InvalidArgumentException("setTransactionIsolation()");
|
||||||
|
}
|
||||||
|
|
||||||
|
StatementExecutor ex(_handle);
|
||||||
|
ex.prepare(Poco::format("SET SESSION TRANSACTION ISOLATION LEVEL %s", isolation));
|
||||||
|
ex.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Poco::UInt32 SessionImpl::getTransactionIsolation()
|
||||||
|
{
|
||||||
|
std::string isolation;
|
||||||
|
getSetting("tx_isolation", isolation);
|
||||||
|
Poco::replaceInPlace(isolation, "-", " ");
|
||||||
|
if (MYSQL_READ_UNCOMMITTED == isolation)
|
||||||
|
return Session::TRANSACTION_READ_UNCOMMITTED;
|
||||||
|
else if (MYSQL_READ_COMMITTED == isolation)
|
||||||
|
return Session::TRANSACTION_READ_COMMITTED;
|
||||||
|
else if (MYSQL_REPEATABLE_READ == isolation)
|
||||||
|
return Session::TRANSACTION_REPEATABLE_READ;
|
||||||
|
else if (MYSQL_SERIALIZABLE == isolation)
|
||||||
|
return Session::TRANSACTION_SERIALIZABLE;
|
||||||
|
|
||||||
|
throw InvalidArgumentException("getTransactionIsolation()");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SessionImpl::hasTransactionIsolation(Poco::UInt32 ti)
|
||||||
|
{
|
||||||
|
return Session::TRANSACTION_READ_UNCOMMITTED == ti ||
|
||||||
|
Session::TRANSACTION_READ_COMMITTED == ti ||
|
||||||
|
Session::TRANSACTION_REPEATABLE_READ == ti ||
|
||||||
|
Session::TRANSACTION_SERIALIZABLE == ti;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionImpl::close()
|
||||||
|
{
|
||||||
|
if (_connected)
|
||||||
|
{
|
||||||
|
_handle.close();
|
||||||
|
_connected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SessionImpl::setConnectionTimeout(std::size_t timeout)
|
||||||
|
{
|
||||||
|
_handle.options(MYSQL_OPT_READ_TIMEOUT, static_cast<unsigned int>(timeout));
|
||||||
|
_handle.options(MYSQL_OPT_WRITE_TIMEOUT, static_cast<unsigned int>(timeout));
|
||||||
|
_timeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}}}
|
||||||
148
src/cpp/MySQL/StatementExecutor.cpp
Normal file
148
src/cpp/MySQL/StatementExecutor.cpp
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
//
|
||||||
|
// StatementExecutor.cpp
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: StatementExecutor
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include <mysql.h>
|
||||||
|
#include "Poco/Data/MySQL/StatementExecutor.h"
|
||||||
|
#include "Poco/Format.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
|
||||||
|
StatementExecutor::StatementExecutor(MYSQL* mysql)
|
||||||
|
: _pSessionHandle(mysql)
|
||||||
|
, _affectedRowCount(0)
|
||||||
|
{
|
||||||
|
if (!(_pHandle = mysql_stmt_init(mysql)))
|
||||||
|
throw StatementException("mysql_stmt_init error");
|
||||||
|
|
||||||
|
_state = STMT_INITED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StatementExecutor::~StatementExecutor()
|
||||||
|
{
|
||||||
|
mysql_stmt_close(_pHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int StatementExecutor::state() const
|
||||||
|
{
|
||||||
|
return _state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StatementExecutor::prepare(const std::string& query)
|
||||||
|
{
|
||||||
|
if (_state >= STMT_COMPILED)
|
||||||
|
{
|
||||||
|
_state = STMT_COMPILED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc = mysql_stmt_prepare(_pHandle, query.c_str(), static_cast<unsigned int>(query.length()));
|
||||||
|
if (rc != 0)
|
||||||
|
{
|
||||||
|
// retry if connection lost
|
||||||
|
int err = mysql_errno(_pSessionHandle);
|
||||||
|
if (err == 2006 /* CR_SERVER_GONE_ERROR */ || err == 2013 /* CR_SERVER_LOST */)
|
||||||
|
{
|
||||||
|
rc = mysql_stmt_prepare(_pHandle, query.c_str(), static_cast<unsigned int>(query.length()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rc != 0) throw StatementException("mysql_stmt_prepare error", _pHandle, query);
|
||||||
|
|
||||||
|
_query = query;
|
||||||
|
_state = STMT_COMPILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StatementExecutor::bindParams(MYSQL_BIND* params, std::size_t count)
|
||||||
|
{
|
||||||
|
if (_state < STMT_COMPILED)
|
||||||
|
throw StatementException("Statement is not compiled yet");
|
||||||
|
|
||||||
|
if (count != mysql_stmt_param_count(_pHandle))
|
||||||
|
throw StatementException("wrong bind parameters count", 0, _query);
|
||||||
|
|
||||||
|
if (count == 0) return;
|
||||||
|
|
||||||
|
if (mysql_stmt_bind_param(_pHandle, params) != 0)
|
||||||
|
throw StatementException("mysql_stmt_bind_param() error ", _pHandle, _query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StatementExecutor::bindResult(MYSQL_BIND* result)
|
||||||
|
{
|
||||||
|
if (_state < STMT_COMPILED)
|
||||||
|
throw StatementException("Statement is not compiled yet");
|
||||||
|
|
||||||
|
if (mysql_stmt_bind_result(_pHandle, result) != 0)
|
||||||
|
throw StatementException("mysql_stmt_bind_result error ", _pHandle, _query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StatementExecutor::execute()
|
||||||
|
{
|
||||||
|
if (_state < STMT_COMPILED)
|
||||||
|
throw StatementException("Statement is not compiled yet");
|
||||||
|
|
||||||
|
if (mysql_stmt_execute(_pHandle) != 0)
|
||||||
|
throw StatementException("mysql_stmt_execute error", _pHandle, _query);
|
||||||
|
|
||||||
|
_state = STMT_EXECUTED;
|
||||||
|
|
||||||
|
my_ulonglong affectedRows = mysql_affected_rows(_pSessionHandle);
|
||||||
|
if (affectedRows != ((my_ulonglong) - 1))
|
||||||
|
_affectedRowCount = static_cast<std::size_t>(affectedRows); //Was really a DELETE, UPDATE or INSERT statement
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool StatementExecutor::fetch()
|
||||||
|
{
|
||||||
|
if (_state < STMT_EXECUTED)
|
||||||
|
throw StatementException("Statement is not executed yet");
|
||||||
|
|
||||||
|
int res = mysql_stmt_fetch(_pHandle);
|
||||||
|
|
||||||
|
// we have specified zero buffers for BLOBs, so DATA_TRUNCATED is normal in this case
|
||||||
|
if ((res != 0) && (res != MYSQL_NO_DATA) && (res != MYSQL_DATA_TRUNCATED))
|
||||||
|
throw StatementException("mysql_stmt_fetch error", _pHandle, _query);
|
||||||
|
|
||||||
|
return (res == 0) || (res == MYSQL_DATA_TRUNCATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool StatementExecutor::fetchColumn(std::size_t n, MYSQL_BIND *bind)
|
||||||
|
{
|
||||||
|
if (_state < STMT_EXECUTED)
|
||||||
|
throw StatementException("Statement is not executed yet");
|
||||||
|
|
||||||
|
int res = mysql_stmt_fetch_column(_pHandle, bind, static_cast<unsigned int>(n), 0);
|
||||||
|
|
||||||
|
if ((res != 0) && (res != MYSQL_NO_DATA))
|
||||||
|
throw StatementException(Poco::format("mysql_stmt_fetch_column(%z) error", n), _pHandle, _query);
|
||||||
|
|
||||||
|
return (res == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int StatementExecutor::getAffectedRowCount() const
|
||||||
|
{
|
||||||
|
return _affectedRowCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}}}
|
||||||
66
src/cpp/MySQL/Utility.cpp
Normal file
66
src/cpp/MySQL/Utility.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
//
|
||||||
|
// Utility.cpp
|
||||||
|
//
|
||||||
|
// Library: Data/MySQL
|
||||||
|
// Package: MySQL
|
||||||
|
// Module: Utility
|
||||||
|
//
|
||||||
|
// Implementation of Utility
|
||||||
|
//
|
||||||
|
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Data/MySQL/Utility.h"
|
||||||
|
#include <mysql.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Poco {
|
||||||
|
namespace Data {
|
||||||
|
namespace MySQL {
|
||||||
|
|
||||||
|
|
||||||
|
std::string Utility::serverInfo(MYSQL* pHandle)
|
||||||
|
{
|
||||||
|
std::string info(mysql_get_server_info(pHandle));
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string Utility::serverInfo(Session& session)
|
||||||
|
{
|
||||||
|
std::string info(mysql_get_server_info(handle(session)));
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long Utility::serverVersion(MYSQL* pHandle)
|
||||||
|
{
|
||||||
|
return mysql_get_server_version(pHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long Utility::serverVersion(Session& session)
|
||||||
|
{
|
||||||
|
return mysql_get_server_version(handle(session));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string Utility::hostInfo(MYSQL* pHandle)
|
||||||
|
{
|
||||||
|
std::string info(mysql_get_host_info(pHandle));
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string Utility::hostInfo(Session& session)
|
||||||
|
{
|
||||||
|
std::string info(mysql_get_host_info(handle(session)));
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} } } // namespace Poco::Data::MySQL
|
||||||
405
src/cpp/SingletonManager/ConnectionManager.cpp
Normal file
405
src/cpp/SingletonManager/ConnectionManager.cpp
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
#include "ConnectionManager.h"
|
||||||
|
#include "../Connections/MysqlConnection.h"
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
|
ConnectThread::ConnectThread(ConnectionManager* parent)
|
||||||
|
: Thread(true), initMysqlThread(false), mParent(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectThread::~ConnectThread()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConnectThread::ThreadFunction()
|
||||||
|
{
|
||||||
|
if (!initMysqlThread) {
|
||||||
|
if(mysql_thread_init()) {
|
||||||
|
printf("error by calling mysql thread init\n");
|
||||||
|
}
|
||||||
|
initMysqlThread = true;
|
||||||
|
}
|
||||||
|
mDataMutex.lock();
|
||||||
|
|
||||||
|
// clean up not longer used connections
|
||||||
|
while (mConnectionWaitingOnDestroy.size() > 0) {
|
||||||
|
auto con = mConnectionWaitingOnDestroy.front();
|
||||||
|
mConnectionWaitingOnDestroy.pop();
|
||||||
|
mDataMutex.unlock();
|
||||||
|
delete con;
|
||||||
|
mDataMutex.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// creating new connections
|
||||||
|
while(mConnectionsWaitingOnConnectCall.size() > 0) {
|
||||||
|
auto con = mConnectionsWaitingOnConnectCall.front();
|
||||||
|
mConnectionsWaitingOnConnectCall.pop();
|
||||||
|
mDataMutex.unlock();
|
||||||
|
if(!con->connect()) {
|
||||||
|
//printf("[ConnectThread::ThreadFunction] error connecting with type: %s\n",
|
||||||
|
//Connection::getConnectionTypeName(con->getType()));
|
||||||
|
};
|
||||||
|
mParent->markAsAvailable(con);
|
||||||
|
mParent->condSignal();
|
||||||
|
mDataMutex.lock();
|
||||||
|
}
|
||||||
|
mDataMutex.unlock();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectThread::cleanUpInThread()
|
||||||
|
{
|
||||||
|
if (initMysqlThread) {
|
||||||
|
mysql_thread_end();
|
||||||
|
initMysqlThread = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectThread::addConnectionConnect(Connection* connection)
|
||||||
|
{
|
||||||
|
mDataMutex.lock();
|
||||||
|
mConnectionsWaitingOnConnectCall.push(connection);
|
||||||
|
mDataMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ConnectThread::addConnectionDestroy(Connection* connection)
|
||||||
|
{
|
||||||
|
mDataMutex.lock();
|
||||||
|
mConnectionWaitingOnDestroy.push(connection);
|
||||||
|
mDataMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
// ConnectionManager
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
|
ConnectionManager* ConnectionManager::getInstance()
|
||||||
|
{
|
||||||
|
static ConnectionManager only;
|
||||||
|
return &only;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectionManager::ConnectionManager()
|
||||||
|
: mConnectionEstablishThread(this), mInitalized(true)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectionManager::~ConnectionManager()
|
||||||
|
{
|
||||||
|
if (mInitalized) {
|
||||||
|
deinitalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionManager::deinitalize()
|
||||||
|
{
|
||||||
|
lock();
|
||||||
|
mInitalized = false;
|
||||||
|
unlock();
|
||||||
|
|
||||||
|
mConnectionEstablishThread.exitThread();
|
||||||
|
|
||||||
|
for (auto it = mConnections.begin(); it != mConnections.end(); it++)
|
||||||
|
{
|
||||||
|
auto freeConnections = it->second->mFreeConnections;
|
||||||
|
while (freeConnections.size() > 0) {
|
||||||
|
delete freeConnections.top();
|
||||||
|
freeConnections.pop();
|
||||||
|
}
|
||||||
|
auto cfg_ptr = it->second->cfg_ptr;
|
||||||
|
cfg_ptr->removeRef();
|
||||||
|
if (cfg_ptr->getRef() <= 0) {
|
||||||
|
delete cfg_ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mConnections.clear();
|
||||||
|
mInitalized = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConnectionManager::addConnectionPool(DRSimpleResourcePtr<Config>* cfg_ptr)
|
||||||
|
{
|
||||||
|
if (!mInitalized) {
|
||||||
|
printf("[ConnectionManager::%s] not initialized any more\n", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((*cfg_ptr)->name == std::string("")) {
|
||||||
|
// getConnectionTypeName
|
||||||
|
ConnectionConfig* cfg = static_cast<ConnectionConfig*>((Config*)(*cfg_ptr));
|
||||||
|
(*cfg_ptr)->name = "Connect_";
|
||||||
|
(*cfg_ptr)->name += Connection::getConnectionTypeName(cfg->type);
|
||||||
|
if (cfg->type == CONN_MYSQL) {
|
||||||
|
DBConnectionConfig* db_cfg = static_cast<DBConnectionConfig*>((Config*)(*cfg_ptr));
|
||||||
|
(*cfg_ptr)->name += "_";
|
||||||
|
(*cfg_ptr)->name += db_cfg->db;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DHASH id = (*cfg_ptr)->getHash();
|
||||||
|
|
||||||
|
// check if collision
|
||||||
|
lock();
|
||||||
|
if (!mInitalized) {
|
||||||
|
printf("[ConnectionManager::%s] not initialized any more\n", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = mConnections.find(id);
|
||||||
|
if (it != mConnections.end()) {
|
||||||
|
unlock();
|
||||||
|
if ((*it->second->cfg_ptr)->name == (*cfg_ptr)->name) {
|
||||||
|
printf("connection %s already in there: %s\n", (*cfg_ptr)->name.data(), __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Hash Collision detected with %s and %s in %s\n",
|
||||||
|
(*cfg_ptr)->name.data(), (*it->second->cfg_ptr)->name.data(), __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unlock();
|
||||||
|
// try to create connection object
|
||||||
|
|
||||||
|
auto con = createConnection(cfg_ptr);
|
||||||
|
if (!con) {
|
||||||
|
printf("couldn't create connection with cfg: %s\n", (*cfg_ptr)->name.data());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// create pool
|
||||||
|
auto pool = new ConnectionPool;
|
||||||
|
//pool->cfg = cfg;
|
||||||
|
pool->cfg_ptr = cfg_ptr;
|
||||||
|
pool->cfg_ptr->addRef();
|
||||||
|
printf("create new connection pool for connection: %s\n", (*cfg_ptr)->name.data());
|
||||||
|
|
||||||
|
lock();
|
||||||
|
if (!mInitalized) {
|
||||||
|
printf("[ConnectionManager::%s] not initialized any more\n", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mConnections.insert(std::pair<int, ConnectionPool*>(id, pool));
|
||||||
|
|
||||||
|
unlock();
|
||||||
|
|
||||||
|
// start connection
|
||||||
|
if(con) {
|
||||||
|
mConnectionEstablishThread.addConnectionConnect(con);
|
||||||
|
mConnectionEstablishThread.condSignal();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConnectionManager::markAsAvailable(Connection* con)
|
||||||
|
{
|
||||||
|
if (!mInitalized) {
|
||||||
|
addError(new Error(__FUNCTION__, "not initialized any more"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DHASH id = con->getHash();
|
||||||
|
lock();
|
||||||
|
if (!mInitalized) {
|
||||||
|
addError(new Error(__FUNCTION__, "not initialized any more"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = mConnections.find(id);
|
||||||
|
if (it == mConnections.end()) {
|
||||||
|
addError(new ParamError(__FUNCTION__, "couldn't find connection pool for id:", id));
|
||||||
|
delete con;
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (!con->isOpen()) {
|
||||||
|
if (con->errorCount() > 0) {
|
||||||
|
it->second->mErrorConnectingAttempts++;
|
||||||
|
addError(new ParamError(__FUNCTION__, "connection wasn't open and has errors, failed connecting attempt: ", it->second->mErrorConnectingAttempts));
|
||||||
|
getErrors(con);
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it->second->mFreeConnections.push(con);
|
||||||
|
checkTime(it->second);
|
||||||
|
|
||||||
|
unlock();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionManager::checkTime(ConnectionPool* pool)
|
||||||
|
{
|
||||||
|
if (!mInitalized) {
|
||||||
|
addError(new Error(__FUNCTION__, "not initialized any more"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto currentSize = pool->mFreeConnections.size();
|
||||||
|
// (re)start timer if at least three unused connections reached
|
||||||
|
if (pool->mFreeConnectionsCount < 3 && currentSize >= 3) {
|
||||||
|
pool->mConnectionFreeTimeout.reset();
|
||||||
|
}
|
||||||
|
if (currentSize >= 3 && pool->mConnectionFreeTimeout.seconds() > UNUSED_CONNECTION_TIMEOUT_SECONDS) {
|
||||||
|
// clean one connection and reset timer
|
||||||
|
auto con = pool->mFreeConnections.top();
|
||||||
|
pool->mFreeConnections.pop();
|
||||||
|
currentSize = pool->mFreeConnections.size();
|
||||||
|
|
||||||
|
mConnectionEstablishThread.addConnectionDestroy(con);
|
||||||
|
mConnectionEstablishThread.condSignal();
|
||||||
|
pool->mConnectionFreeTimeout.reset();
|
||||||
|
|
||||||
|
}
|
||||||
|
pool->mFreeConnectionsCount = currentSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection* ConnectionManager::createConnection(DRSimpleResourcePtr<Config>* cfg_ptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto con_cfg = static_cast<ConnectionConfig*>((Config*)(*cfg_ptr));
|
||||||
|
switch (con_cfg->type) {
|
||||||
|
case CONN_DEFAULT: return new Connection(cfg_ptr);
|
||||||
|
case CONN_MYSQL: return new MysqlConnection(cfg_ptr);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConnectionManager::isConnectionPool(DHASH id)
|
||||||
|
{
|
||||||
|
if (!mInitalized) {
|
||||||
|
addError(new Error(__FUNCTION__, "not initialized any more"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
lock();
|
||||||
|
if (!mInitalized) {
|
||||||
|
addError(new Error(__FUNCTION__, "not initialized any more"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto it = mConnections.find(id);
|
||||||
|
if (it == mConnections.end()) {
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unlock();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection* ConnectionManager::getConnection(DHASH id)
|
||||||
|
{
|
||||||
|
if (!mInitalized) {
|
||||||
|
addError(new Error(__FUNCTION__, "not initialized any more"));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
lock();
|
||||||
|
if (!mInitalized) {
|
||||||
|
unlock();
|
||||||
|
addError(new Error(__FUNCTION__, "not initialized any more"));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto it = mConnections.find(id);
|
||||||
|
if (it == mConnections.end()) {
|
||||||
|
addError(new ParamError(__FUNCTION__, "couldn't find connection pool for id:", id));
|
||||||
|
unlock();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
Connection* result = nullptr;
|
||||||
|
auto pool = it->second;
|
||||||
|
if (pool->mFreeConnections.size() > 0) {
|
||||||
|
result = pool->mFreeConnections.top();
|
||||||
|
pool->mFreeConnections.pop();
|
||||||
|
checkTime(pool);
|
||||||
|
}
|
||||||
|
unlock();
|
||||||
|
// if pool is empty, create new connection
|
||||||
|
if (pool->mFreeConnections.size() == 0) {
|
||||||
|
auto con = createConnection(pool->cfg_ptr);
|
||||||
|
if (!con) {
|
||||||
|
addError(new ParamError(__FUNCTION__, "couldn't create connection with cfg:", (*pool->cfg_ptr)->name));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
mConnectionEstablishThread.addConnectionConnect(con);
|
||||||
|
mConnectionEstablishThread.condSignal();
|
||||||
|
}
|
||||||
|
|
||||||
|
// we have get a connection, return
|
||||||
|
if (result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// we haven't get a connection, so we wait
|
||||||
|
std::unique_lock<std::mutex> lk(mConnectCondMutex);
|
||||||
|
mConnectCond.wait(lk, [] {return 1; });
|
||||||
|
lock();
|
||||||
|
if (!mInitalized) {
|
||||||
|
unlock();
|
||||||
|
addError(new Error(__FUNCTION__, "not initialized any more"));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pool->mFreeConnections.size() == 0) {
|
||||||
|
addError(new Error(__FUNCTION__, "no free connection after wait :/"));
|
||||||
|
unlock();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
result = pool->mFreeConnections.top();
|
||||||
|
pool->mFreeConnections.pop();
|
||||||
|
checkTime(pool);
|
||||||
|
unlock();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// int ConnectionManager::connectMysql(
|
||||||
|
// const char* db,
|
||||||
|
// const char* username /* = "root"*/,
|
||||||
|
// const char* pwd /* = nullptr*/,
|
||||||
|
// const char* url /* = "127.0.0.1" */,
|
||||||
|
// int port /*= 3306*/ )
|
||||||
|
// {
|
||||||
|
//mysqlx://mike:s3cr3t!@localhost:13009
|
||||||
|
/*std::stringstream urlStream;
|
||||||
|
urlStream << username;
|
||||||
|
if (pwd) {
|
||||||
|
urlStream << ":" << pwd;
|
||||||
|
}
|
||||||
|
urlStream << "@" << url;
|
||||||
|
urlStream << ":" << port;
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
mysqlx::Session* mysqlSession = nullptr;
|
||||||
|
try {
|
||||||
|
mysqlSession = new mysqlx::Session(url, port, username, pwd, db);
|
||||||
|
}
|
||||||
|
catch (const char* e) {
|
||||||
|
printf("[ConnectionManager::connectMysql] catch e: %s\n", e);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mWorkingMutex.lock();
|
||||||
|
|
||||||
|
int handle = mMysqlConnections.size();
|
||||||
|
mMysqlConnections.insert(std::pair<int, mysqlx::Session*>(handle, mysqlSession));
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
mysqlx::Session* ConnectionManager::getMysqlConnection(int handle)
|
||||||
|
{
|
||||||
|
mysqlx::Session* session = nullptr;
|
||||||
|
mWorkingMutex.lock();
|
||||||
|
auto it = mMysqlConnections.find(handle);
|
||||||
|
if (it != mMysqlConnections.end()) {
|
||||||
|
session = it->second;
|
||||||
|
}
|
||||||
|
mWorkingMutex.unlock();
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
*/
|
||||||
104
src/cpp/SingletonManager/ConnectionManager.h
Normal file
104
src/cpp/SingletonManager/ConnectionManager.h
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*!
|
||||||
|
*
|
||||||
|
* \author: einhornimmond
|
||||||
|
*
|
||||||
|
* \date: 28.02.19
|
||||||
|
*
|
||||||
|
* \brief: manage Connections like mysql or socket connections to another server
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DR_LUA_WEB_MODULE_CONNECTION_MANAGER_H
|
||||||
|
#define DR_LUA_WEB_MODULE_CONNECTION_MANAGER_H
|
||||||
|
|
||||||
|
#include "../LuaWebModule.h"
|
||||||
|
#include "../Connections/Connection.h"
|
||||||
|
#include "../CoreLib/Profiler.h"
|
||||||
|
#include "../CoreLib/Thread.h"
|
||||||
|
#include "../CoreLib/DRResourcePtr.h"
|
||||||
|
#include <queue>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#define UNUSED_CONNECTION_TIMEOUT_SECONDS 2
|
||||||
|
|
||||||
|
class ConnectionManager;
|
||||||
|
|
||||||
|
class ConnectThread : public Thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConnectThread(ConnectionManager* parent);
|
||||||
|
virtual ~ConnectThread();
|
||||||
|
|
||||||
|
void addConnectionConnect(Connection* connection);
|
||||||
|
void addConnectionDestroy(Connection* connection);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::mutex mDataMutex;
|
||||||
|
std::queue<Connection*> mConnectionsWaitingOnConnectCall;
|
||||||
|
std::queue<Connection*> mConnectionWaitingOnDestroy;
|
||||||
|
|
||||||
|
virtual int ThreadFunction();
|
||||||
|
virtual void cleanUpInThread();
|
||||||
|
|
||||||
|
bool initMysqlThread;
|
||||||
|
ConnectionManager* mParent;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ConnectionManager : public ErrorList
|
||||||
|
{
|
||||||
|
friend ConnectThread;
|
||||||
|
|
||||||
|
public:
|
||||||
|
~ConnectionManager();
|
||||||
|
|
||||||
|
static ConnectionManager* getInstance();
|
||||||
|
|
||||||
|
bool addConnectionPool(DRSimpleResourcePtr<Config>* cfg);
|
||||||
|
bool markAsAvailable(Connection* con);
|
||||||
|
|
||||||
|
bool isConnectionPool(DHASH id);
|
||||||
|
|
||||||
|
static Connection* createConnection(DRSimpleResourcePtr<Config>* cfg);
|
||||||
|
inline Connection* getConnection(const char* name) { return getConnection(DRMakeStringHash(name)); }
|
||||||
|
|
||||||
|
Connection* getConnection(DHASH id);
|
||||||
|
|
||||||
|
inline void lock() { mWorkingMutex.lock(); }
|
||||||
|
inline void unlock() { mWorkingMutex.unlock(); }
|
||||||
|
|
||||||
|
void deinitalize();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ConnectionManager();
|
||||||
|
|
||||||
|
struct ConnectionPool {
|
||||||
|
ConnectionPool(): mFreeConnectionsCount(0), mErrorConnectingAttempts(0){}
|
||||||
|
DRSimpleResourcePtr<Config>* cfg_ptr;
|
||||||
|
std::stack<Connection*> mFreeConnections;
|
||||||
|
// used to measure how long at least two connections not used
|
||||||
|
Profiler mConnectionFreeTimeout;
|
||||||
|
// only for calculating connection timeout
|
||||||
|
int mFreeConnectionsCount;
|
||||||
|
|
||||||
|
int mErrorConnectingAttempts;
|
||||||
|
};
|
||||||
|
|
||||||
|
void checkTime(ConnectionPool* pool);
|
||||||
|
|
||||||
|
// connection Pool
|
||||||
|
std::map<int, ConnectionPool*> mConnections;
|
||||||
|
|
||||||
|
// access mutex
|
||||||
|
std::mutex mWorkingMutex;
|
||||||
|
|
||||||
|
inline void condSignal() { mConnectCond.notify_one(); }
|
||||||
|
|
||||||
|
// creating and destroying connections thread
|
||||||
|
ConnectThread mConnectionEstablishThread;
|
||||||
|
std::condition_variable mConnectCond;
|
||||||
|
std::mutex mConnectCondMutex;
|
||||||
|
|
||||||
|
bool mInitalized;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //DR_LUA_WEB_MODULE_CONNECTION_MANAGER_H
|
||||||
46
src/cpp/SingletonManager/ErrorManager.cpp
Normal file
46
src/cpp/SingletonManager/ErrorManager.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include "ErrorManager.h"
|
||||||
|
|
||||||
|
ErrorManager* ErrorManager::getInstance()
|
||||||
|
{
|
||||||
|
static ErrorManager only;
|
||||||
|
return &only;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorManager::ErrorManager()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorManager::~ErrorManager()
|
||||||
|
{
|
||||||
|
for (auto it = mErrorsMap.begin(); it != mErrorsMap.end(); it++) {
|
||||||
|
for (auto listIt = it->second->begin(); listIt != it->second->end(); listIt++) {
|
||||||
|
delete *listIt;
|
||||||
|
}
|
||||||
|
delete it->second;
|
||||||
|
}
|
||||||
|
mErrorsMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ErrorManager::addError(Error* error)
|
||||||
|
{
|
||||||
|
DHASH id = DRMakeStringHash(error->getFunctionName());
|
||||||
|
auto it = mErrorsMap.find(id);
|
||||||
|
std::list<Error*>* list = nullptr;
|
||||||
|
|
||||||
|
printf("[ErrorManager::addError] error with function: %s, %s\n", error->getFunctionName(), error->getMessage());
|
||||||
|
|
||||||
|
if (it == mErrorsMap.end()) {
|
||||||
|
list = new std::list<Error *>;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
list = it->second;
|
||||||
|
// check if hash collision
|
||||||
|
if (strcmp((*list->begin())->getFunctionName(), error->getFunctionName()) != 0) {
|
||||||
|
throw "[ErrorManager::addError] hash collision detected";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list->push_back(error);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
42
src/cpp/SingletonManager/ErrorManager.h
Normal file
42
src/cpp/SingletonManager/ErrorManager.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*!
|
||||||
|
*
|
||||||
|
* \author: einhornimmond
|
||||||
|
*
|
||||||
|
* \date: 28.02.19
|
||||||
|
*
|
||||||
|
* \brief: manage error log and store errors for retrieving from lua
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DR_LUA_WEB_MODULE_ERROR_MANAGER_H
|
||||||
|
#define DR_LUA_WEB_MODULE_ERROR_MANAGER_H
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <ios>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <cstring>
|
||||||
|
#include "../Error/Error.h"
|
||||||
|
#include "../CoreLib/DRHash.hpp"
|
||||||
|
|
||||||
|
class ErrorManager : public IErrorCollection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~ErrorManager();
|
||||||
|
|
||||||
|
static ErrorManager* getInstance();
|
||||||
|
|
||||||
|
// will called delete on error
|
||||||
|
virtual void addError(Error* error);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ErrorManager();
|
||||||
|
|
||||||
|
|
||||||
|
// access mutex
|
||||||
|
std::mutex mWorkingMutex;
|
||||||
|
std::map<DHASH, std::list<Error*>*> mErrorsMap;
|
||||||
|
// how many errors should be stored
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //DR_LUA_WEB_MODULE_CONNECTION_MANAGER_H
|
||||||
132
src/cpp/SingletonManager/SessionManager.cpp
Normal file
132
src/cpp/SingletonManager/SessionManager.cpp
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#include "SessionManager.h"
|
||||||
|
|
||||||
|
SessionManager* SessionManager::getInstance()
|
||||||
|
{
|
||||||
|
static SessionManager only;
|
||||||
|
return &only;
|
||||||
|
}
|
||||||
|
|
||||||
|
SessionManager::SessionManager()
|
||||||
|
: mInitalized(true)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SessionManager::~SessionManager()
|
||||||
|
{
|
||||||
|
if (mInitalized) {
|
||||||
|
deinitalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionManager::deinitalize()
|
||||||
|
{
|
||||||
|
|
||||||
|
mWorkingMutex.lock();
|
||||||
|
|
||||||
|
while (mEmptyRequestStack.size()) {
|
||||||
|
mEmptyRequestStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) {
|
||||||
|
delete it->second;
|
||||||
|
}
|
||||||
|
mRequestSessionMap.clear();
|
||||||
|
|
||||||
|
mInitalized = false;
|
||||||
|
mWorkingMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MysqlSession* SessionManager::getNewMysqlSession(int* handle)
|
||||||
|
{
|
||||||
|
if (!mInitalized) {
|
||||||
|
printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
// lock
|
||||||
|
mWorkingMutex.lock();
|
||||||
|
|
||||||
|
// check if we have an existing session ready to use
|
||||||
|
if (mEmptyRequestStack.size() > 0) {
|
||||||
|
int local_handle = mEmptyRequestStack.top();
|
||||||
|
mEmptyRequestStack.pop();
|
||||||
|
auto resultIt = mRequestSessionMap.find(local_handle);
|
||||||
|
if (resultIt != mRequestSessionMap.end()) {
|
||||||
|
MysqlSession* result = resultIt->second;
|
||||||
|
mWorkingMutex.unlock();
|
||||||
|
|
||||||
|
if (handle) {
|
||||||
|
*handle = local_handle;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// else create new RequestSession Object
|
||||||
|
int newHandle = mRequestSessionMap.size();
|
||||||
|
auto requestSession = new MysqlSession(newHandle);
|
||||||
|
mRequestSessionMap.insert(std::pair<int, MysqlSession*>(newHandle, requestSession));
|
||||||
|
mWorkingMutex.unlock();
|
||||||
|
|
||||||
|
if (handle) {
|
||||||
|
*handle = newHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SessionManager::releseMysqlSession(int requestHandleSession)
|
||||||
|
{
|
||||||
|
if (!mInitalized) {
|
||||||
|
printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mWorkingMutex.lock();
|
||||||
|
auto it = mRequestSessionMap.find(requestHandleSession);
|
||||||
|
if (it == mRequestSessionMap.end()) {
|
||||||
|
printf("[SessionManager::releaseRequestSession] requestSession with handle: %d not found\n", requestHandleSession);
|
||||||
|
mWorkingMutex.unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
it->second->reset();
|
||||||
|
mEmptyRequestStack.push(requestHandleSession);
|
||||||
|
mWorkingMutex.unlock();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SessionManager::isExist(int requestHandleSession)
|
||||||
|
{
|
||||||
|
if (!mInitalized) {
|
||||||
|
printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool result = false;
|
||||||
|
mWorkingMutex.lock();
|
||||||
|
auto it = mRequestSessionMap.find(requestHandleSession);
|
||||||
|
if (it != mRequestSessionMap.end()) {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
mWorkingMutex.unlock();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
MysqlSession* SessionManager::getMysqlSession(int handle)
|
||||||
|
{
|
||||||
|
if (!mInitalized) {
|
||||||
|
printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
MysqlSession* result = nullptr;
|
||||||
|
mWorkingMutex.lock();
|
||||||
|
auto it = mRequestSessionMap.find(handle);
|
||||||
|
if (it != mRequestSessionMap.end()) {
|
||||||
|
result = it->second;
|
||||||
|
}
|
||||||
|
mWorkingMutex.unlock();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
50
src/cpp/SingletonManager/SessionManager.h
Normal file
50
src/cpp/SingletonManager/SessionManager.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*!
|
||||||
|
*
|
||||||
|
* \author: einhornimmond
|
||||||
|
*
|
||||||
|
* \date: 28.02.19
|
||||||
|
*
|
||||||
|
* \brief: manage different session from lua
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DR_LUA_WEB_MODULE_SESSION_MANAGER_H
|
||||||
|
#define DR_LUA_WEB_MODULE_SESSION_MANAGER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "../Session/MysqlSession.h"
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <map>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
class SessionManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~SessionManager();
|
||||||
|
|
||||||
|
static SessionManager* getInstance();
|
||||||
|
|
||||||
|
MysqlSession* getNewMysqlSession(int* handle = nullptr);
|
||||||
|
inline bool releseMysqlSession(MysqlSession* requestSession) {
|
||||||
|
return releseMysqlSession(requestSession->getHandle());
|
||||||
|
}
|
||||||
|
bool releseMysqlSession(int requestHandleSession);
|
||||||
|
bool isExist(int requestHandleSession);
|
||||||
|
MysqlSession* getMysqlSession(int handle);
|
||||||
|
|
||||||
|
void deinitalize();
|
||||||
|
protected:
|
||||||
|
SessionManager();
|
||||||
|
|
||||||
|
|
||||||
|
// access mutex
|
||||||
|
std::mutex mWorkingMutex;
|
||||||
|
|
||||||
|
// sessions storage
|
||||||
|
std::map<int, MysqlSession*> mRequestSessionMap;
|
||||||
|
std::stack<int> mEmptyRequestStack;
|
||||||
|
|
||||||
|
bool mInitalized;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //DR_LUA_WEB_MODULE_SESSION_MANAGER_H
|
||||||
29
src/cpp/model/Error.cpp
Normal file
29
src/cpp/model/Error.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include "Error.h"
|
||||||
|
|
||||||
|
|
||||||
|
Error::Error(const char* functionName, const char* message)
|
||||||
|
: mFunctionName(functionName), mMessage(message)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Error::~Error()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Error::getString()
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << mFunctionName << ": " << mMessage << std::endl;
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ParamError::getString()
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << mFunctionName << ": " << mMessage << " " << mParam << std::endl;
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
59
src/cpp/model/Error.h
Normal file
59
src/cpp/model/Error.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*!
|
||||||
|
*
|
||||||
|
* \author: einhornimmond
|
||||||
|
*
|
||||||
|
* \date: 07.03.19
|
||||||
|
*
|
||||||
|
* \brief: error data
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DR_LUA_WEB_MODULE_ERROR_ERROR_H
|
||||||
|
#define DR_LUA_WEB_MODULE_ERROR_ERROR_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
class Error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Error(const char* functionName, const char* message);
|
||||||
|
~Error();
|
||||||
|
|
||||||
|
const char* getFunctionName() { return mFunctionName.data(); }
|
||||||
|
const char* getMessage() { return mMessage.data(); }
|
||||||
|
virtual std::string getString();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string mFunctionName;
|
||||||
|
std::string mMessage;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ParamError : public Error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ParamError(const char* functionName, const char* message, const char* param)
|
||||||
|
: Error(functionName, message), mParam(param) {}
|
||||||
|
ParamError(const char* functionName, const char* message, const std::string& param)
|
||||||
|
: Error(functionName, message), mParam(param) {}
|
||||||
|
|
||||||
|
ParamError(const char* functioName, const char* message, int param)
|
||||||
|
: Error(functioName, message) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << param;
|
||||||
|
mParam = ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::string getString();
|
||||||
|
protected:
|
||||||
|
std::string mParam;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class IErrorCollection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void addError(Error*) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DR_LUA_WEB_MODULE_ERROR_ERROR_H
|
||||||
66
src/cpp/model/ErrorList.cpp
Normal file
66
src/cpp/model/ErrorList.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#include "ErrorList.h"
|
||||||
|
|
||||||
|
ErrorList::ErrorList()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorList::~ErrorList()
|
||||||
|
{
|
||||||
|
while (mErrorStack.size() > 0) {
|
||||||
|
delete mErrorStack.top();
|
||||||
|
mErrorStack.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ErrorList::addError(Error* error)
|
||||||
|
{
|
||||||
|
mErrorStack.push(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error* ErrorList::getLastError()
|
||||||
|
{
|
||||||
|
if (mErrorStack.size() == 0) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error* error = mErrorStack.top();
|
||||||
|
if (error) {
|
||||||
|
mErrorStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ErrorList::clearErrors()
|
||||||
|
{
|
||||||
|
while (mErrorStack.size()) {
|
||||||
|
auto error = mErrorStack.top();
|
||||||
|
if (error) {
|
||||||
|
delete error;
|
||||||
|
}
|
||||||
|
mErrorStack.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ErrorList::getErrors(ErrorList* send)
|
||||||
|
{
|
||||||
|
Error* error = nullptr;
|
||||||
|
int iCount = 0;
|
||||||
|
while (error = send->getLastError()) {
|
||||||
|
addError(error);
|
||||||
|
iCount++;
|
||||||
|
}
|
||||||
|
return iCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ErrorList::printErrors()
|
||||||
|
{
|
||||||
|
while (mErrorStack.size() > 0) {
|
||||||
|
auto error = mErrorStack.top();
|
||||||
|
mErrorStack.pop();
|
||||||
|
printf(error->getString().data());
|
||||||
|
delete error;
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/cpp/model/ErrorList.h
Normal file
44
src/cpp/model/ErrorList.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*!
|
||||||
|
*
|
||||||
|
* \author: einhornimmond
|
||||||
|
*
|
||||||
|
* \date: 07.03.19
|
||||||
|
*
|
||||||
|
* \brief: error
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DR_LUA_WEB_MODULE_ERROR_ERROR_LIST_H
|
||||||
|
#define DR_LUA_WEB_MODULE_ERROR_ERROR_LIST_H
|
||||||
|
|
||||||
|
#include "Error.h"
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
class ErrorList : public IErrorCollection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ErrorList();
|
||||||
|
~ErrorList();
|
||||||
|
|
||||||
|
// push error, error will be deleted in deconstructor
|
||||||
|
virtual void addError(Error* error);
|
||||||
|
|
||||||
|
// return error on top of stack, please delete after using
|
||||||
|
Error* getLastError();
|
||||||
|
|
||||||
|
inline size_t errorCount() { return mErrorStack.size(); }
|
||||||
|
|
||||||
|
// delete all errors
|
||||||
|
void clearErrors();
|
||||||
|
|
||||||
|
static int moveErrors(ErrorList* recv, ErrorList* send) {
|
||||||
|
return recv->getErrors(send);
|
||||||
|
}
|
||||||
|
int getErrors(ErrorList* send);
|
||||||
|
|
||||||
|
void printErrors();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::stack<Error*> mErrorStack;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DR_LUA_WEB_MODULE_ERROR_ERROR_LIST_H
|
||||||
13
src/cpp/model/Session.cpp
Normal file
13
src/cpp/model/Session.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "Session.h"
|
||||||
|
|
||||||
|
Session::Session(int handle)
|
||||||
|
: mHandleId(handle)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Session::~Session()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
29
src/cpp/model/Session.h
Normal file
29
src/cpp/model/Session.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*!
|
||||||
|
*
|
||||||
|
* \author: einhornimmond
|
||||||
|
*
|
||||||
|
* \date: 02.03.19
|
||||||
|
*
|
||||||
|
* \brief: store session data
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DR_LUA_WEB_MODULE_SESSION_SESSION_H
|
||||||
|
#define DR_LUA_WEB_MODULE_SESSION_SESSION_H
|
||||||
|
|
||||||
|
#include "../Error/ErrorList.h"
|
||||||
|
|
||||||
|
class Session : public ErrorList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Session(int handle);
|
||||||
|
~Session();
|
||||||
|
|
||||||
|
inline int getHandle() { return mHandleId; }
|
||||||
|
virtual void reset() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int mHandleId;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DR_LUA_WEB_MODULE_SESSION_SESSION_H
|
||||||
0
src/cpp/model/User.cpp
Normal file
0
src/cpp/model/User.cpp
Normal file
0
src/cpp/model/User.h
Normal file
0
src/cpp/model/User.h
Normal file
Loading…
x
Reference in New Issue
Block a user