Skip to content

Commit 394a798

Browse files
committed
WL12495: DevAPI: Support session attributes
1 parent 2025e74 commit 394a798

File tree

23 files changed

+1081
-49
lines changed

23 files changed

+1081
-49
lines changed

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ else()
9898
endif()
9999

100100

101+
#
102+
# Connector System Configuration
103+
#
104+
include(config.cmake)
105+
106+
101107
#
102108
# Install settings
103109
# ================

cdk/foundation/connection_tcpip.cc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,42 @@ namespace cdk {
130130
namespace foundation {
131131
namespace connection {
132132

133+
class Socket_system_initializer
134+
{
135+
Socket_system_initializer()
136+
{
137+
detail::initialize_socket_system();
138+
}
139+
140+
~Socket_system_initializer()
141+
{
142+
try
143+
{
144+
detail::uninitialize_socket_system();
145+
}
146+
catch (...)
147+
{
148+
// Ignoring errors in destructor.
149+
}
150+
}
151+
152+
friend void socket_system_initialize();
153+
};
154+
155+
void socket_system_initialize()
156+
{
157+
static Socket_system_initializer initializer;
158+
}
159+
160+
161+
std::string get_local_hostname()
162+
{
163+
// This will initialize socket system (e.g. Winsock) during construction of first CDK connection.
164+
socket_system_initialize();
165+
166+
return detail::get_local_hostname();
167+
}
168+
133169

134170
TCPIP::TCPIP(const std::string& host,
135171
unsigned short port,

cdk/foundation/connection_tcpip_base.h

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,28 +42,11 @@ namespace foundation {
4242
namespace connection {
4343

4444

45+
void socket_system_initialize();
46+
47+
4548
class Socket_base::Impl
4649
{
47-
class Socket_system_initializer
48-
{
49-
public:
50-
Socket_system_initializer()
51-
{
52-
detail::initialize_socket_system();
53-
}
54-
55-
~Socket_system_initializer()
56-
{
57-
try
58-
{
59-
detail::uninitialize_socket_system();
60-
}
61-
catch (...)
62-
{
63-
// Ignoring errors in destructor.
64-
}
65-
}
66-
};
6750

6851
public:
6952
typedef detail::Socket socket;
@@ -74,7 +57,7 @@ class Socket_base::Impl
7457
: m_sock(detail::NULL_SOCKET)
7558
{
7659
// This will initialize socket system (e.g. Winsock) during construction of first CDK connection.
77-
static Socket_system_initializer initializer;
60+
socket_system_initialize();
7861
}
7962

8063
bool is_open() const

cdk/foundation/socket_detail.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,5 +968,14 @@ size_t send_some(Socket socket, const byte *buffer, size_t buffer_size, bool wai
968968
return bytes_sent;
969969
}
970970

971+
std::string get_local_hostname()
972+
{
973+
char buf[1024] = {0};
974+
if (gethostname(buf, sizeof(buf)) < 0) {
975+
throw_socket_error();
976+
}
977+
return buf;
978+
}
979+
971980

972981
}}}} // cdk::foundation::connection::detail

cdk/foundation/socket_detail.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,11 @@ size_t recv_some(Socket socket, byte *buffer, size_t buffer_size, bool wait);
442442
size_t send_some(Socket socket, const byte *buffer, size_t buffer_size, bool wait);
443443

444444

445+
/**
446+
@brief get_local_hostname returns hostname of the current machine
447+
*/
448+
std::string get_local_hostname();
449+
445450
}}}} // cdk::foundation::connection::detail
446451

447452

cdk/include/mysql/cdk/data_source.h

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ PUSH_SYS_WARNINGS_CDK
3737
#include <functional>
3838
#include <algorithm>
3939
#include <set>
40+
#include "api/expression.h"
4041
POP_SYS_WARNINGS_CDK
4142

4243

