diff options
author | Caolán McNamara <caolanm@redhat.com> | 2014-09-25 13:56:39 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2014-09-25 17:19:37 +0100 |
commit | e01a142c5d1400ac489c2ac0c5bf7779e308434f (patch) | |
tree | 90dd112bb7d3f46f91d76a1ba2d13b8abb0f1654 /connectivity | |
parent | 763a0d8ade51685b1138377a022a36fde99acc15 (diff) |
coverity#1210000 Uncaught exception
and
coverity#1210001 Uncaught exception
Change-Id: Ia6ef659ba6e62d56813a87c3fcf0fa4a5d26d9f9
Diffstat (limited to 'connectivity')
-rw-r--r-- | connectivity/source/drivers/firebird/Connection.cxx | 424 | ||||
-rw-r--r-- | connectivity/source/drivers/firebird/Connection.hxx | 7 |
2 files changed, 232 insertions, 199 deletions
diff --git a/connectivity/source/drivers/firebird/Connection.cxx b/connectivity/source/drivers/firebird/Connection.cxx index caf62f863337..fd4b43f158fe 100644 --- a/connectivity/source/drivers/firebird/Connection.cxx +++ b/connectivity/source/drivers/firebird/Connection.cxx @@ -107,190 +107,206 @@ void SAL_CALL Connection::release() throw() } void Connection::construct(const ::rtl::OUString& url, const Sequence< PropertyValue >& info) - throw(SQLException, RuntimeException) + throw (SQLException, RuntimeException, std::exception) { osl_atomic_increment( &m_refCount ); - m_sConnectionURL = url; - - bool bIsNewDatabase = false; - OUString aStorageURL; - if (url.equals("sdbc:embedded:firebird")) + try { - m_bIsEmbedded = true; + m_sConnectionURL = url; - const PropertyValue* pIter = info.getConstArray(); - const PropertyValue* pEnd = pIter + info.getLength(); - - for (;pIter != pEnd; ++pIter) + bool bIsNewDatabase = false; + OUString aStorageURL; + if (url.equals("sdbc:embedded:firebird")) { - if ( pIter->Name == "Storage" ) + m_bIsEmbedded = true; + + const PropertyValue* pIter = info.getConstArray(); + const PropertyValue* pEnd = pIter + info.getLength(); + + for (;pIter != pEnd; ++pIter) { - m_xEmbeddedStorage.set(pIter->Value,UNO_QUERY); + if ( pIter->Name == "Storage" ) + { + m_xEmbeddedStorage.set(pIter->Value,UNO_QUERY); + } + else if ( pIter->Name == "URL" ) + { + pIter->Value >>= aStorageURL; + } + else if ( pIter->Name == "Document" ) + { + pIter->Value >>= m_xParentDocument; + } } - else if ( pIter->Name == "URL" ) + + if ( !m_xEmbeddedStorage.is() ) { - pIter->Value >>= aStorageURL; + ::connectivity::SharedResources aResources; + const OUString sMessage = aResources.getResourceString(STR_NO_STORAGE); + ::dbtools::throwGenericSQLException(sMessage ,*this); } - else if ( pIter->Name == "Document" ) + + bIsNewDatabase = !m_xEmbeddedStorage->hasElements(); + + m_pExtractedFDBFile.reset(new ::utl::TempFile(NULL, true)); + m_pExtractedFDBFile->EnableKillingFile(); + m_sFirebirdURL = m_pExtractedFDBFile->GetFileName() + "/firebird.fdb"; + + SAL_INFO("connectivity.firebird", "Temporary .fdb location: " << m_sFirebirdURL); + + if (!bIsNewDatabase) { - pIter->Value >>= m_xParentDocument; + SAL_INFO("connectivity.firebird", "Extracting .fdb from .odb" ); + if (!m_xEmbeddedStorage->isStreamElement(our_sDBLocation)) + { + ::connectivity::SharedResources aResources; + const OUString sMessage = aResources.getResourceString(STR_ERROR_NEW_VERSION); + ::dbtools::throwGenericSQLException(sMessage ,*this); + } + + Reference< XStream > xDBStream(m_xEmbeddedStorage->openStreamElement(our_sDBLocation, + ElementModes::READ)); + + uno::Reference< ucb::XSimpleFileAccess2 > xFileAccess( + ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), + uno::UNO_QUERY ); + if ( !xFileAccess.is() ) + { + ::connectivity::SharedResources aResources; + const OUString sMessage = aResources.getResourceString(STR_ERROR_NEW_VERSION); + ::dbtools::throwGenericSQLException(sMessage ,*this); + } + + xFileAccess->writeFile(m_sFirebirdURL,xDBStream->getInputStream()); } - } + // TOOO: Get DB properties from XML - if ( !m_xEmbeddedStorage.is() ) + } + // External file AND/OR remote connection + else if (url.startsWith("sdbc:firebird:")) { - ::connectivity::SharedResources aResources; - const OUString sMessage = aResources.getResourceString(STR_NO_STORAGE); - ::dbtools::throwGenericSQLException(sMessage ,*this); + m_sFirebirdURL = url.copy(OUString("sdbc:firebird:").getLength()); + if (m_sFirebirdURL.startsWith("file://")) + { + m_bIsFile = true; + uno::Reference< ucb::XSimpleFileAccess > xFileAccess( + ucb::SimpleFileAccess::create(comphelper::getProcessComponentContext()), + uno::UNO_QUERY); + if (!xFileAccess->exists(m_sFirebirdURL)) + bIsNewDatabase = true; + + m_sFirebirdURL = m_sFirebirdURL.copy(OUString("file://").getLength()); + } } - bIsNewDatabase = !m_xEmbeddedStorage->hasElements(); + char dpbBuffer[1 + 3 + 257 + 257 ]; // Expand as needed + int dpbLength = 0; + { + char* dpb; + char userName[256] = ""; + char userPassword[256] = ""; - m_pExtractedFDBFile.reset(new ::utl::TempFile(NULL, true)); - m_pExtractedFDBFile->EnableKillingFile(); - m_sFirebirdURL = m_pExtractedFDBFile->GetFileName() + "/firebird.fdb"; + dpb = dpbBuffer; + *dpb++ = isc_dpb_version1; - SAL_INFO("connectivity.firebird", "Temporary .fdb location: " << m_sFirebirdURL); + *dpb++ = isc_dpb_sql_dialect; + *dpb++ = 1; // 1 byte long + *dpb++ = FIREBIRD_SQL_DIALECT; + // Do any more dpbBuffer additions here - if (!bIsNewDatabase) - { - SAL_INFO("connectivity.firebird", "Extracting .fdb from .odb" ); - if (!m_xEmbeddedStorage->isStreamElement(our_sDBLocation)) + if (m_bIsEmbedded || m_bIsFile) { - ::connectivity::SharedResources aResources; - const OUString sMessage = aResources.getResourceString(STR_ERROR_NEW_VERSION); - ::dbtools::throwGenericSQLException(sMessage ,*this); + *dpb++ = isc_dpb_trusted_auth; + *dpb++ = 1; // Length of data + *dpb++ = 1; // TRUE + } + else + { + // TODO: parse password from connection string as needed? } - Reference< XStream > xDBStream(m_xEmbeddedStorage->openStreamElement(our_sDBLocation, - ElementModes::READ)); - - uno::Reference< ucb::XSimpleFileAccess2 > xFileAccess( - ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), - uno::UNO_QUERY ); - if ( !xFileAccess.is() ) + if (strlen(userName)) { - ::connectivity::SharedResources aResources; - const OUString sMessage = aResources.getResourceString(STR_ERROR_NEW_VERSION); - ::dbtools::throwGenericSQLException(sMessage ,*this); + int nUsernameLength = strlen(userName); + *dpb++ = isc_dpb_user_name; + *dpb++ = (char) nUsernameLength; + strcpy(dpb, userName); + dpb+= nUsernameLength; } - xFileAccess->writeFile(m_sFirebirdURL,xDBStream->getInputStream()); - } - // TOOO: Get DB properties from XML + if (strlen(userPassword)) + { + int nPasswordLength = strlen(userPassword); + *dpb++ = isc_dpb_password; + *dpb++ = (char) nPasswordLength; + strcpy(dpb, userPassword); + dpb+= nPasswordLength; + } - } - // External file AND/OR remote connection - else if (url.startsWith("sdbc:firebird:")) - { - m_sFirebirdURL = url.copy(OUString("sdbc:firebird:").getLength()); - if (m_sFirebirdURL.startsWith("file://")) - { - m_bIsFile = true; - uno::Reference< ucb::XSimpleFileAccess > xFileAccess( - ucb::SimpleFileAccess::create(comphelper::getProcessComponentContext()), - uno::UNO_QUERY); - if (!xFileAccess->exists(m_sFirebirdURL)) - bIsNewDatabase = true; - - m_sFirebirdURL = m_sFirebirdURL.copy(OUString("file://").getLength()); + dpbLength = dpb - dpbBuffer; } - } - char dpbBuffer[1 + 3 + 257 + 257 ]; // Expand as needed - int dpbLength = 0; - { - char* dpb; - char userName[256] = ""; - char userPassword[256] = ""; - - dpb = dpbBuffer; - *dpb++ = isc_dpb_version1; - - *dpb++ = isc_dpb_sql_dialect; - *dpb++ = 1; // 1 byte long - *dpb++ = FIREBIRD_SQL_DIALECT; - // Do any more dpbBuffer additions here - - if (m_bIsEmbedded || m_bIsFile) + ISC_STATUS_ARRAY status; /* status vector */ + ISC_STATUS aErr; + if (bIsNewDatabase) { - *dpb++ = isc_dpb_trusted_auth; - *dpb++ = 1; // Length of data - *dpb++ = 1; // TRUE + aErr = isc_create_database(status, + m_sFirebirdURL.getLength(), + OUStringToOString(m_sFirebirdURL,RTL_TEXTENCODING_UTF8).getStr(), + &m_aDBHandle, + dpbLength, + dpbBuffer, + 0); + if (aErr) + { + evaluateStatusVector(status, "isc_create_database", *this); + } } else { - // TODO: parse password from connection string as needed? - } - - if (strlen(userName)) - { - int nUsernameLength = strlen(userName); - *dpb++ = isc_dpb_user_name; - *dpb++ = (char) nUsernameLength; - strcpy(dpb, userName); - dpb+= nUsernameLength; + aErr = isc_attach_database(status, + m_sFirebirdURL.getLength(), + OUStringToOString(m_sFirebirdURL, RTL_TEXTENCODING_UTF8).getStr(), + &m_aDBHandle, + dpbLength, + dpbBuffer); + if (aErr) + { + evaluateStatusVector(status, "isc_attach_database", *this); + } } - if (strlen(userPassword)) + if (m_bIsEmbedded) // Add DocumentEventListener to save the .fdb as needed { - int nPasswordLength = strlen(userPassword); - *dpb++ = isc_dpb_password; - *dpb++ = (char) nPasswordLength; - strcpy(dpb, userPassword); - dpb+= nPasswordLength; + // TODO: this is only needed when we change icu versions, so ideally + // we somehow keep track of which icu version we have. There might + // be something db internal that we can check, or we might have to store + // it in the .odb. + rebuildIndexes(); + + // We need to attach as a document listener in order to be able to store + // the temporary db back into the .odb when saving + uno::Reference<XDocumentEventBroadcaster> xBroadcaster(m_xParentDocument, UNO_QUERY); + + if (xBroadcaster.is()) + xBroadcaster->addDocumentEventListener(this); + else + assert(false); } - - dpbLength = dpb - dpbBuffer; } - - ISC_STATUS_ARRAY status; /* status vector */ - ISC_STATUS aErr; - if (bIsNewDatabase) + catch (const Exception&) { - aErr = isc_create_database(status, - m_sFirebirdURL.getLength(), - OUStringToOString(m_sFirebirdURL,RTL_TEXTENCODING_UTF8).getStr(), - &m_aDBHandle, - dpbLength, - dpbBuffer, - 0); - if (aErr) - { - evaluateStatusVector(status, "isc_create_database", *this); - } + throw; } - else + catch (const std::exception&) { - aErr = isc_attach_database(status, - m_sFirebirdURL.getLength(), - OUStringToOString(m_sFirebirdURL, RTL_TEXTENCODING_UTF8).getStr(), - &m_aDBHandle, - dpbLength, - dpbBuffer); - if (aErr) - { - evaluateStatusVector(status, "isc_attach_database", *this); - } + throw; } + catch (...) // const Firebird::Exception& firebird throws this, but doesn't install the fb_exception.h that declares it - if (m_bIsEmbedded) // Add DocumentEventListener to save the .fdb as needed { - // TODO: this is only needed when we change icu versions, so ideally - // we somehow keep track of which icu version we have. There might - // be something db internal that we can check, or we might have to store - // it in the .odb. - rebuildIndexes(); - - // We need to attach as a document listener in order to be able to store - // the temporary db back into the .odb when saving - uno::Reference<XDocumentEventBroadcaster> xBroadcaster(m_xParentDocument, UNO_QUERY); - - if (xBroadcaster.is()) - xBroadcaster->addDocumentEventListener(this); - else - assert(false); + throw std::runtime_error("Generic Firebird::Exception"); } osl_atomic_decrement( &m_refCount ); @@ -788,65 +804,81 @@ uno::Reference< XTablesSupplier > Connection::createCatalog() } -void Connection::rebuildIndexes() throw (SQLException, RuntimeException) +void Connection::rebuildIndexes() throw (SQLException, RuntimeException, std::exception) { MutexGuard aGuard(m_aMutex); - // We only need to do this for character based columns on user-created tables. - - // Ideally we'd use a FOR SELECT ... INTO .... DO ..., but that seems to - // only be possible using PSQL, i.e. using a stored procedure. - OUString sSql( - // multiple columns possible per index, only select once - "SELECT DISTINCT indices.RDB$INDEX_NAME " - "FROM RDB$INDICES indices " - "JOIN RDB$INDEX_SEGMENTS index_segments " - "ON (indices.RDB$INDEX_NAME = index_segments.RDB$INDEX_NAME) " - "JOIN RDB$RELATION_FIELDS relation_fields " - "ON (index_segments.RDB$FIELD_NAME = relation_fields.RDB$FIELD_NAME) " - "JOIN RDB$FIELDS fields " - "ON (relation_fields.RDB$FIELD_SOURCE = fields.RDB$FIELD_NAME) " - - "WHERE (indices.RDB$SYSTEM_FLAG = 0) " - // TODO: what about blr_text2 etc. ? - "AND ((fields.RDB$FIELD_TYPE = " + OUString::number((int) blr_text) + ") " - " OR (fields.RDB$FIELD_TYPE = " + OUString::number((int) blr_varying) + ")) " - "AND (indices.RDB$INDEX_INACTIVE IS NULL OR indices.RDB$INDEX_INACTIVE = 0) " - ); - - uno::Reference< XStatement > xCharIndicesStatement = createStatement(); - uno::Reference< XResultSet > xCharIndices = - xCharIndicesStatement->executeQuery(sSql); - uno::Reference< XRow > xRow(xCharIndices, UNO_QUERY_THROW); - - uno::Reference< XStatement > xAlterIndexStatement = createStatement(); - - // ALTER is a DDL statement, hence using Statement will cause a commit - // after every alter -- in this case this is inappropriate (xCharIndicesStatement - // and its ResultSet become invalidated) hence we use the native api. - while (xCharIndices->next()) + try { - OUString sIndexName(sanitizeIdentifier(xRow->getString(1))); - SAL_INFO("connectivity.firebird", "rebuilding index " + sIndexName); - OString sAlterIndex = "ALTER INDEX \"" - + OUStringToOString(sIndexName, RTL_TEXTENCODING_UTF8) - + "\" ACTIVE"; - - ISC_STATUS_ARRAY aStatusVector; - ISC_STATUS aErr; - - aErr = isc_dsql_execute_immediate(aStatusVector, - &getDBHandle(), - &getTransaction(), - 0, // Length: 0 for null terminated - sAlterIndex.getStr(), - FIREBIRD_SQL_DIALECT, - NULL); - if (aErr) - evaluateStatusVector(aStatusVector, - "rebuildIndexes:isc_dsql_execute_immediate", - *this); + // We only need to do this for character based columns on user-created tables. + + // Ideally we'd use a FOR SELECT ... INTO .... DO ..., but that seems to + // only be possible using PSQL, i.e. using a stored procedure. + OUString sSql( + // multiple columns possible per index, only select once + "SELECT DISTINCT indices.RDB$INDEX_NAME " + "FROM RDB$INDICES indices " + "JOIN RDB$INDEX_SEGMENTS index_segments " + "ON (indices.RDB$INDEX_NAME = index_segments.RDB$INDEX_NAME) " + "JOIN RDB$RELATION_FIELDS relation_fields " + "ON (index_segments.RDB$FIELD_NAME = relation_fields.RDB$FIELD_NAME) " + "JOIN RDB$FIELDS fields " + "ON (relation_fields.RDB$FIELD_SOURCE = fields.RDB$FIELD_NAME) " + + "WHERE (indices.RDB$SYSTEM_FLAG = 0) " + // TODO: what about blr_text2 etc. ? + "AND ((fields.RDB$FIELD_TYPE = " + OUString::number((int) blr_text) + ") " + " OR (fields.RDB$FIELD_TYPE = " + OUString::number((int) blr_varying) + ")) " + "AND (indices.RDB$INDEX_INACTIVE IS NULL OR indices.RDB$INDEX_INACTIVE = 0) " + ); + + uno::Reference< XStatement > xCharIndicesStatement = createStatement(); + uno::Reference< XResultSet > xCharIndices = + xCharIndicesStatement->executeQuery(sSql); + uno::Reference< XRow > xRow(xCharIndices, UNO_QUERY_THROW); + + uno::Reference< XStatement > xAlterIndexStatement = createStatement(); + + // ALTER is a DDL statement, hence using Statement will cause a commit + // after every alter -- in this case this is inappropriate (xCharIndicesStatement + // and its ResultSet become invalidated) hence we use the native api. + while (xCharIndices->next()) + { + OUString sIndexName(sanitizeIdentifier(xRow->getString(1))); + SAL_INFO("connectivity.firebird", "rebuilding index " + sIndexName); + OString sAlterIndex = "ALTER INDEX \"" + + OUStringToOString(sIndexName, RTL_TEXTENCODING_UTF8) + + "\" ACTIVE"; + + ISC_STATUS_ARRAY aStatusVector; + ISC_STATUS aErr; + + aErr = isc_dsql_execute_immediate(aStatusVector, + &getDBHandle(), + &getTransaction(), + 0, // Length: 0 for null terminated + sAlterIndex.getStr(), + FIREBIRD_SQL_DIALECT, + NULL); + if (aErr) + evaluateStatusVector(aStatusVector, + "rebuildIndexes:isc_dsql_execute_immediate", + *this); + } + commit(); + } + catch (const Exception&) + { + throw; + } + catch (const std::exception&) + { + throw; + } + catch (...) // const Firebird::Exception& firebird throws this, but doesn't install the fb_exception.h that declares it + { + throw std::runtime_error("Generic Firebird::Exception"); } - commit(); + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/firebird/Connection.hxx b/connectivity/source/drivers/firebird/Connection.hxx index d613263048ad..e5467ebe3083 100644 --- a/connectivity/source/drivers/firebird/Connection.hxx +++ b/connectivity/source/drivers/firebird/Connection.hxx @@ -149,7 +149,7 @@ namespace connectivity * versions. */ void rebuildIndexes() - throw (css::sdbc::SQLException, css::uno::RuntimeException); + throw (css::sdbc::SQLException, css::uno::RuntimeException, std::exception); void buildTypeInfo() throw (css::sdbc::SQLException); @@ -176,8 +176,9 @@ namespace connectivity virtual void construct( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info) - throw(::com::sun::star::sdbc::SQLException, - ::com::sun::star::uno::RuntimeException); + throw(css::sdbc::SQLException, + css::uno::RuntimeException, + std::exception); ::rtl::OUString getConnectionURL() const {return m_sConnectionURL;} bool isEmbedded() const {return m_bIsEmbedded;} |