merge the formfield patch from ooo-build
[ooovba.git] / connectivity / source / drivers / mozab / MConnection.cxx
blobf84b150e86ae744e0fdd7d5a139cba48e5785f10
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: MConnection.cxx,v $
10 * $Revision: 1.28.56.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
34 #include "diagnose_ex.h"
35 #include "MConnection.hxx"
36 #include "MDatabaseMetaData.hxx"
37 #include "MDriver.hxx"
38 #include "MColumnAlias.hxx"
39 #include "MStatement.hxx"
40 #include "MPreparedStatement.hxx"
42 #include <connectivity/dbcharset.hxx>
43 #include <connectivity/dbexception.hxx>
44 #include <connectivity/sqlerror.hxx>
46 #include "resource/mozab_res.hrc"
47 #include "resource/common_res.hrc"
49 #include <com/sun/star/sdbc/ColumnValue.hpp>
50 #include <com/sun/star/sdbc/XRow.hpp>
51 #include <com/sun/star/sdbc/TransactionIsolation.hpp>
53 #include <comphelper/officeresourcebundle.hxx>
55 #if OSL_DEBUG_LEVEL > 0
56 # define OUtoCStr( x ) ( ::rtl::OUStringToOString ( (x), RTL_TEXTENCODING_ASCII_US).getStr())
57 #else /* OSL_DEBUG_LEVEL */
58 # define OUtoCStr( x ) ("dummy")
59 #endif /* OSL_DEBUG_LEVEL */
61 extern "C" SAL_DLLPUBLIC_EXPORT void* SAL_CALL OMozabConnection_CreateInstance(
62 void* _pDriver)
64 return (new connectivity::mozab::OConnection( reinterpret_cast<connectivity::mozab::MozabDriver*>(_pDriver) ));
67 using namespace dbtools;
69 //------------------------------------------------------------------------------
70 using namespace com::sun::star::uno;
71 using namespace com::sun::star::lang;
72 using namespace com::sun::star::beans;
73 using namespace com::sun::star::sdbc;
74 using namespace com::sun::star::sdbcx;
75 // --------------------------------------------------------------------------------
77 namespace connectivity { namespace mozab {
79 // =====================================================================
80 // = ConnectionImplData
81 // =====================================================================
82 struct ConnectionImplData
84 ::boost::shared_ptr< ::comphelper::OfficeResourceBundle > pResourceBundle;
87 // -----------------------------------------------------------------------------
88 #ifdef __MINGW32__
89 extern "C"
90 #endif
91 const sal_Char* getSdbcScheme( SdbcScheme _eScheme )
93 switch ( _eScheme )
95 case SDBC_MOZILLA: return "mozilla";
96 case SDBC_THUNDERBIRD: return "thunderbird";
97 case SDBC_LDAP: return "ldap";
98 case SDBC_OUTLOOK_MAPI: return "outlook";
99 case SDBC_OUTLOOK_EXPRESS: return "outlookexp";
101 return NULL;
103 // -----------------------------------------------------------------------------
104 ::rtl::OUString OConnection::getDriverImplementationName()
106 return rtl::OUString::createFromAscii(MOZAB_DRIVER_IMPL_NAME);
109 // -----------------------------------------------------------------------------
110 const sal_Char* getSchemeURI( MozillaScheme _eScheme )
112 switch ( _eScheme )
114 case SCHEME_MOZILLA : return "moz-abdirectory://";
115 case SCHEME_MOZILLA_MDB : return "moz-abmdbdirectory://";
116 case SCHEME_LDAP : return "moz-abldapdirectory://";
117 case SCHEME_OUTLOOK_MAPI : return "moz-aboutlookdirectory://op/";
118 case SCHEME_OUTLOOK_EXPRESS : return "moz-aboutlookdirectory://oe/";
120 return NULL;
123 // -----------------------------------------------------------------------------
125 OConnection::OConnection(MozabDriver* _pDriver)
126 :OSubComponent<OConnection, OConnection_BASE>((::cppu::OWeakObject*)_pDriver, this)
127 ,m_pDriver(_pDriver)
128 ,m_pImplData( new ConnectionImplData )
129 ,m_aColumnAlias( _pDriver->getMSFactory() )
130 ,m_nMaxResultRecords( -1 )
131 ,m_aNameMapper(NULL)
132 ,m_eSDBCAddressType(SDBCAddress::Unknown)
134 m_pDriver->acquire();
137 //-----------------------------------------------------------------------------
138 OConnection::~OConnection()
140 acquire();
141 if(!isClosed())
142 close();
143 m_pDriver->release();
144 m_pDriver = NULL;
146 //-----------------------------------------------------------------------------
147 void SAL_CALL OConnection::release() throw()
149 relase_ChildImpl();
151 // -----------------------------------------------------------------------------
152 //-----------------------------------------------------------------------------
153 void OConnection::construct(const ::rtl::OUString& url,const Sequence< PropertyValue >& info) throw(SQLException)
155 OSL_TRACE("IN OConnection::construct()\n" );
156 // open file
157 setURL(url);
159 // Skip 'sdbc:mozab: part of URL
161 sal_Int32 nLen = url.indexOf(':');
162 nLen = url.indexOf(':',nLen+1);
163 OSL_ENSURE( url.copy( 0, nLen ).equalsAscii( "sdbc:address" ), "OConnection::construct: invalid start of the URI - should never have survived XDriver::acceptsURL!" );
165 ::rtl::OUString aAddrbookURI(url.copy(nLen+1));
166 // Get Scheme
167 nLen = aAddrbookURI.indexOf(':');
168 ::rtl::OUString aAddrbookScheme;
169 ::rtl::OUString sAdditionalInfo;
170 if ( nLen == -1 )
172 // There isn't any subschema: - but could be just subschema
173 if ( aAddrbookURI.getLength() > 0 )
175 aAddrbookScheme= aAddrbookURI;
177 else
179 OSL_TRACE( "No subschema given!!!\n");
180 throwSQLException( STR_URI_SYNTAX_ERROR, *this );
183 else
185 aAddrbookScheme = aAddrbookURI.copy(0, nLen);
186 sAdditionalInfo = aAddrbookURI.copy( nLen + 1 );
189 OSL_TRACE("URI = %s\n", ((OUtoCStr(aAddrbookURI)) ? (OUtoCStr(aAddrbookURI)):("NULL")) );
190 OSL_TRACE("Scheme = %s\n", ((OUtoCStr(aAddrbookScheme)) ? (OUtoCStr(aAddrbookScheme)):("NULL")) );
193 // Now we have a URI convert it to a MozillaURI
195 // The Mapping being used is:
197 // * for Mozilla
198 // "sdbc:address:mozilla:" -> abdirectory://
199 // * for LDAP
200 // "sdbc:address:ldap:" -> abldapdirectory://
201 // * for Outlook (using MAPI API)
202 // "sdbc:address:outlook:" -> aboutlookdirectory://op/
203 // * for windows system address book
204 // "sdbc:address:outlookexp:" -> aboutlookdirectory://oe/
206 m_sBindDN = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(""));
207 m_sPassword = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(""));
208 m_bUseSSL = sal_False;
210 if ( aAddrbookScheme.compareToAscii( getSdbcScheme( SDBC_MOZILLA ) ) == 0 ) {
211 m_sMozillaURI = rtl::OUString::createFromAscii( getSchemeURI( SCHEME_MOZILLA ) );
212 m_eSDBCAddressType = SDBCAddress::Mozilla;
213 if(sAdditionalInfo.getLength())
214 m_sMozillaProfile = sAdditionalInfo;
216 else
217 if ( aAddrbookScheme.compareToAscii( getSdbcScheme( SDBC_THUNDERBIRD ) ) == 0 ) {
218 //Yes. I am sure it is SCHEME_MOZILLA
219 m_sMozillaURI = rtl::OUString::createFromAscii( getSchemeURI( SCHEME_MOZILLA ) );
220 m_eSDBCAddressType = SDBCAddress::ThunderBird;
221 if(sAdditionalInfo.getLength())
222 m_sMozillaProfile = sAdditionalInfo;
224 else if ( aAddrbookScheme.compareToAscii( getSdbcScheme( SDBC_LDAP ) ) == 0 ) {
225 rtl::OUString sBaseDN;
226 sal_Int32 nPortNumber = -1;
228 m_sMozillaURI = rtl::OUString::createFromAscii( getSchemeURI( SCHEME_LDAP ) );
229 m_eSDBCAddressType = SDBCAddress::LDAP;
231 if ( !m_sHostName.getLength() )
233 // see whether the URI contains a hostname/port
234 if ( sAdditionalInfo.getLength() )
236 sal_Int32 nPortSeparator = sAdditionalInfo.indexOf( ':' );
237 if ( nPortSeparator == -1 )
238 m_sHostName = sAdditionalInfo;
239 else
241 m_sHostName = sAdditionalInfo.copy( 0, nPortSeparator );
242 nPortNumber = sAdditionalInfo.copy( nPortSeparator + 1 ).toInt32();
243 OSL_ENSURE( nPortNumber != 0, "OConnection::construct: invalid LDAP port number in the URL!" );
244 if ( nPortNumber == 0 )
245 nPortNumber = -1;
250 const PropertyValue* pInfo = info.getConstArray();
251 const PropertyValue* pInfoEnd = pInfo + info.getLength();
253 for (; pInfo != pInfoEnd; ++pInfo)
255 OSL_TRACE( "info[%d].Name = %s\n", pInfo - info.getConstArray(), OUtoCStr( pInfo->Name ) );
257 if ( 0 == pInfo->Name.compareToAscii("HostName") )
259 pInfo->Value >>= m_sHostName;
261 else if ( 0 == pInfo->Name.compareToAscii("BaseDN") )
263 pInfo->Value >>= sBaseDN;
265 else if ( 0 == pInfo->Name.compareToAscii("user") )
267 pInfo->Value >>= m_sBindDN;
269 else if ( 0 == pInfo->Name.compareToAscii("password") )
271 pInfo->Value >>= m_sPassword;
273 else if ( 0 == pInfo->Name.compareToAscii("UseSSL") )
275 pInfo->Value >>= m_bUseSSL;
277 else if ( 0 == pInfo->Name.compareToAscii("PortNumber") )
279 OSL_VERIFY( pInfo->Value >>= nPortNumber );
281 else if ( 0 == pInfo->Name.compareToAscii("MaxRowCount") )
283 pInfo->Value >>= m_nMaxResultRecords;
287 if ( m_sHostName.getLength() != 0 ) {
288 m_sMozillaURI += m_sHostName;
290 else
291 throwSQLException( STR_NO_HOSTNAME, *this );
293 if ( nPortNumber > 0 ) {
294 m_sMozillaURI += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(":") );
295 m_sMozillaURI += rtl::OUString::valueOf( nPortNumber );
298 if ( sBaseDN.getLength() != 0 ) {
299 m_sMozillaURI += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/") );
300 m_sMozillaURI += sBaseDN;
302 else
303 throwSQLException( STR_NO_BASEDN, *this );
305 // Addition of a fake query to enable the Mozilla LDAP directory to work correctly.
306 m_sMozillaURI += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("?(or(DisplayName,=,DontDoThisAtHome)))"));
309 else if ( aAddrbookScheme.compareToAscii( getSdbcScheme( SDBC_OUTLOOK_MAPI ) ) == 0 ) {
310 m_sMozillaURI = ::rtl::OUString::createFromAscii( getSchemeURI( SCHEME_OUTLOOK_MAPI ) );
311 m_eSDBCAddressType = SDBCAddress::Outlook;
313 else if ( aAddrbookScheme.compareToAscii( getSdbcScheme( SDBC_OUTLOOK_EXPRESS ) ) == 0 ) {
314 m_sMozillaURI = rtl::OUString::createFromAscii( getSchemeURI( SCHEME_OUTLOOK_EXPRESS ) );
315 m_eSDBCAddressType = SDBCAddress::OutlookExp;
317 else
319 OSL_TRACE("Invalid subschema given!!!\n");
320 throwSQLException( STR_URI_SYNTAX_ERROR, *this );
323 OSL_TRACE("Moz URI = %s, %s\n", ((OUtoCStr(m_sMozillaURI)) ? (OUtoCStr(m_sMozillaURI)):("NULL")), usesFactory() ? "uses factory" : "no factory");
324 OSL_TRACE( "\tOUT OConnection::construct()\n" );
326 MDatabaseMetaDataHelper _aDbHelper;
328 // The creation of the nsIAbDirectory i/f for LDAP doesn't actually test
329 // the validity of the connection, it's normally delayed until the query
330 // is executed, but it's a bit late then to fail...
331 if ( isLDAP() )
333 if ( !_aDbHelper.testLDAPConnection( this ) )
335 OSL_TRACE("testLDAPConnection : FAILED\n" );
336 throwSQLException( _aDbHelper.getError(), *this );
338 else
340 OSL_TRACE("testLDAPConnection : SUCCESS\n" );
344 // Test connection by getting to get the Table Names
345 ::std::vector< ::rtl::OUString > tables;
346 ::std::vector< ::rtl::OUString > types;
347 if ( !_aDbHelper.getTableStrings( this, tables, types ) )
349 throwSQLException( _aDbHelper.getError(), *this );
353 // XServiceInfo
354 // --------------------------------------------------------------------------------
355 IMPLEMENT_SERVICE_INFO(OConnection, "com.sun.star.sdbc.drivers.mozab.OConnection", "com.sun.star.sdbc.Connection")
357 // --------------------------------------------------------------------------------
358 Reference< XStatement > SAL_CALL OConnection::createStatement( ) throw(SQLException, RuntimeException)
360 ::osl::MutexGuard aGuard( m_aMutex );
361 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
363 // create a statement
364 // the statement can only be executed once
365 Reference< XStatement > xReturn = new OStatement(this);
366 m_aStatements.push_back(WeakReferenceHelper(xReturn));
367 return xReturn;
369 // --------------------------------------------------------------------------------
370 Reference< XPreparedStatement > SAL_CALL OConnection::prepareStatement( const ::rtl::OUString& _sSql ) throw(SQLException, RuntimeException)
372 ::osl::MutexGuard aGuard( m_aMutex );
373 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
375 OSL_TRACE("OConnection::prepareStatement( %s )", OUtoCStr( _sSql ) );
376 // the pre
377 // create a statement
378 // the statement can only be executed more than once
379 OPreparedStatement* pPrepared = new OPreparedStatement(this,_sSql);
380 Reference< XPreparedStatement > xReturn = pPrepared;
381 pPrepared->lateInit();
383 m_aStatements.push_back(WeakReferenceHelper(xReturn));
384 return xReturn;
386 // --------------------------------------------------------------------------------
387 Reference< XPreparedStatement > SAL_CALL OConnection::prepareCall( const ::rtl::OUString& _sSql ) throw(SQLException, RuntimeException)
389 OSL_UNUSED( _sSql );
390 ::dbtools::throwFeatureNotImplementedException( "XConnection::prepareCall", *this );
391 OSL_TRACE("OConnection::prepareCall( %s )", OUtoCStr( _sSql ) );
392 return NULL;
394 // --------------------------------------------------------------------------------
395 ::rtl::OUString SAL_CALL OConnection::nativeSQL( const ::rtl::OUString& _sSql ) throw(SQLException, RuntimeException)
397 ::osl::MutexGuard aGuard( m_aMutex );
398 // when you need to transform SQL92 to you driver specific you can do it here
399 OSL_TRACE("OConnection::nativeSQL( %s )", OUtoCStr( _sSql ) );
401 return _sSql;
403 // --------------------------------------------------------------------------------
404 void SAL_CALL OConnection::setAutoCommit( sal_Bool /*autoCommit*/ ) throw(SQLException, RuntimeException)
406 ::dbtools::throwFeatureNotImplementedException( "XConnection::setAutoCommit", *this );
408 // --------------------------------------------------------------------------------
409 sal_Bool SAL_CALL OConnection::getAutoCommit( ) throw(SQLException, RuntimeException)
411 // you have to distinguish which if you are in autocommit mode or not
412 // at normal case true should be fine here
414 return sal_True;
416 // --------------------------------------------------------------------------------
417 void SAL_CALL OConnection::commit( ) throw(SQLException, RuntimeException)
419 // when you database does support transactions you should commit here
421 // --------------------------------------------------------------------------------
422 void SAL_CALL OConnection::rollback( ) throw(SQLException, RuntimeException)
424 // same as commit but for the other case
426 // --------------------------------------------------------------------------------
427 sal_Bool SAL_CALL OConnection::isClosed( ) throw(SQLException, RuntimeException)
429 ::osl::MutexGuard aGuard( m_aMutex );
431 // just simple -> we are close when we are disposed taht means someone called dispose(); (XComponent)
432 return OConnection_BASE::rBHelper.bDisposed;
434 // --------------------------------------------------------------------------------
435 Reference< XDatabaseMetaData > SAL_CALL OConnection::getMetaData( ) throw(SQLException, RuntimeException)
437 ::osl::MutexGuard aGuard( m_aMutex );
438 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
440 // here we have to create the class with biggest interface
441 // The answer is 42 :-)
442 Reference< XDatabaseMetaData > xMetaData = m_xMetaData;
443 if(!xMetaData.is())
445 xMetaData = new ODatabaseMetaData(this); // need the connection because it can return it
446 m_xMetaData = xMetaData;
449 return xMetaData;
451 // --------------------------------------------------------------------------------
452 void SAL_CALL OConnection::setReadOnly( sal_Bool /*readOnly*/ ) throw(SQLException, RuntimeException)
454 ::dbtools::throwFeatureNotImplementedException( "XConnection::setReadOnly", *this );
456 // --------------------------------------------------------------------------------
457 sal_Bool SAL_CALL OConnection::isReadOnly( ) throw(SQLException, RuntimeException)
459 // return if your connection to readonly
460 return sal_False;
462 // --------------------------------------------------------------------------------
463 void SAL_CALL OConnection::setCatalog( const ::rtl::OUString& /*catalog*/ ) throw(SQLException, RuntimeException)
465 ::dbtools::throwFeatureNotImplementedException( "XConnection::setCatalog", *this );
467 // --------------------------------------------------------------------------------
468 ::rtl::OUString SAL_CALL OConnection::getCatalog( ) throw(SQLException, RuntimeException)
470 // return your current catalog
471 return ::rtl::OUString();
473 // --------------------------------------------------------------------------------
474 void SAL_CALL OConnection::setTransactionIsolation( sal_Int32 /*level*/ ) throw(SQLException, RuntimeException)
476 ::dbtools::throwFeatureNotImplementedException( "XConnection::setTransactionIsolation", *this );
478 // --------------------------------------------------------------------------------
479 sal_Int32 SAL_CALL OConnection::getTransactionIsolation( ) throw(SQLException, RuntimeException)
481 // please have a look at @see com.sun.star.sdbc.TransactionIsolation
482 return TransactionIsolation::NONE;
484 // --------------------------------------------------------------------------------
485 Reference< ::com::sun::star::container::XNameAccess > SAL_CALL OConnection::getTypeMap( ) throw(SQLException, RuntimeException)
487 // if your driver has special database types you can return it here
488 return NULL;
490 // --------------------------------------------------------------------------------
491 void SAL_CALL OConnection::setTypeMap( const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
493 ::dbtools::throwFeatureNotImplementedException( "XConnection::setTypeMap", *this );
495 // --------------------------------------------------------------------------------
496 // XCloseable
497 void SAL_CALL OConnection::close( ) throw(SQLException, RuntimeException)
499 // we just dispose us
501 ::osl::MutexGuard aGuard( m_aMutex );
502 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
505 dispose();
507 // --------------------------------------------------------------------------------
508 // XWarningsSupplier
509 Any SAL_CALL OConnection::getWarnings( ) throw(SQLException, RuntimeException)
511 // when you collected some warnings -> return it
512 return Any();
514 // --------------------------------------------------------------------------------
515 void SAL_CALL OConnection::clearWarnings( ) throw(SQLException, RuntimeException)
517 // you should clear your collected warnings here
519 //------------------------------------------------------------------------------
520 void OConnection::disposing()
522 // we noticed that we should be destroied in near future so we have to dispose our statements
523 ::osl::MutexGuard aGuard(m_aMutex);
525 m_pImplData->pResourceBundle.reset();
527 OConnection_BASE::disposing();
528 if ( m_aNameMapper ) {
529 MQuery::FreeNameMapper( m_aNameMapper );
530 m_aNameMapper = NULL;
533 dispose_ChildImpl();
535 // -----------------------------------------------------------------------------
537 Reference< XTablesSupplier > SAL_CALL OConnection::createCatalog()
539 OSL_TRACE("IN OConnection::createCatalog()\n" );
540 ::osl::MutexGuard aGuard( m_aMutex );
541 Reference< XTablesSupplier > xTab = m_xCatalog;
542 if(!m_xCatalog.is())
544 OCatalog *pCat = new OCatalog(this);
545 xTab = pCat;
546 m_xCatalog = xTab;
548 OSL_TRACE( "\tOUT OConnection::createCatalog()\n" );
549 return xTab;
551 // -----------------------------------------------------------------------------
553 MNameMapper* OConnection::getNameMapper ()
555 if (m_aNameMapper==NULL)
556 m_aNameMapper = MQuery::CreateNameMapper();
558 return m_aNameMapper;
561 // -----------------------------------------------------------------------------
562 void OConnection::throwSQLException( const ErrorDescriptor& _rError, const Reference< XInterface >& _rxContext )
564 if ( _rError.getResId() != 0 )
566 OSL_ENSURE( ( _rError.getErrorCondition() == 0 ),
567 "OConnection::throwSQLException: unsupported error code combination!" );
569 ::rtl::OUString sParameter( _rError.getParameter() );
570 if ( sParameter.getLength() )
572 const ::rtl::OUString sError( getResources().getResourceStringWithSubstitution(
573 _rError.getResId(),
574 "$1$", sParameter
575 ) );
576 ::dbtools::throwGenericSQLException( sError, _rxContext );
577 OSL_ENSURE( false, "OConnection::throwSQLException: unreachable (1)!" );
580 throwGenericSQLException( _rError.getResId(), _rxContext );
581 OSL_ENSURE( false, "OConnection::throwSQLException: unreachable (2)!" );
584 if ( _rError.getErrorCondition() != 0 )
586 SQLError aErrorHelper( getDriver()->getMSFactory() );
587 ::rtl::OUString sParameter( _rError.getParameter() );
588 if ( sParameter.getLength() )
589 aErrorHelper.raiseException( _rError.getErrorCondition(), _rxContext, sParameter );
590 else
591 aErrorHelper.raiseException( _rError.getErrorCondition(), _rxContext);
592 OSL_ENSURE( false, "OConnection::throwSQLException: unreachable (3)!" );
595 throwGenericSQLException( STR_UNSPECIFIED_ERROR, _rxContext );
598 // -----------------------------------------------------------------------------
599 void OConnection::throwSQLException( const sal_uInt16 _nErrorResourceId, const Reference< XInterface >& _rxContext )
601 ErrorDescriptor aError;
602 aError.setResId( _nErrorResourceId );
603 throwSQLException( aError, _rxContext );
606 } } // namespace connectivity::mozab