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