@@ -46,12 +47,29 @@ namespace cdk {
4647

4748
namespace ds {
4849

50+
51+
struct Attr_processor
52+
{
53+
virtual ~Attr_processor() {}
54+
virtual void attr(const string &key, const string &val)=0;
55+
};
56+
57+
class Session_attributes
58+
: public cdk::api::Expr_base<Attr_processor>
59+
{};
60+
61+
4962
/*
5063
* Generic session options which are valid for any data source.
5164
*/
5265

66+
67+
5368
template <class Base>
54-
class Options : public Base
69+
class Options
70+
: public Base
71+
, public Session_attributes
72+
, public Attr_processor
5573
{
5674
public:
5775

@@ -88,6 +106,31 @@ class Options : public Base
88106
m_has_db = true;
89107
}
90108

109+
void set_attributes(std::map<std::string,std::string> &connection_attr)
110+
{
111+
m_connection_attr = connection_attr;
112+
}
113+
114+
const Session_attributes* attributes() const
115+
{
116+
if (m_connection_attr.empty())
117+
return nullptr;
118+
return this;
119+
}
120+
121+
void process(Processor &prc) const override
122+
{
123+
for (auto &el : m_connection_attr)
124+
{
125+
prc.attr(el.first, el.second);
126+
}
127+
}
128+
129+
void attr(const string &key, const string &val) override
130+
{
131+
m_connection_attr[key]=val;
132+
}
133+
91134
protected:
92135

93136
string m_usr;
@@ -96,6 +139,7 @@ class Options : public Base
96139

97140
bool m_has_db;
98141
string m_db;
142+
std::map<std::string,std::string> m_connection_attr;
99143

100144
};
101145

cdk/include/mysql/cdk/foundation/connection_tcpip.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ namespace connection {
4949
class TCPIP;
5050
class TLS;
5151

52+
/**
53+
@brief get_local_hostname returns hostname of the current machine
54+
*/
55+
std::string get_local_hostname();
56+
57+
5258

5359
/*
5460
Defining cdkio error category

cdk/include/mysql/cdk/mysqlx/session.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,9 @@ class Session
524524
{
525525
m_prepare_prc.m_session = this;
526526
m_stmt_stats.clear();
527+
send_connection_attr(options);
527528
authenticate(options, conn.is_secure());
529+
528530
// TODO: make "lazy" checks instead, deferring to the time when given
529531
// feature is used.
530532
check_protocol_fields();
@@ -697,6 +699,8 @@ class Session
697699

698700
Reply_init & set_command(Proto_prepare_op *cmd);
699701

702+
// Send Connection Attributes
703+
void send_connection_attr(const Options &options);
700704
// Authentication (cdk::protocol::mysqlx::Auth_processor)
701705
void authenticate(const Options &options, bool secure = false);
702706
void do_authenticate(const Options &options, int auth_method, bool secure);

cdk/mysqlx/session.cc

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,73 @@ class AuthSha256Memory
354354
Class Session
355355
*/
356356

357+
void Session::send_connection_attr(const Options &options)
358+
{
359+
360+
struct Attr_converter
361+
: cdk::protocol::mysqlx::api::Any::Document
362+
, ds::Attr_processor
363+
{
364+
Attr_converter(const ds::Session_attributes* attr)
365+
:m_attr(attr)
366+
{}
367+
368+
const ds::Session_attributes * m_attr;
369+
Processor::Any_prc::Doc_prc *m_attr_prc;
370+
371+
void process(Processor &prc) const override
372+
{
373+
auto *self = const_cast<Attr_converter*>(this);
374+
prc.doc_begin();
375+
self->m_attr_prc = prc.key_val("session_connect_attrs")->doc();
376+
self->m_attr_prc->doc_begin();
377+
m_attr->process(*self);
378+
self->m_attr_prc->doc_end();
379+
prc.doc_end();
380+
}
381+
382+
void attr(const string &key, const string &val) override
383+
{
384+
m_attr_prc->key_val(key)->scalar()->str(bytes(val));
385+
}
386+
387+
} ;
388+
389+
if (options.attributes())
390+
{
391+
m_protocol.snd_CapabilitiesSet(Attr_converter(options.attributes())).wait();
392+
393+
struct Check_reply_prc : cdk::protocol::mysqlx::Reply_processor
394+
{
395+
string m_msg;
396+
unsigned int m_code = 0;
397+
cdk::protocol::mysqlx::sql_state_t m_sql_state;
398+
void error(unsigned int code, short int,
399+
cdk::protocol::mysqlx::sql_state_t state, const string &msg) override
400+
{
401+
m_code = code;
402+
m_sql_state = state;
403+
m_msg = msg;
404+
}
405+
406+
void ok(string) override
407+
{}
408+
};
409+
410+
Check_reply_prc prc;
411+
412+
m_protocol.rcv_Reply(prc).wait();
413+
414+
if(prc.m_code != 0 && prc.m_code != 5002)
415+
{
416+
//code: 5002
417+
//msg: "Capability \'session_connect_attrs\' doesn\'t exist"
418+
throw Server_error(prc.m_code, prc.m_sql_state, prc.m_msg);
419+
}
420+
421+
}
422+
}
423+
357424

358425
void Session::send_auth()
359426
{

0 commit comments

Comments
 (0)