Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 281 lines (216 sloc) 7.201 kB
5a63907 @aleks-f change EOL to 'native'
aleks-f authored
1 //
2a81e59 @aleks-f MySQL DateTime support, samples Linux compile
aleks-f authored
2 // SessionImpl.cpp
5a63907 @aleks-f change EOL to 'native'
aleks-f authored
3 //
4 // $Id: //poco/1.4/Data/MySQL/src/SessionImpl.cpp#1 $
5 //
6 // Library: Data
7 // Package: MySQL
8 // Module: SessionImpl
9 //
10 // Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
11 // and Contributors.
12 //
628a06f @bufferoverflow LICENSE: add info about SPDX-License-Identifier usage and use it
bufferoverflow authored
13 // SPDX-License-Identifier: BSL-1.0
5a63907 @aleks-f change EOL to 'native'
aleks-f authored
14 //
15
16
17 #include "Poco/Data/MySQL/SessionImpl.h"
18 #include "Poco/Data/MySQL/MySQLStatementImpl.h"
19 #include "Poco/Data/Session.h"
20 #include "Poco/NumberParser.h"
21 #include "Poco/String.h"
22
23
24 namespace
25 {
26 std::string copyStripped(std::string::const_iterator from, std::string::const_iterator to)
27 {
28 // skip leading spaces
29 while ((from != to) && isspace(*from)) from++;
30 // skip trailing spaces
31 while ((from != to) && isspace(*(to - 1))) to--;
32
33 return std::string(from, to);
34 }
35 }
36
37
38 namespace Poco {
39 namespace Data {
40 namespace MySQL {
41
42
43 const std::string SessionImpl::MYSQL_READ_UNCOMMITTED = "READ UNCOMMITTED";
44 const std::string SessionImpl::MYSQL_READ_COMMITTED = "READ COMMITTED";
45 const std::string SessionImpl::MYSQL_REPEATABLE_READ = "REPEATABLE READ";
46 const std::string SessionImpl::MYSQL_SERIALIZABLE = "SERIALIZABLE";
47
48
49 SessionImpl::SessionImpl(const std::string& connectionString, std::size_t loginTimeout) :
2a81e59 @aleks-f MySQL DateTime support, samples Linux compile
aleks-f authored
50 Poco::Data::AbstractSessionImpl<SessionImpl>(connectionString, loginTimeout),
5a63907 @aleks-f change EOL to 'native'
aleks-f authored
51 _handle(0),
52 _connected(false),
53 _inTransaction(false)
54 {
b95ec4f @aleks-f MySQL fixes/additions/improvements
aleks-f authored
55 addProperty("insertId", &SessionImpl::setInsertId, &SessionImpl::getInsertId);
56 setProperty("handle", static_cast<MYSQL*>(_handle));
5a63907 @aleks-f change EOL to 'native'
aleks-f authored
57 open();
58 setConnectionTimeout(CONNECTION_TIMEOUT_DEFAULT);
59 }
60
61
62 void SessionImpl::open(const std::string& connect)
63 {
64 if (connect != connectionString())
65 {
66 if (isConnected())
67 throw InvalidAccessException("Session already connected");
68
69 if (!connect.empty())
70 setConnectionString(connect);
71 }
72
73 poco_assert_dbg (!connectionString().empty());
74
75 _handle.init();
76
77 unsigned int timeout = static_cast<unsigned int>(getLoginTimeout());
78 _handle.options(MYSQL_OPT_CONNECT_TIMEOUT, timeout);
79
80 std::map<std::string, std::string> options;
81
82 // Default values
83 options["host"] = "localhost";
84 options["port"] = "3306";
85 options["user"] = "";
86 options["password"] = "";
87 options["db"] = "";
88 options["compress"] = "";
89 options["auto-reconnect"] = "";
b95ec4f @aleks-f MySQL fixes/additions/improvements
aleks-f authored
90 options["secure-auth"] = "";
1324366 @coolypf Add MySQL charset configuration support
coolypf authored
91 options["character-set"] = "utf8";
5a63907 @aleks-f change EOL to 'native'
aleks-f authored
92
93 const std::string& connString = connectionString();
94 for (std::string::const_iterator start = connString.begin();;)
95 {
96 std::string::const_iterator finish = std::find(start, connString.end(), ';');
97 std::string::const_iterator middle = std::find(start, finish, '=');
98
99 if (middle == finish)
100 throw MySQLException("create session: bad connection string format, can not find '='");
101
102 options[copyStripped(start, middle)] = copyStripped(middle + 1, finish);
103
104 if ((finish == connString.end()) || (finish + 1 == connString.end())) break;
105
106 start = finish + 1;
107 }
108
b95ec4f @aleks-f MySQL fixes/additions/improvements
aleks-f authored
109 if (options["user"].empty())
5a63907 @aleks-f change EOL to 'native'
aleks-f authored
110 throw MySQLException("create session: specify user name");
111
248d521 @aleks-f #310 Connect to MySQL db without specifying database name.
aleks-f authored
112 const char * db = NULL;
113 if (!options["db"].empty())
114 db = options["db"].c_str();
5a63907 @aleks-f change EOL to 'native'
aleks-f authored
115
116 unsigned int port = 0;
117 if (!NumberParser::tryParseUnsigned(options["port"], port) || 0 == port || port > 65535)
118 throw MySQLException("create session: specify correct port (numeric in decimal notation)");
119
120 if (options["compress"] == "true")
121 _handle.options(MYSQL_OPT_COMPRESS);
122 else if (options["compress"] == "false")
123 ;
b95ec4f @aleks-f MySQL fixes/additions/improvements
aleks-f authored
124 else if (!options["compress"].empty())
5a63907 @aleks-f change EOL to 'native'
aleks-f authored
125 throw MySQLException("create session: specify correct compress option (true or false) or skip it");
126
127 if (options["auto-reconnect"] == "true")
128 _handle.options(MYSQL_OPT_RECONNECT, true);
129 else if (options["auto-reconnect"] == "false")
130 _handle.options(MYSQL_OPT_RECONNECT, false);
b95ec4f @aleks-f MySQL fixes/additions/improvements
aleks-f authored
131 else if (!options["auto-reconnect"].empty())
5a63907 @aleks-f change EOL to 'native'
aleks-f authored
132 throw MySQLException("create session: specify correct auto-reconnect option (true or false) or skip it");
133
b95ec4f @aleks-f MySQL fixes/additions/improvements
aleks-f authored
134 if (options["secure-auth"] == "true")
135 _handle.options(MYSQL_SECURE_AUTH, true);
136 else if (options["secure-auth"] == "false")
137 _handle.options(MYSQL_SECURE_AUTH, false);
138 else if (!options["secure-auth"].empty())
139 throw MySQLException("create session: specify correct secure-auth option (true or false) or skip it");
140
1324366 @coolypf Add MySQL charset configuration support
coolypf authored
141 if (!options["character-set"].empty())
142 _handle.options(MYSQL_SET_CHARSET_NAME, options["character-set"].c_str());
143
5a63907 @aleks-f change EOL to 'native'
aleks-f authored
144 // Real connect
145 _handle.connect(options["host"].c_str(),
146 options["user"].c_str(),
147 options["password"].c_str(),
248d521 @aleks-f #310 Connect to MySQL db without specifying database name.
aleks-f authored
148 db,
5a63907 @aleks-f change EOL to 'native'
aleks-f authored
149 port);
150
151 addFeature("autoCommit",
152 &SessionImpl::autoCommit,
153 &SessionImpl::isAutoCommit);
154
155 _connected = true;
156 }
157
158
159 SessionImpl::~SessionImpl()
160 {
161 close();
162 }
163
164
165 Poco::Data::StatementImpl* SessionImpl::createStatementImpl()
166 {
167 return new MySQLStatementImpl(*this);
168 }
169
170
171 void SessionImpl::begin()
172 {
173 Poco::FastMutex::ScopedLock l(_mutex);
174
175 if (_inTransaction)
176 throw Poco::InvalidAccessException("Already in transaction.");
177
32c5b6b @aleks-f ODBC fixes and tests (Oracle, SQL Server, MySQL on Windows)
aleks-f authored
178 _handle.startTransaction();
5a63907 @aleks-f change EOL to 'native'
aleks-f authored
179 _inTransaction = true;
180 }
181
182
183 void SessionImpl::commit()
184 {
32c5b6b @aleks-f ODBC fixes and tests (Oracle, SQL Server, MySQL on Windows)
aleks-f authored
185 _handle.commit();
5a63907 @aleks-f change EOL to 'native'
aleks-f authored
186 _inTransaction = false;
187 }
188
189
190 void SessionImpl::rollback()
191 {
32c5b6b @aleks-f ODBC fixes and tests (Oracle, SQL Server, MySQL on Windows)
aleks-f authored
192 _handle.rollback();
5a63907 @aleks-f change EOL to 'native'
aleks-f authored
193 _inTransaction = false;
194 }
195
196
197 void SessionImpl::autoCommit(const std::string&, bool val)
198 {
199 StatementExecutor ex(_handle);
200 ex.prepare(Poco::format("SET autocommit=%d", val ? 1 : 0));
201 ex.execute();
202 }
203
204
205 bool SessionImpl::isAutoCommit(const std::string&)
206 {
207 int ac = 0;
208 return 1 == getSetting("autocommit", ac);
209 }
210
211
212 void SessionImpl::setTransactionIsolation(Poco::UInt32 ti)
213 {
214 std::string isolation;
215 switch (ti)
216 {
217 case Session::TRANSACTION_READ_UNCOMMITTED:
218 isolation = MYSQL_READ_UNCOMMITTED; break;
219 case Session::TRANSACTION_READ_COMMITTED:
220 isolation = MYSQL_READ_COMMITTED; break;
221 case Session::TRANSACTION_REPEATABLE_READ:
222 isolation = MYSQL_REPEATABLE_READ; break;
223 case Session::TRANSACTION_SERIALIZABLE:
224 isolation = MYSQL_SERIALIZABLE; break;
225 default:
226 throw Poco::InvalidArgumentException("setTransactionIsolation()");
227 }
228
229 StatementExecutor ex(_handle);
230 ex.prepare(Poco::format("SET SESSION TRANSACTION ISOLATION LEVEL %s", isolation));
231 ex.execute();
232 }
233
234
235 Poco::UInt32 SessionImpl::getTransactionIsolation()
236 {
237 std::string isolation;
238 getSetting("tx_isolation", isolation);
239 Poco::replaceInPlace(isolation, "-", " ");
240 if (MYSQL_READ_UNCOMMITTED == isolation)
241 return Session::TRANSACTION_READ_UNCOMMITTED;
242 else if (MYSQL_READ_COMMITTED == isolation)
243 return Session::TRANSACTION_READ_COMMITTED;
244 else if (MYSQL_REPEATABLE_READ == isolation)
245 return Session::TRANSACTION_REPEATABLE_READ;
246 else if (MYSQL_SERIALIZABLE == isolation)
247 return Session::TRANSACTION_SERIALIZABLE;
248
249 throw InvalidArgumentException("getTransactionIsolation()");
250 }
251
252
253 bool SessionImpl::hasTransactionIsolation(Poco::UInt32 ti)
254 {
255 return Session::TRANSACTION_READ_UNCOMMITTED == ti ||
256 Session::TRANSACTION_READ_COMMITTED == ti ||
257 Session::TRANSACTION_REPEATABLE_READ == ti ||
258 Session::TRANSACTION_SERIALIZABLE == ti;
259 }
260
261
262 void SessionImpl::close()
263 {
264 if (_connected)
265 {
266 _handle.close();
267 _connected = false;
268 }
269 }
270
271
272 void SessionImpl::setConnectionTimeout(std::size_t timeout)
273 {
274 _handle.options(MYSQL_OPT_READ_TIMEOUT, static_cast<unsigned int>(timeout));
275 _handle.options(MYSQL_OPT_WRITE_TIMEOUT, static_cast<unsigned int>(timeout));
276 _timeout = timeout;
277 }
278
279
280 }}}
Something went wrong with that request. Please try again.