1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22 #include "mysqlc_connection.hxx"
23 #include "mysqlc_databasemetadata.hxx"
24
25
26 #include "mysqlc_driver.hxx"
27 #include "mysqlc_statement.hxx"
28 #include "mysqlc_preparedstatement.hxx"
29 #include "mysqlc_general.hxx"
30
31 #include <preextstl.h>
32 #include <cppconn/driver.h>
33 #include <cppconn/connection.h>
34 #include <cppconn/statement.h>
35 #include <cppconn/metadata.h>
36 #include <cppconn/exception.h>
37 #include <postextstl.h>
38
39 #include <com/sun/star/sdbc/ColumnValue.hpp>
40 #include <com/sun/star/sdbc/XRow.hpp>
41 #include <com/sun/star/sdbc/TransactionIsolation.hpp>
42 #include <com/sun/star/lang/DisposedException.hpp>
43 #include <com/sun/star/beans/NamedValue.hpp>
44
45 #include <osl/module.hxx>
46 #include <osl/thread.h>
47 #include <osl/file.h>
48 #include <rtl/uri.hxx>
49 #include <rtl/ustrbuf.hxx>
50
51 using namespace connectivity::mysqlc;
52
53 #include <stdio.h>
54
55 //------------------------------------------------------------------------------
56 using namespace com::sun::star::uno;
57 using namespace com::sun::star::container;
58 using namespace com::sun::star::lang;
59 using namespace com::sun::star::beans;
60 using namespace com::sun::star::sdbc;
61 using ::osl::MutexGuard;
62 using ::rtl::OUString;
63
64
65 #define MYSQLC_URI_PREFIX "sdbc:mysqlc:"
66
67
68 /* {{{ OConnection::OConnection() -I- */
OConnection(MysqlCDriver & _rDriver,sql::Driver * _cppDriver)69 OConnection::OConnection(MysqlCDriver& _rDriver, sql::Driver * _cppDriver)
70 :OMetaConnection_BASE(m_aMutex)
71 ,OSubComponent<OConnection, OConnection_BASE>((::cppu::OWeakObject*)&_rDriver, this)
72 ,m_xMetaData(NULL)
73 ,m_rDriver(_rDriver)
74 ,cppDriver(_cppDriver)
75 ,m_bClosed(sal_False)
76 ,m_bUseCatalog(sal_False)
77 ,m_bUseOldDateFormat(sal_False)
78 {
79 OSL_TRACE("OConnection::OConnection");
80 m_rDriver.acquire();
81 }
82 /* }}} */
83
84
85 /* {{{ OConnection::OConnection() -I- */
~OConnection()86 OConnection::~OConnection()
87 {
88 OSL_TRACE("OConnection::~OConnection");
89 if (!isClosed()) {
90 close();
91 }
92 m_rDriver.release();
93 }
94 /* }}} */
95
96
97 /* {{{ OConnection::release() -I- */
release()98 void SAL_CALL OConnection::release()
99 throw()
100 {
101 OSL_TRACE("OConnection::release");
102 relase_ChildImpl();
103 }
104 /* }}} */
105
106 #ifndef SYSTEM_MYSQL
thisModule()107 extern "C" { void SAL_CALL thisModule() {} }
108 #endif
109
110 /* {{{ OConnection::construct() -I- */
construct(const OUString & url,const Sequence<PropertyValue> & info)111 void OConnection::construct(const OUString& url, const Sequence< PropertyValue >& info)
112 throw(SQLException)
113 {
114 OSL_TRACE("OConnection::construct");
115 MutexGuard aGuard(m_aMutex);
116
117 sal_Int32 nIndex;
118 sal_Bool bEmbedded = sal_False;
119 OUString token;
120 OUString aHostName(RTL_CONSTASCII_USTRINGPARAM("localhost"));
121 sal_Int32 nPort = 3306;
122 OUString aDbName;
123
124 m_settings.encoding = m_rDriver.getDefaultEncoding();
125 m_settings.quoteIdentifier = OUString();
126
127 // parse url. Url has the following format:
128 // external server: sdbc:mysqlc:[hostname]:[port]/[dbname]
129
130 if (!url.compareTo(OUString::createFromAscii(MYSQLC_URI_PREFIX), sizeof(MYSQLC_URI_PREFIX)-1)) {
131 nIndex = 12;
132 } else {
133 bEmbedded = sal_True;
134 nIndex = 20;
135 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OConnection::construct (embedded MySQL)", *this);
136 }
137
138 token = url.getToken(0, '/', nIndex);
139 if (token.getLength()) {
140 sal_Int32 nIndex1 = 0;
141 OUString hostandport = token.getToken(0,':', nIndex1);
142 if (hostandport.getLength()) {
143 aHostName = hostandport;
144 hostandport = token.getToken(0, ':', nIndex1);
145 if (hostandport.getLength() && nIndex1) {
146 nPort = hostandport.toInt32();
147 }
148 token = url.getToken(0, '/', nIndex);
149 if (token.getLength() && nIndex) {
150 aDbName = token;
151 }
152 }
153 }
154
155 // get user and password for mysql connection
156 const PropertyValue *pIter = info.getConstArray();
157 const PropertyValue *pEnd = pIter + info.getLength();
158 OUString aUser, aPass, sUnixSocket, sNamedPipe;
159 bool unixSocketPassed = false;
160 bool namedPipePassed = false;
161
162 m_settings.connectionURL = url;
163 for (;pIter != pEnd;++pIter) {
164 if (!pIter->Name.compareToAscii("user")) {
165 OSL_VERIFY( pIter->Value >>= aUser );
166 } else if (!pIter->Name.compareToAscii("password")) {
167 OSL_VERIFY( pIter->Value >>= aPass );
168 } else if (!pIter->Name.compareToAscii("LocalSocket")) {
169 OSL_VERIFY( pIter->Value >>= sUnixSocket );
170 unixSocketPassed = true;
171 } else if (!pIter->Name.compareToAscii("NamedPipe")) {
172 OSL_VERIFY( pIter->Value >>= sNamedPipe );
173 namedPipePassed = true;
174 } else if ( !pIter->Name.compareToAscii("PublicConnectionURL")) {
175 OSL_VERIFY( pIter->Value >>= m_settings.connectionURL );
176 } else if ( !pIter->Name.compareToAscii("NewURL")) { // legacy name for "PublicConnectionURL"
177 OSL_VERIFY( pIter->Value >>= m_settings.connectionURL );
178 }
179 }
180
181 if (bEmbedded == sal_False) {
182 try {
183 sql::ConnectOptionsMap connProps;
184 ext_std::string host_str = OUStringToOString(aHostName, m_settings.encoding).getStr();
185 ext_std::string user_str = OUStringToOString(aUser, m_settings.encoding).getStr();
186 ext_std::string pass_str = OUStringToOString(aPass, m_settings.encoding).getStr();
187 ext_std::string schema_str = OUStringToOString(aDbName, m_settings.encoding).getStr();
188 connProps["hostName"] = sql::ConnectPropertyVal(host_str);
189 connProps["userName"] = sql::ConnectPropertyVal(user_str);
190 connProps["password"] = sql::ConnectPropertyVal(pass_str);
191 connProps["schema"] = sql::ConnectPropertyVal(schema_str);
192 connProps["port"] = sql::ConnectPropertyVal((int)(nPort));
193 if (unixSocketPassed) {
194 sql::SQLString socket_str = OUStringToOString(sUnixSocket, m_settings.encoding).getStr();
195 connProps["socket"] = socket_str;
196 } else if (namedPipePassed) {
197 sql::SQLString pipe_str = OUStringToOString(sNamedPipe, m_settings.encoding).getStr();
198 connProps["socket"] = pipe_str;
199 }
200
201 #ifndef SYSTEM_MYSQL
202 ::rtl::OUString sMySQLClientLib( RTL_CONSTASCII_USTRINGPARAM( MYSQL_LIB ) );
203
204 ::rtl::OUString moduleBase;
205 OSL_VERIFY( ::osl::Module::getUrlFromAddress( &thisModule, moduleBase ) );
206 ::rtl::OUString sMySQLClientLibURL;
207 try
208 {
209 sMySQLClientLibURL = ::rtl::Uri::convertRelToAbs( moduleBase, sMySQLClientLib.pData );
210 }
211 catch ( const ::rtl::MalformedUriException& e )
212 {
213 (void)e; // silence compiler
214 #if OSL_DEBUG_LEVEL > 0
215 ::rtl::OString sMessage( "OConnection::construct: malformed URI: " );
216 sMessage += ::rtl::OUStringToOString( e.getMessage(), osl_getThreadTextEncoding() );
217 OSL_ENSURE( false, sMessage.getStr() );
218 #endif
219 }
220
221 ::rtl::OUString sMySQLClientLibPath;
222 osl_getSystemPathFromFileURL( sMySQLClientLibURL.pData, &sMySQLClientLibPath.pData );
223
224 sql::SQLString mysqlLib = ::rtl::OUStringToOString( sMySQLClientLibPath, osl_getThreadTextEncoding() ).getStr();
225 connProps["clientlib"] = mysqlLib;
226
227 OSL_TRACE("clientlib=%s", mysqlLib.c_str());
228 #endif
229
230 OSL_TRACE("hostName=%s", host_str.c_str());
231 OSL_TRACE("port=%i", int(nPort));
232 OSL_TRACE("userName=%s", user_str.c_str());
233 OSL_TRACE("password=%s", pass_str.c_str());
234 OSL_TRACE("schema=%s", schema_str.c_str());
235
236 m_settings.cppConnection.reset(cppDriver->connect(connProps));
237 } catch (sql::SQLException &e) {
238 mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
239 }
240 } else {
241 // TODO: support for embedded server
242 }
243
244 m_settings.schema = aDbName;
245 OSL_TRACE(OUStringToOString(m_settings.schema, getConnectionEncoding()).getStr());
246
247 // Check if the server is 4.1 or above
248 if (this->getMysqlVersion() < 40100) {
249 throw SQLException(
250 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MySQL Connector/OO.org requires MySQL Server 4.1 or above" ) ),
251 *this,
252 ::rtl::OUString(),
253 0,
254 Any());
255 }
256 std::auto_ptr<sql::Statement> stmt(m_settings.cppConnection->createStatement());
257 stmt->executeUpdate("SET session sql_mode='ANSI_QUOTES'");
258 stmt->executeUpdate("SET NAMES utf8");
259 }
260 /* }}} */
261
262
263 // XServiceInfo
264 IMPLEMENT_SERVICE_INFO(OConnection, "com.sun.star.sdbc.drivers.mysqlc.OConnection", "com.sun.star.sdbc.Connection")
265
266
267 /* {{{ OConnection::createStatement() -I- */
createStatement()268 Reference< XStatement > SAL_CALL OConnection::createStatement()
269 throw(SQLException, RuntimeException)
270 {
271 OSL_TRACE("OConnection::createStatement");
272 MutexGuard aGuard(m_aMutex);
273 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
274
275 // create a statement
276 Reference< XStatement > xReturn;
277 // the statement can only be executed once
278 try {
279 xReturn = new OStatement(this, m_settings.cppConnection->createStatement());
280 m_aStatements.push_back(WeakReferenceHelper(xReturn));
281 return xReturn;
282 } catch (sql::SQLException & e) {
283 mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
284 }
285 return xReturn;
286 }
287 /* }}} */
288
289
290 /* {{{ OConnection::createStatement() -I- */
prepareStatement(const OUString & _sSql)291 Reference< XPreparedStatement > SAL_CALL OConnection::prepareStatement(const OUString& _sSql)
292 throw(SQLException, RuntimeException)
293 {
294 OSL_TRACE("OConnection::prepareStatement");
295 MutexGuard aGuard(m_aMutex);
296 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
297 const ::rtl::OUString sSqlStatement = transFormPreparedStatement( _sSql );
298
299 Reference< XPreparedStatement > xStatement;
300 try {
301 // create a statement
302 // the statement can only be executed more than once
303 xStatement = new OPreparedStatement(this,
304 m_settings.cppConnection->prepareStatement(OUStringToOString(sSqlStatement, getConnectionEncoding()).getStr()));
305 m_aStatements.push_back( WeakReferenceHelper( xStatement ) );
306 } catch (sql::SQLException & e) {
307 mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
308 }
309 return xStatement;
310 }
311 /* }}} */
312
313
314 /* {{{ OConnection::prepareCall() -U- */
prepareCall(const OUString &)315 Reference< XPreparedStatement > SAL_CALL OConnection::prepareCall(const OUString& /*_sSql*/ )
316 throw(SQLException, RuntimeException)
317 {
318 OSL_TRACE("OConnection::prepareCall");
319 MutexGuard aGuard(m_aMutex);
320 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
321
322 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OConnection::prepareCall", *this);
323 return Reference< XPreparedStatement >();
324 }
325 /* }}} */
326
327
328 /* {{{ OConnection::nativeSQL() -I- */
nativeSQL(const OUString & _sSql)329 OUString SAL_CALL OConnection::nativeSQL(const OUString& _sSql)
330 throw(SQLException, RuntimeException)
331 {
332 OSL_TRACE("OConnection::nativeSQL");
333 MutexGuard aGuard(m_aMutex);
334
335 const ::rtl::OUString sSqlStatement = transFormPreparedStatement( _sSql );
336 ::rtl::OUString sNativeSQL;
337 try {
338 sNativeSQL = mysqlc_sdbc_driver::convert(m_settings.cppConnection->nativeSQL(mysqlc_sdbc_driver::convert(sSqlStatement, getConnectionEncoding())),
339 getConnectionEncoding());
340 } catch (sql::SQLException & e) {
341 mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
342 }
343 return sNativeSQL;
344 }
345 /* }}} */
346
347
348 /* {{{ OConnection::setAutoCommit() -I- */
setAutoCommit(sal_Bool autoCommit)349 void SAL_CALL OConnection::setAutoCommit(sal_Bool autoCommit)
350 throw(SQLException, RuntimeException)
351 {
352 OSL_TRACE("OConnection::setAutoCommit");
353 MutexGuard aGuard(m_aMutex);
354 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
355 try {
356 m_settings.cppConnection->setAutoCommit(autoCommit == sal_True? true:false);
357 } catch (sql::SQLException & e) {
358 mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
359 }
360 }
361 /* }}} */
362
363
364 /* {{{ OConnection::getAutoCommit() -I- */
getAutoCommit()365 sal_Bool SAL_CALL OConnection::getAutoCommit()
366 throw(SQLException, RuntimeException)
367 {
368 OSL_TRACE("OConnection::getAutoCommit");
369 // you have to distinguish which if you are in autocommit mode or not
370 // at normal case true should be fine here
371
372 MutexGuard aGuard(m_aMutex);
373 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
374
375 sal_Bool autoCommit = sal_False;
376 try {
377 autoCommit = m_settings.cppConnection->getAutoCommit() == true ? sal_True : sal_False;
378 } catch (sql::SQLException & e) {
379 mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
380 }
381 return autoCommit;
382 }
383 /* }}} */
384
385
386 /* {{{ OConnection::commit() -I- */
commit()387 void SAL_CALL OConnection::commit()
388 throw(SQLException, RuntimeException)
389 {
390 OSL_TRACE("OConnection::commit");
391 MutexGuard aGuard(m_aMutex);
392 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
393 try {
394 m_settings.cppConnection->commit();
395 } catch (sql::SQLException & e) {
396 mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
397 }
398 }
399 /* }}} */
400
401
402 /* {{{ OConnection::rollback() -I- */
rollback()403 void SAL_CALL OConnection::rollback()
404 throw(SQLException, RuntimeException)
405 {
406 OSL_TRACE("OConnection::rollback");
407 MutexGuard aGuard(m_aMutex);
408 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
409 try {
410 m_settings.cppConnection->rollback();
411 } catch (sql::SQLException & e) {
412 mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
413 }
414 }
415 /* }}} */
416
417
418 /* {{{ OConnection::isClosed() -I- */
isClosed()419 sal_Bool SAL_CALL OConnection::isClosed()
420 throw(SQLException, RuntimeException)
421 {
422 OSL_TRACE("OConnection::isClosed");
423 MutexGuard aGuard(m_aMutex);
424
425 // just simple -> we are close when we are disposed that means someone called dispose(); (XComponent)
426 return (OConnection_BASE::rBHelper.bDisposed);
427 }
428 /* }}} */
429
430
431 /* {{{ OConnection::createStatement() -I- */
getMetaData()432 Reference< XDatabaseMetaData > SAL_CALL OConnection::getMetaData()
433 throw(SQLException, RuntimeException)
434 {
435 OSL_TRACE("OConnection::getMetaData");
436 MutexGuard aGuard(m_aMutex);
437 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
438
439 Reference< XDatabaseMetaData > xMetaData = m_xMetaData;
440 if (!xMetaData.is()) {
441 try {
442 xMetaData = new ODatabaseMetaData(*this); // need the connection because it can return it
443 } catch (sql::SQLException & e) {
444 mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
445 }
446 m_xMetaData = xMetaData;
447 }
448
449 return xMetaData;
450 }
451 /* }}} */
452
453
454 /* {{{ OConnection::createStatement() -I- */
setReadOnly(sal_Bool readOnly)455 void SAL_CALL OConnection::setReadOnly(sal_Bool readOnly)
456 throw(SQLException, RuntimeException)
457 {
458 OSL_TRACE("OConnection::setReadOnly");
459 MutexGuard aGuard(m_aMutex);
460 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
461
462 m_settings.readOnly = readOnly;
463 }
464 /* }}} */
465
466
467 /* {{{ OConnection::createStatement() -I- */
isReadOnly()468 sal_Bool SAL_CALL OConnection::isReadOnly()
469 throw(SQLException, RuntimeException)
470 {
471 OSL_TRACE("OConnection::isReadOnly");
472 MutexGuard aGuard(m_aMutex);
473 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
474
475 // return if your connection to readonly
476 return (m_settings.readOnly);
477 }
478 /* }}} */
479
480
481 /* {{{ OConnection::createStatement() -I- */
setCatalog(const OUString & catalog)482 void SAL_CALL OConnection::setCatalog(const OUString& catalog)
483 throw(SQLException, RuntimeException)
484 {
485 OSL_TRACE("OConnection::setCatalog");
486 MutexGuard aGuard(m_aMutex);
487 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
488
489 try {
490 // m_settings.cppConnection->setCatalog(OUStringToOString(catalog, m_settings.encoding).getStr());
491 m_settings.cppConnection->setSchema(OUStringToOString(catalog, getConnectionEncoding()).getStr());
492 } catch (sql::SQLException & e) {
493 mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
494 }
495 }
496 /* }}} */
497
498
499 /* {{{ OConnection::createStatement() -I- */
getCatalog()500 OUString SAL_CALL OConnection::getCatalog()
501 throw(SQLException, RuntimeException)
502 {
503 OSL_TRACE("OConnection::getCatalog");
504 MutexGuard aGuard(m_aMutex);
505 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
506
507 OUString catalog;
508 try {
509 catalog = mysqlc_sdbc_driver::convert(m_settings.cppConnection->getSchema(), getConnectionEncoding());
510 } catch (sql::SQLException & e) {
511 mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
512 }
513 return catalog;
514 }
515 /* }}} */
516
517
518 /* {{{ OConnection::createStatement() -I- */
setTransactionIsolation(sal_Int32 level)519 void SAL_CALL OConnection::setTransactionIsolation(sal_Int32 level)
520 throw(SQLException, RuntimeException)
521 {
522 OSL_TRACE("OConnection::setTransactionIsolation");
523 MutexGuard aGuard(m_aMutex);
524 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
525
526 sql::enum_transaction_isolation cpplevel = sql::TRANSACTION_SERIALIZABLE;
527
528 switch (level) {
529 case TransactionIsolation::READ_UNCOMMITTED:
530 cpplevel = sql::TRANSACTION_READ_UNCOMMITTED;
531 break;
532 case TransactionIsolation::READ_COMMITTED:
533 cpplevel = sql::TRANSACTION_READ_COMMITTED;
534 break;
535 case TransactionIsolation::REPEATABLE_READ:
536 cpplevel = sql::TRANSACTION_REPEATABLE_READ;
537 break;
538 case TransactionIsolation::SERIALIZABLE:
539 cpplevel = sql::TRANSACTION_SERIALIZABLE;
540 break;
541 case TransactionIsolation::NONE:
542 cpplevel = sql::TRANSACTION_SERIALIZABLE;
543 break;
544 default:;
545 /* XXX: Exception ?? */
546 }
547 try {
548 m_settings.cppConnection->setTransactionIsolation(cpplevel);
549 } catch (sql::SQLException & e) {
550 mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
551 }
552 }
553 /* }}} */
554
555
556 /* {{{ OConnection::createStatement() -I- */
getTransactionIsolation()557 sal_Int32 SAL_CALL OConnection::getTransactionIsolation()
558 throw(SQLException, RuntimeException)
559 {
560 OSL_TRACE("OConnection::getTransactionIsolation");
561 MutexGuard aGuard(m_aMutex);
562 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
563
564 try {
565 switch (m_settings.cppConnection->getTransactionIsolation()) {
566 case sql::TRANSACTION_SERIALIZABLE: return TransactionIsolation::SERIALIZABLE;
567 case sql::TRANSACTION_REPEATABLE_READ: return TransactionIsolation::REPEATABLE_READ;
568 case sql::TRANSACTION_READ_COMMITTED: return TransactionIsolation::READ_COMMITTED;
569 case sql::TRANSACTION_READ_UNCOMMITTED: return TransactionIsolation::READ_UNCOMMITTED;
570 default:
571 ;
572 }
573 } catch (sql::SQLException & e) {
574 mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
575 }
576 return TransactionIsolation::NONE;
577 }
578 /* }}} */
579
580
581 /* {{{ OConnection::getTypeMap() -I- */
getTypeMap()582 Reference<XNameAccess> SAL_CALL OConnection::getTypeMap()
583 throw(SQLException, RuntimeException)
584 {
585 OSL_TRACE("OConnection::getTypeMap");
586 MutexGuard aGuard(m_aMutex);
587 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
588
589 Reference<XNameAccess > t;
590 {
591 t = m_typeMap;
592 }
593 return (t);
594 }
595 /* }}} */
596
597
598 /* {{{ OConnection::setTypeMap() -I- */
setTypeMap(const Reference<XNameAccess> & typeMap)599 void SAL_CALL OConnection::setTypeMap(const Reference<XNameAccess >& typeMap)
600 throw(SQLException, RuntimeException)
601 {
602 OSL_TRACE("OConnection::setTypeMap");
603 MutexGuard aGuard(m_aMutex);
604 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
605
606 m_typeMap = typeMap;
607 }
608 /* }}} */
609
610
611 // XCloseable
612 /* {{{ OConnection::close() -I- */
close()613 void SAL_CALL OConnection::close()
614 throw(SQLException, RuntimeException)
615 {
616 OSL_TRACE("OConnection::close");
617 /*
618 we need block, because the mutex is a local variable,
619 which will guard the block
620 */
621 {
622 // we just dispose us
623 MutexGuard aGuard(m_aMutex);
624 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
625 }
626 dispose();
627 }
628 /* }}} */
629
630
631 // XWarningsSupplier
632 /* {{{ OConnection::getWarnings() -I- */
getWarnings()633 Any SAL_CALL OConnection::getWarnings()
634 throw(SQLException, RuntimeException)
635 {
636 Any x = Any();
637 OSL_TRACE("OConnection::getWarnings");
638 // when you collected some warnings -> return it
639 return x;
640 }
641 /* }}} */
642
643
644 /* {{{ OConnection::clearWarnings() -I- */
clearWarnings()645 void SAL_CALL OConnection::clearWarnings()
646 throw(SQLException, RuntimeException)
647 {
648 OSL_TRACE("OConnection::clearWarnings");
649 // you should clear your collected warnings here#
650 }
651 /* }}} */
652
653
654 /* {{{ OConnection::buildTypeInfo() -I- */
buildTypeInfo()655 void OConnection::buildTypeInfo()
656 throw(SQLException)
657 {
658 OSL_TRACE("OConnection::buildTypeInfo");
659 }
660 /* }}} */
661
662
663 /* {{{ OConnection::disposing() -I- */
disposing()664 void OConnection::disposing()
665 {
666 OSL_TRACE("OConnection::disposing");
667 // we noticed that we should be destroied in near future so we have to dispose our statements
668 MutexGuard aGuard(m_aMutex);
669
670 for (OWeakRefArray::iterator i = m_aStatements.begin(); i != m_aStatements.end() ; ++i) {
671 Reference< XComponent > xComp(i->get(), UNO_QUERY);
672 if (xComp.is()) {
673 xComp->dispose();
674 }
675 }
676 m_aStatements.clear();
677
678 m_bClosed = sal_True;
679 m_xMetaData = WeakReference< XDatabaseMetaData >();
680
681 dispose_ChildImpl();
682 OConnection_BASE::disposing();
683 }
684 /* }}} */
685
686
687 /* ToDo - upcast the connection to MySQL_Connection and use ::getSessionVariable() */
688
689 /* {{{ OConnection::getMysqlVariable() -I- */
getMysqlVariable(const char * varname)690 OUString OConnection::getMysqlVariable(const char *varname)
691 throw(SQLException, RuntimeException)
692 {
693 OSL_TRACE("OConnection::getMysqlVariable");
694 MutexGuard aGuard(m_aMutex);
695 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
696
697 OUString ret;
698 ::rtl::OUStringBuffer aStatement;
699 aStatement.appendAscii( "SHOW SESSION VARIABLES LIKE '" );
700 aStatement.appendAscii( varname );
701 aStatement.append( sal_Unicode( '\'' ) );
702
703 try {
704 XStatement * stmt = new OStatement(this, m_settings.cppConnection->createStatement());
705 Reference< XResultSet > rs = stmt->executeQuery( aStatement.makeStringAndClear() );
706 if (rs.is() && rs->next()) {
707 Reference< XRow > xRow(rs, UNO_QUERY);
708 ret = xRow->getString(2);
709 }
710 } catch (sql::SQLException & e) {
711 mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
712 }
713
714 return ret;
715 }
716 /* }}} */
717
718
719 /* {{{ OConnection::getMysqlVersion() -I- */
getMysqlVersion()720 sal_Int32 OConnection::getMysqlVersion()
721 throw(SQLException, RuntimeException)
722 {
723 OSL_TRACE("OConnection::getMysqlVersion");
724 MutexGuard aGuard(m_aMutex);
725 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
726
727 sal_Int32 version(0);
728 try {
729 version = 10000 * m_settings.cppConnection->getMetaData()->getDatabaseMajorVersion();
730 version += 100 * m_settings.cppConnection->getMetaData()->getDatabaseMinorVersion();
731 version += m_settings.cppConnection->getMetaData()->getDatabasePatchVersion();
732 } catch (sql::SQLException & e) {
733 mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
734 }
735 return version;
736 }
737 /* }}} */
738
739
740 /* {{{ OConnection::sdbcColumnType() -I- */
741 // TODO: Not used
742 //sal_Int32 OConnection::sdbcColumnType(OUString typeName)
743 //{
744 // OSL_TRACE("OConnection::sdbcColumnType");
745 // int i = 0;
746 // while (mysqlc_types[i].typeName) {
747 // if (OUString::createFromAscii(mysqlc_types[i].typeName).equals(
748 // typeName.toAsciiUpperCase()))
749 // {
750 // return mysqlc_types[i].dataType;
751 // }
752 // i++;
753 // }
754 // return 0;
755 //}
756 // -----------------------------------------------------------------------------
transFormPreparedStatement(const::rtl::OUString & _sSQL)757 ::rtl::OUString OConnection::transFormPreparedStatement(const ::rtl::OUString& _sSQL)
758 {
759 ::rtl::OUString sSqlStatement = _sSQL;
760 if ( !m_xParameterSubstitution.is() ) {
761 try {
762 Sequence< Any > aArgs(1);
763 Reference< XConnection> xCon = this;
764 aArgs[0] <<= NamedValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ActiveConnection")), makeAny(xCon));
765
766 m_xParameterSubstitution.set(m_rDriver.getFactory()->createInstanceWithArguments(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.helper.ParameterSubstitution")),aArgs),UNO_QUERY);
767 } catch(const Exception&) {}
768 }
769 if ( m_xParameterSubstitution.is() ) {
770 try {
771 sSqlStatement = m_xParameterSubstitution->substituteVariables(sSqlStatement,sal_True);
772 } catch(const Exception&) { }
773 }
774 return sSqlStatement;
775 }
776
777 /* }}} */
778
779 /*
780 * Local variables:
781 * tab-width: 4
782 * c-basic-offset: 4
783 * End:
784 * vim600: noet sw=4 ts=4 fdm=marker
785 * vim<600: noet sw=4 ts=4
786 */
787