1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_connectivity.hxx" 30 31 #include "KConnection.hxx" 32 #include "KDatabaseMetaData.hxx" 33 #include "KStatement.hxx" 34 #include "KPreparedStatement.hxx" 35 #include "KDriver.hxx" 36 #include "KCatalog.hxx" 37 #include <com/sun/star/sdbc/ColumnValue.hpp> 38 #include <com/sun/star/sdbc/TransactionIsolation.hpp> 39 #include <shell/kde_headers.h> 40 41 using namespace connectivity::kab; 42 using namespace com::sun::star::uno; 43 using namespace com::sun::star::lang; 44 using namespace com::sun::star::beans; 45 using namespace com::sun::star::sdbc; 46 using namespace com::sun::star::sdbcx; 47 48 IMPLEMENT_SERVICE_INFO(KabConnection, "com.sun.star.sdbc.drivers.KabConnection", "com.sun.star.sdbc.Connection") 49 //----------------------------------------------------------------------------- 50 KabConnection::KabConnection(KabDriver* _pDriver) 51 : OMetaConnection_BASE(m_aMutex), 52 OSubComponent<KabConnection, KabConnection_BASE>((::cppu::OWeakObject*)_pDriver, this), 53 m_xMetaData(NULL), 54 m_pAddressBook(NULL), 55 m_pDriver(_pDriver) 56 { 57 m_pDriver->acquire(); 58 } 59 //----------------------------------------------------------------------------- 60 KabConnection::~KabConnection() 61 { 62 if (!isClosed()) 63 close(); 64 65 m_pDriver->release(); 66 m_pDriver = NULL; 67 } 68 //----------------------------------------------------------------------------- 69 void SAL_CALL KabConnection::release() throw() 70 { 71 relase_ChildImpl(); 72 } 73 // ----------------------------------------------------------------------------- 74 void KabConnection::construct(const ::rtl::OUString&, const Sequence< PropertyValue >&) throw(SQLException) 75 { 76 osl_incrementInterlockedCount( &m_refCount ); 77 78 // create a KDE address book object 79 m_pAddressBook = KABC::StdAddressBook::self(); 80 m_pAddressBook->setAutomaticSave(false); 81 // perharps we should analyze the URL to know whether the addressbook is local, over LDAP, etc... 82 // perharps we should get some user and password information from "info" properties 83 84 osl_decrementInterlockedCount( &m_refCount ); 85 } 86 // XServiceInfo 87 // -------------------------------------------------------------------------------- 88 Reference< XStatement > SAL_CALL KabConnection::createStatement( ) throw(SQLException, RuntimeException) 89 { 90 ::osl::MutexGuard aGuard( m_aMutex ); 91 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 92 93 // create a statement 94 // the statement can only be executed once 95 Reference< XStatement > xReturn = new KabStatement(this); 96 m_aStatements.push_back(WeakReferenceHelper(xReturn)); 97 return xReturn; 98 } 99 // -------------------------------------------------------------------------------- 100 Reference< XPreparedStatement > SAL_CALL KabConnection::prepareStatement( const ::rtl::OUString& _sSql ) throw(SQLException, RuntimeException) 101 { 102 ::osl::MutexGuard aGuard( m_aMutex ); 103 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 104 105 // create a statement 106 // the statement can only be executed more than once 107 Reference< XPreparedStatement > xReturn = new KabPreparedStatement(this, _sSql); 108 m_aStatements.push_back(WeakReferenceHelper(xReturn)); 109 return xReturn; 110 } 111 // -------------------------------------------------------------------------------- 112 Reference< XPreparedStatement > SAL_CALL KabConnection::prepareCall( const ::rtl::OUString& ) throw(SQLException, RuntimeException) 113 { 114 ::osl::MutexGuard aGuard( m_aMutex ); 115 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 116 117 // not implemented yet :-) a task to do 118 return NULL; 119 } 120 // -------------------------------------------------------------------------------- 121 ::rtl::OUString SAL_CALL KabConnection::nativeSQL( const ::rtl::OUString& _sSql ) throw(SQLException, RuntimeException) 122 { 123 ::osl::MutexGuard aGuard( m_aMutex ); 124 // when you need to transform SQL92 to you driver specific you can do it here 125 126 return _sSql; 127 } 128 // -------------------------------------------------------------------------------- 129 void SAL_CALL KabConnection::setAutoCommit( sal_Bool ) throw(SQLException, RuntimeException) 130 { 131 ::osl::MutexGuard aGuard( m_aMutex ); 132 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 133 // here you have to set your commit mode please have a look at the jdbc documentation to get a clear explanation 134 } 135 // -------------------------------------------------------------------------------- 136 sal_Bool SAL_CALL KabConnection::getAutoCommit( ) throw(SQLException, RuntimeException) 137 { 138 ::osl::MutexGuard aGuard( m_aMutex ); 139 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 140 // you have to distinguish which if you are in autocommit mode or not 141 // at normal case true should be fine here 142 143 return sal_True; 144 } 145 // -------------------------------------------------------------------------------- 146 void SAL_CALL KabConnection::commit( ) throw(SQLException, RuntimeException) 147 { 148 ::osl::MutexGuard aGuard( m_aMutex ); 149 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 150 151 // when you database does support transactions you should commit here 152 } 153 // -------------------------------------------------------------------------------- 154 void SAL_CALL KabConnection::rollback( ) throw(SQLException, RuntimeException) 155 { 156 ::osl::MutexGuard aGuard( m_aMutex ); 157 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 158 159 // same as commit but for the other case 160 } 161 // -------------------------------------------------------------------------------- 162 sal_Bool SAL_CALL KabConnection::isClosed( ) throw(SQLException, RuntimeException) 163 { 164 ::osl::MutexGuard aGuard( m_aMutex ); 165 166 // just simple -> we are closed when we are disposed, that means someone called dispose(); (XComponent) 167 return KabConnection_BASE::rBHelper.bDisposed; 168 } 169 // -------------------------------------------------------------------------------- 170 Reference< XDatabaseMetaData > SAL_CALL KabConnection::getMetaData( ) throw(SQLException, RuntimeException) 171 { 172 ::osl::MutexGuard aGuard( m_aMutex ); 173 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 174 175 // here we have to create the class with biggest interface 176 // The answer is 42 :-) 177 Reference< XDatabaseMetaData > xMetaData = m_xMetaData; 178 if (!xMetaData.is()) 179 { 180 xMetaData = new KabDatabaseMetaData(this); // need the connection because it can return it 181 m_xMetaData = xMetaData; 182 } 183 184 return xMetaData; 185 } 186 // -------------------------------------------------------------------------------- 187 void SAL_CALL KabConnection::setReadOnly( sal_Bool ) throw(SQLException, RuntimeException) 188 { 189 ::osl::MutexGuard aGuard( m_aMutex ); 190 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 191 192 // set you connection to readonly 193 } 194 // -------------------------------------------------------------------------------- 195 sal_Bool SAL_CALL KabConnection::isReadOnly( ) throw(SQLException, RuntimeException) 196 { 197 ::osl::MutexGuard aGuard( m_aMutex ); 198 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 199 200 // return if your connection to readonly 201 return sal_False; 202 } 203 // -------------------------------------------------------------------------------- 204 void SAL_CALL KabConnection::setCatalog( const ::rtl::OUString& ) throw(SQLException, RuntimeException) 205 { 206 ::osl::MutexGuard aGuard( m_aMutex ); 207 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 208 209 // if your database doesn't work with catalogs you go to next method otherwise you kjnow what to do 210 } 211 // -------------------------------------------------------------------------------- 212 ::rtl::OUString SAL_CALL KabConnection::getCatalog( ) throw(SQLException, RuntimeException) 213 { 214 ::osl::MutexGuard aGuard( m_aMutex ); 215 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 216 217 218 // return your current catalog 219 return ::rtl::OUString(); 220 } 221 // -------------------------------------------------------------------------------- 222 void SAL_CALL KabConnection::setTransactionIsolation( sal_Int32 ) throw(SQLException, RuntimeException) 223 { 224 ::osl::MutexGuard aGuard( m_aMutex ); 225 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 226 227 // set your isolation level 228 // please have a look at @see com.sun.star.sdbc.TransactionIsolation 229 } 230 // -------------------------------------------------------------------------------- 231 sal_Int32 SAL_CALL KabConnection::getTransactionIsolation( ) throw(SQLException, RuntimeException) 232 { 233 ::osl::MutexGuard aGuard( m_aMutex ); 234 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 235 236 237 // please have a look at @see com.sun.star.sdbc.TransactionIsolation 238 return TransactionIsolation::NONE; 239 } 240 // -------------------------------------------------------------------------------- 241 Reference< ::com::sun::star::container::XNameAccess > SAL_CALL KabConnection::getTypeMap( ) throw(SQLException, RuntimeException) 242 { 243 ::osl::MutexGuard aGuard( m_aMutex ); 244 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 245 246 // if your driver has special database types you can return it here 247 248 return NULL; 249 } 250 // -------------------------------------------------------------------------------- 251 void SAL_CALL KabConnection::setTypeMap( const Reference< ::com::sun::star::container::XNameAccess >& ) throw(SQLException, RuntimeException) 252 { 253 // the other way around 254 } 255 // -------------------------------------------------------------------------------- 256 // XCloseable 257 void SAL_CALL KabConnection::close( ) throw(SQLException, RuntimeException) 258 { 259 { 260 ::osl::MutexGuard aGuard( m_aMutex ); 261 checkDisposed(KabConnection_BASE::rBHelper.bDisposed); 262 } 263 dispose(); 264 } 265 // -------------------------------------------------------------------------------- 266 // XWarningsSupplier 267 Any SAL_CALL KabConnection::getWarnings( ) throw(SQLException, RuntimeException) 268 { 269 // when you collected some warnings -> return it 270 return Any(); 271 } 272 // -------------------------------------------------------------------------------- 273 void SAL_CALL KabConnection::clearWarnings( ) throw(SQLException, RuntimeException) 274 { 275 // you should clear your collected warnings here 276 } 277 //------------------------------------------------------------------------------ 278 void KabConnection::disposing() 279 { 280 // we noticed that we should be destroied in near future so we have to dispose our statements 281 ::osl::MutexGuard aGuard(m_aMutex); 282 283 for (OWeakRefArray::iterator i = m_aStatements.begin(); m_aStatements.end() != i; ++i) 284 { 285 Reference< XComponent > xComp(i->get(), UNO_QUERY); 286 if (xComp.is()) 287 xComp->dispose(); 288 } 289 m_aStatements.clear(); 290 291 if (m_pAddressBook != NULL) 292 { 293 m_pAddressBook->close(); 294 m_pAddressBook = NULL; 295 } 296 297 m_xMetaData = ::com::sun::star::uno::WeakReference< ::com::sun::star::sdbc::XDatabaseMetaData>(); 298 299 dispose_ChildImpl(); 300 KabConnection_BASE::disposing(); 301 } 302 // ----------------------------------------------------------------------------- 303 Reference< XTablesSupplier > SAL_CALL KabConnection::createCatalog() 304 { 305 ::osl::MutexGuard aGuard( m_aMutex ); 306 307 Reference< XTablesSupplier > xTab = m_xCatalog; 308 if (!m_xCatalog.is()) 309 { 310 KabCatalog *pCat = new KabCatalog(this); 311 xTab = pCat; 312 m_xCatalog = xTab; 313 } 314 return xTab; 315 } 316 // ----------------------------------------------------------------------------- 317 ::KABC::AddressBook* KabConnection::getAddressBook() const 318 { 319 return m_pAddressBook; 320 } 321 // ----------------------------------------------------------------------------- 322 extern "C" SAL_DLLPUBLIC_EXPORT void* SAL_CALL createKabConnection( void* _pDriver ) 323 { 324 KabConnection* pConnection = new KabConnection( static_cast< KabDriver* >( _pDriver ) ); 325 // by definition, the pointer crossing library boundaries as void ptr is acquired once 326 pConnection->acquire(); 327 return pConnection; 328 } 329