diff options
Diffstat (limited to 'connectivity/source/drivers/firebird')
45 files changed, 1020 insertions, 722 deletions
diff --git a/connectivity/source/drivers/firebird/Blob.cxx b/connectivity/source/drivers/firebird/Blob.cxx index 8ed9fc4a8ac7..26a5deaca0b4 100644 --- a/connectivity/source/drivers/firebird/Blob.cxx +++ b/connectivity/source/drivers/firebird/Blob.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -19,7 +19,7 @@ #include <connectivity/CommonTools.hxx> #include <connectivity/dbexception.hxx> #include <cppuhelper/exc_hlp.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> using namespace ::connectivity::firebird; @@ -67,7 +67,7 @@ void Blob::ensureBlobIsOpened() nullptr); if (aErr) - evaluateStatusVector(m_statusVector, "isc_open_blob2", *this); + evaluateStatusVector(m_statusVector, u"isc_open_blob2", *this); m_bBlobOpened = true; m_nBlobPosition = 0; @@ -90,7 +90,7 @@ void Blob::ensureBlobIsOpened() aResultBuffer); if (aErr) - evaluateStatusVector(m_statusVector, "isc_blob_info", *this); + evaluateStatusVector(m_statusVector, u"isc_blob_info", *this); char* pIt = aResultBuffer; while( *pIt != isc_info_end ) // info is in clusters @@ -122,28 +122,31 @@ sal_uInt16 Blob::getMaximumSegmentSize() return m_nMaxSegmentSize; } -bool Blob::readOneSegment(uno::Sequence< sal_Int8 >& rDataOut) +bool Blob::readOneSegment(std::vector<char>& rDataOut) { checkDisposed(Blob_BASE::rBHelper.bDisposed); ensureBlobIsOpened(); sal_uInt16 nMaxSize = getMaximumSegmentSize(); - if(rDataOut.getLength() < nMaxSize) - rDataOut.realloc(nMaxSize); + if(rDataOut.size() < nMaxSize) + rDataOut.resize(nMaxSize); sal_uInt16 nActualSize = 0; ISC_STATUS aRet = isc_get_segment(m_statusVector, &m_blobHandle, &nActualSize, nMaxSize, - reinterpret_cast<char*>(rDataOut.getArray()) ); + rDataOut.data() ); if (aRet && aRet != isc_segstr_eof && IndicatesError(m_statusVector)) { - OUString sError(StatusVectorToString(m_statusVector, "isc_get_segment")); + OUString sError(StatusVectorToString(m_statusVector, u"isc_get_segment")); throw IOException(sError, *this); } + + if (rDataOut.size() > nActualSize) + rDataOut.resize(nActualSize); m_nBlobPosition += nActualSize; return aRet == isc_segstr_eof; // last segment read } @@ -160,7 +163,7 @@ void Blob::closeBlob() aErr = isc_close_blob(m_statusVector, &m_blobHandle); if (aErr) - evaluateStatusVector(m_statusVector, "isc_close_blob", *this); + evaluateStatusVector(m_statusVector, u"isc_close_blob", *this); m_bBlobOpened = false; #if SAL_TYPES_SIZEOFPOINTER == 8 @@ -299,7 +302,7 @@ sal_Int32 SAL_CALL Blob::readBytes(uno::Sequence< sal_Int8 >& rDataOut, reinterpret_cast<char*>(rDataOut.getArray()) + nTotalBytesRead); if (aErr && IndicatesError(m_statusVector)) { - OUString sError(StatusVectorToString(m_statusVector, "isc_get_segment")); + OUString sError(StatusVectorToString(m_statusVector, u"isc_get_segment")); throw IOException(sError, *this); } nTotalBytesRead += nBytesRead; @@ -385,4 +388,4 @@ void SAL_CALL Blob::closeInput() } } -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Blob.hxx b/connectivity/source/drivers/firebird/Blob.hxx index 9cad65a3c05f..990108934bf2 100644 --- a/connectivity/source/drivers/firebird/Blob.hxx +++ b/connectivity/source/drivers/firebird/Blob.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -7,8 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_BLOB_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_BLOB_HXX +#pragma once #include <ibase.h> @@ -17,6 +16,8 @@ #include <com/sun/star/io/XInputStream.hpp> #include <com/sun/star/sdbc/XBlob.hpp> +#include <vector> + namespace connectivity::firebird { typedef ::cppu::WeakComponentImplHelper< css::sdbc::XBlob, @@ -60,7 +61,7 @@ namespace connectivity::firebird isc_tr_handle* pTransactionHandle, ISC_QUAD const & aBlobID); - bool readOneSegment(css::uno::Sequence< sal_Int8 >& rDataOut); + bool readOneSegment(std::vector<char>& rDataOut); // ---- XBlob ---------------------------------------------------- virtual sal_Int64 SAL_CALL @@ -96,5 +97,4 @@ namespace connectivity::firebird } -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_BLOB_HXX -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Catalog.cxx b/connectivity/source/drivers/firebird/Catalog.cxx index 47fedab60d59..2ef4f514b12a 100644 --- a/connectivity/source/drivers/firebird/Catalog.cxx +++ b/connectivity/source/drivers/firebird/Catalog.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -10,6 +10,7 @@ #include "Catalog.hxx" #include "Tables.hxx" #include "Users.hxx" +#include "Views.hxx" #include <com/sun/star/sdbc/XRow.hpp> @@ -27,9 +28,7 @@ Catalog::Catalog(const uno::Reference< XConnection >& rConnection): //----- OCatalog ------------------------------------------------------------- void Catalog::refreshTables() { - Sequence< OUString > aTypes(2); - aTypes[0] = "TABLE"; - aTypes[1] = "VIEW"; + Sequence< OUString > aTypes {"TABLE", "VIEW"}; uno::Reference< XResultSet > xTables = m_xMetaData->getTables(Any(), "%", @@ -55,8 +54,20 @@ void Catalog::refreshTables() void Catalog::refreshViews() { - // TODO: implement me. - // Sets m_pViews (OCatalog) + css::uno::Reference<css::sdbc::XResultSet> xViews + = m_xMetaData->getTables(css::uno::Any(), "%", "%", { "VIEW" }); + + if (!xViews.is()) + return; + + ::std::vector<OUString> aViewNames; + + fillNames(xViews, aViewNames); + + if (!m_pViews) + m_pViews.reset(new Views(m_xConnection, *this, m_aMutex, aViewNames)); + else + m_pViews->reFill(aViewNames); } //----- IRefreshableGroups --------------------------------------------------- @@ -90,4 +101,5 @@ void Catalog::refreshUsers() else m_pUsers->reFill(aUserNames); } -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Catalog.hxx b/connectivity/source/drivers/firebird/Catalog.hxx index 1ac364bc845c..3ffb9238eda7 100644 --- a/connectivity/source/drivers/firebird/Catalog.hxx +++ b/connectivity/source/drivers/firebird/Catalog.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -7,8 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_CATALOG_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_CATALOG_HXX +#pragma once #include <sdbcx/VCatalog.hxx> @@ -31,10 +30,11 @@ namespace connectivity::firebird // IRefreshableUsers virtual void refreshUsers() override; + + sdbcx::OCollection* getPrivateTables() const { return m_pTables.get(); } + sdbcx::OCollection* getPrivateViews() const { return m_pViews.get(); } }; } // namespace connectivity::firebird -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_CATALOG_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Clob.cxx b/connectivity/source/drivers/firebird/Clob.cxx index 2038dfc11350..dde050edee3a 100644 --- a/connectivity/source/drivers/firebird/Clob.cxx +++ b/connectivity/source/drivers/firebird/Clob.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -9,8 +9,6 @@ #include <sal/config.h> -#include <string_view> - #include "Clob.hxx" #include "Blob.hxx" @@ -54,13 +52,11 @@ sal_Int64 SAL_CALL Clob::length() // Read each segment, and calculate it's size by interpreting it as a // character stream. Assume that no characters are split by the segments. bool bLastSegmRead = false; + std::vector<char> aSegmentBytes; do { - uno::Sequence < sal_Int8 > aSegmentBytes; bLastSegmRead = m_aBlob->readOneSegment( aSegmentBytes ); - OUString sSegment ( reinterpret_cast< char *>( aSegmentBytes.getArray() ), - aSegmentBytes.getLength(), - RTL_TEXTENCODING_UTF8 ); + OUString sSegment(aSegmentBytes.data(), aSegmentBytes.size(), RTL_TEXTENCODING_UTF8); if( !bLastSegmRead) m_nCharCount += sSegment.getLength(); @@ -73,60 +69,51 @@ sal_Int64 SAL_CALL Clob::length() OUString SAL_CALL Clob::getSubString(sal_Int64 nPosition, sal_Int32 nLength) { + if (nPosition < 1) // XClob is indexed from 1 + throw lang::IllegalArgumentException("nPosition < 1", *this, 0); + --nPosition; // make 0-based + + if (nLength < 0) + throw lang::IllegalArgumentException("nLength < 0", *this, 0); + MutexGuard aGuard(m_aMutex); checkDisposed(Clob_BASE::rBHelper.bDisposed); // TODO do not reset position if it is not necessary m_aBlob->closeInput(); // reset position OUStringBuffer sSegmentBuffer; - sal_Int64 nActPos = 1; - sal_Int32 nActLen = 0; + std::vector<char> aSegmentBytes; - // skip irrelevant parts - while( nActPos < nPosition ) + for (;;) { - uno::Sequence < sal_Int8 > aSegmentBytes; bool bLastRead = m_aBlob->readOneSegment( aSegmentBytes ); - if( bLastRead ) - throw lang::IllegalArgumentException("nPosition out of range", *this, 0); - - OUString sSegment ( reinterpret_cast< char *>( aSegmentBytes.getArray() ), - aSegmentBytes.getLength(), - RTL_TEXTENCODING_UTF8 ); - sal_Int32 nStrLen = sSegment.getLength(); - nActPos += nStrLen; - if( nActPos > nPosition ) + // TODO: handle possible case of split UTF-8 character + OUString sSegment(aSegmentBytes.data(), aSegmentBytes.size(), RTL_TEXTENCODING_UTF8); + + // skip irrelevant parts + if (sSegment.getLength() < nPosition) { - sal_Int32 nCharsToCopy = static_cast<sal_Int32>(nActPos - nPosition); - if( nCharsToCopy > nLength ) - nCharsToCopy = nLength; - // append relevant part of first segment - sSegmentBuffer.append( std::u16string_view(sSegment).substr(0, nCharsToCopy) ); - nActLen += sSegmentBuffer.getLength(); + if (bLastRead) + throw lang::IllegalArgumentException("nPosition out of range", *this, 0); + nPosition -= sSegment.getLength(); + continue; } - } - // read nLength characters - while( nActLen < nLength ) - { - uno::Sequence < sal_Int8 > aSegmentBytes; - bool bLastRead = m_aBlob->readOneSegment( aSegmentBytes ); + // Getting here for the first time, nPosition may be > 0, meaning copy start offset. + // This also handles sSegment.getLength() == nPosition case, including nLength == 0. + const sal_Int32 nCharsToCopy = std::min<sal_Int32>(sSegment.getLength() - nPosition, + nLength - sSegmentBuffer.getLength()); + sSegmentBuffer.append(sSegment.subView(nPosition, nCharsToCopy)); + if (sSegmentBuffer.getLength() == nLength) + return sSegmentBuffer.makeStringAndClear(); + + assert(sSegmentBuffer.getLength() < nLength); - OUString sSegment ( reinterpret_cast< char *>( aSegmentBytes.getArray() ), - aSegmentBytes.getLength(), - RTL_TEXTENCODING_UTF8 ); - sal_Int32 nStrLen = sSegment.getLength(); - if( nActLen + nStrLen > nLength ) - sSegmentBuffer.append(std::u16string_view(sSegment).substr(0, nLength - nActLen)); - else - sSegmentBuffer.append(sSegment); - nActLen += nStrLen; - - if( bLastRead && nActLen < nLength ) + if (bLastRead) throw lang::IllegalArgumentException("out of range", *this, 0); - } - return sSegmentBuffer.makeStringAndClear(); + nPosition = 0; // No offset after first append + } } uno::Reference< XInputStream > SAL_CALL Clob::getCharacterStream() @@ -147,9 +134,8 @@ sal_Int64 SAL_CALL Clob::position(const OUString& /*rPattern*/, sal_Int64 SAL_CALL Clob::positionOfClob(const Reference <XClob >& /*rPattern*/, sal_Int64 /*aStart*/) { - ::dbtools::throwFeatureNotImplementedSQLException("Blob::positionOfBlob", *this); + ::dbtools::throwFeatureNotImplementedSQLException("Clob::positionOfClob", *this); return 0; } - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Clob.hxx b/connectivity/source/drivers/firebird/Clob.hxx index 8ebc639f0bbb..7fc5459d5d29 100644 --- a/connectivity/source/drivers/firebird/Clob.hxx +++ b/connectivity/source/drivers/firebird/Clob.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -7,8 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_CLOB_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_CLOB_HXX +#pragma once #include "Blob.hxx" @@ -62,5 +61,4 @@ namespace connectivity::firebird } -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_CLOB_HXX -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Column.cxx b/connectivity/source/drivers/firebird/Column.cxx index aa8abf9bb75c..0a18ebe5b441 100644 --- a/connectivity/source/drivers/firebird/Column.cxx +++ b/connectivity/source/drivers/firebird/Column.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -48,4 +48,4 @@ css::uno::Sequence< OUString > SAL_CALL Column::getSupportedServiceNames( ) return { "com.sun.star.sdbc.Firebird" }; } -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Column.hxx b/connectivity/source/drivers/firebird/Column.hxx index ce0bfa217051..c66287ce5668 100644 --- a/connectivity/source/drivers/firebird/Column.hxx +++ b/connectivity/source/drivers/firebird/Column.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -6,8 +6,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_HCOLUMN_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_HCOLUMN_HXX +#pragma once #include <connectivity/sdbcx/VColumn.hxx> @@ -29,6 +28,5 @@ namespace connectivity::firebird }; } -#endif // INCLUDED_CONNECTIVITY_SOURCE_INC_HSQLDB_HCOLUMNS_HXX -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Columns.cxx b/connectivity/source/drivers/firebird/Columns.cxx index 293dac97dc5b..d36e25f9195b 100644 --- a/connectivity/source/drivers/firebird/Columns.cxx +++ b/connectivity/source/drivers/firebird/Columns.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -12,13 +12,11 @@ using namespace ::connectivity; using namespace ::connectivity::firebird; -using namespace ::connectivity::sdbcx; using namespace ::cppu; using namespace ::osl; using namespace ::com::sun::star; -using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::uno; Columns::Columns(Table& rTable, @@ -38,4 +36,4 @@ Reference< css::beans::XPropertySet > Columns::createDescriptor() return new Column; } -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Columns.hxx b/connectivity/source/drivers/firebird/Columns.hxx index c7a22a2c245f..a211f70d1809 100644 --- a/connectivity/source/drivers/firebird/Columns.hxx +++ b/connectivity/source/drivers/firebird/Columns.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -7,8 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_COLUMNS_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_COLUMNS_HXX +#pragma once #include "Table.hxx" @@ -28,7 +27,4 @@ namespace connectivity::firebird } // namespace connectivity::firebird - -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_COLUMNS_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Connection.cxx b/connectivity/source/drivers/firebird/Connection.cxx index 05c24e9f73be..5a2be8872485 100644 --- a/connectivity/source/drivers/firebird/Connection.cxx +++ b/connectivity/source/drivers/firebird/Connection.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -22,7 +22,6 @@ #include "Clob.hxx" #include "Connection.hxx" #include "DatabaseMetaData.hxx" -#include "Driver.hxx" #include "PreparedStatement.hxx" #include "Statement.hxx" #include "Util.hxx" @@ -44,11 +43,12 @@ #include <resource/sharedresources.hxx> #include <comphelper/processfactory.hxx> +#include <comphelper/servicehelper.hxx> #include <comphelper/storagehelper.hxx> #include <cppuhelper/exc_hlp.hxx> #include <unotools/tempfile.hxx> -#include <unotools/localfilehelper.hxx> +#include <osl/file.hxx> #include <rtl/strbuf.hxx> #include <sal/log.hxx> @@ -72,16 +72,14 @@ using namespace ::com::sun::star::uno; * Location within the .odb that an embedded .fdb will be stored. * Only relevant for embedded dbs. */ -constexpr OUStringLiteral our_sFDBLocation( u"firebird.fdb" ); +constexpr OUString our_sFDBLocation( u"firebird.fdb"_ustr ); /** * Older version of LO may store the database in a .fdb file */ -constexpr OUStringLiteral our_sFBKLocation( u"firebird.fbk" ); +constexpr OUString our_sFBKLocation( u"firebird.fbk"_ustr ); Connection::Connection() : Connection_BASE(m_aMutex) - , m_sConnectionURL() - , m_sFirebirdURL() , m_bIsEmbedded(false) , m_bIsFile(false) , m_bIsAutoCommit(true) @@ -96,7 +94,6 @@ Connection::Connection() #endif , m_xCatalog(nullptr) , m_xMetaData(nullptr) - , m_aStatements() { } @@ -164,7 +161,7 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& bIsNewDatabase = !m_xEmbeddedStorage->hasElements(); - m_pDatabaseFileDir.reset(new ::utl::TempFile(nullptr, true)); + m_pDatabaseFileDir.reset(new ::utl::TempFileNamed(nullptr, true)); m_pDatabaseFileDir->EnableKillingFile(); m_sFirebirdURL = m_pDatabaseFileDir->GetFileName() + "/firebird.fdb"; m_sFBKPath = m_pDatabaseFileDir->GetFileName() + "/firebird.fbk"; @@ -199,7 +196,7 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& // External file AND/OR remote connection else if (url.startsWith("sdbc:firebird:")) { - m_sFirebirdURL = url.copy(OUString("sdbc:firebird:").getLength()); + m_sFirebirdURL = url.copy(strlen("sdbc:firebird:")); if (m_sFirebirdURL.startsWith("file://")) { m_bIsFile = true; @@ -208,19 +205,19 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& if (!xFileAccess->exists(m_sFirebirdURL)) bIsNewDatabase = true; - m_sFirebirdURL = m_sFirebirdURL.copy(OUString("file://").getLength()); + osl::FileBase::getSystemPathFromFileURL(m_sFirebirdURL, m_sFirebirdURL); } } std::string dpbBuffer; { - char userName[256] = ""; - char userPassword[256] = ""; + OString userName; + OString userPassword; dpbBuffer.push_back(isc_dpb_version1); dpbBuffer.push_back(isc_dpb_sql_dialect); dpbBuffer.push_back(1); // 1 byte long - dpbBuffer.push_back(FIREBIRD_SQL_DIALECT); + dpbBuffer.push_back(SQL_DIALECT_CURRENT); // set UTF8 as default character set of the database const char sCharset[] = "UTF8"; @@ -236,45 +233,64 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& if (m_bIsEmbedded || m_bIsFile) { - strcpy(userName,"sysdba"); - strcpy(userPassword,"masterkey"); + userName = "sysdba"_ostr; + userPassword = "masterkey"_ostr; } else { - // TODO: parse password from connection string as needed? + for (const auto& rIter : info) + { + if (rIter.Name == "user") + { + if (OUString value; rIter.Value >>= value) + userName = OUStringToOString(value, RTL_TEXTENCODING_UTF8); + } + else if (rIter.Name == "password") + { + if (OUString value; rIter.Value >>= value) + userPassword = OUStringToOString(value, RTL_TEXTENCODING_UTF8); + } + } } - if (strlen(userName)) + if (!userName.isEmpty()) { - int nUsernameLength = strlen(userName); + const sal_Int32 nMaxUsername = 255; //max size + int nUsernameLength = std::min(userName.getLength(), nMaxUsername); dpbBuffer.push_back(isc_dpb_user_name); dpbBuffer.push_back(nUsernameLength); - dpbBuffer.append(userName); + dpbBuffer.append(userName.getStr(), nUsernameLength); } - if (strlen(userPassword)) + if (!userPassword.isEmpty()) { - int nPasswordLength = strlen(userPassword); + const sal_Int32 nMaxPassword = 255; //max size + int nPasswordLength = std::min(userPassword.getLength(), nMaxPassword); dpbBuffer.push_back(isc_dpb_password); dpbBuffer.push_back(nPasswordLength); - dpbBuffer.append(userPassword); + dpbBuffer.append(userPassword.getStr(), nPasswordLength); } } + // use isc_dpb_utf8_filename to identify encoding of filenames + dpbBuffer.push_back(isc_dpb_utf8_filename); + dpbBuffer.push_back(0); // no filename here, it is passed to functions directly + ISC_STATUS_ARRAY status; /* status vector */ ISC_STATUS aErr; + const OString sFirebirdURL = OUStringToOString(m_sFirebirdURL, RTL_TEXTENCODING_UTF8); if (bIsNewDatabase) { aErr = isc_create_database(status, - m_sFirebirdURL.getLength(), - OUStringToOString(m_sFirebirdURL,RTL_TEXTENCODING_UTF8).getStr(), + sFirebirdURL.getLength(), + sFirebirdURL.getStr(), &m_aDBHandle, dpbBuffer.size(), dpbBuffer.c_str(), 0); if (aErr) { - evaluateStatusVector(status, "isc_create_database", *this); + evaluateStatusVector(status, u"isc_create_database", *this); } } else @@ -285,14 +301,14 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& } aErr = isc_attach_database(status, - m_sFirebirdURL.getLength(), - OUStringToOString(m_sFirebirdURL, RTL_TEXTENCODING_UTF8).getStr(), + sFirebirdURL.getLength(), + sFirebirdURL.getStr(), &m_aDBHandle, dpbBuffer.size(), dpbBuffer.c_str()); if (aErr) { - evaluateStatusVector(status, "isc_attach_database", *this); + evaluateStatusVector(status, u"isc_attach_database", *this); } } @@ -323,12 +339,6 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& } } -void Connection::notifyDatabaseModified() -{ - if (m_xParentDocument.is()) // Only true in embedded mode - m_xParentDocument->setModified(true); -} - //----- XServiceInfo --------------------------------------------------------- IMPLEMENT_SERVICE_INFO(Connection, "com.sun.star.sdbc.drivers.firebird.Connection", "com.sun.star.sdbc.Connection") @@ -342,7 +352,7 @@ Reference< XBlob> Connection::createBlob(ISC_QUAD const * pBlobId) &m_aTransactionHandle, *pBlobId); - m_aStatements.push_back(WeakReferenceHelper(xReturn)); + m_aStatements.emplace_back(xReturn); return xReturn; } @@ -355,10 +365,23 @@ Reference< XClob> Connection::createClob(ISC_QUAD const * pBlobId) &m_aTransactionHandle, *pBlobId); - m_aStatements.push_back(WeakReferenceHelper(xReturn)); + m_aStatements.emplace_back(xReturn); return xReturn; } +//----- XUnoTunnel ---------------------------------------------------------- +// virtual +sal_Int64 SAL_CALL Connection::getSomething(const css::uno::Sequence<sal_Int8>& rId) +{ + return comphelper::getSomethingImpl(rId, this); +} + +// static +const css::uno::Sequence<sal_Int8> & Connection::getUnoTunnelId() +{ + static const comphelper::UnoIdInit implId; + return implId.getSeq(); +} //----- XConnection ---------------------------------------------------------- Reference< XStatement > SAL_CALL Connection::createStatement( ) @@ -373,7 +396,7 @@ Reference< XStatement > SAL_CALL Connection::createStatement( ) // create a statement // the statement can only be executed once Reference< XStatement > xReturn = new OStatement(this); - m_aStatements.push_back(WeakReferenceHelper(xReturn)); + m_aStatements.emplace_back(xReturn); return xReturn; } @@ -389,7 +412,7 @@ Reference< XPreparedStatement > SAL_CALL Connection::prepareStatement( buildTypeInfo(); Reference< XPreparedStatement > xReturn = new OPreparedStatement(this, _sSql); - m_aStatements.push_back(WeakReferenceHelper(xReturn)); + m_aStatements.emplace_back(xReturn); return xReturn; } @@ -411,7 +434,6 @@ Reference< XPreparedStatement > SAL_CALL Connection::prepareCall( OUString SAL_CALL Connection::nativeSQL( const OUString& _sSql ) { - MutexGuard aGuard( m_aMutex ); // We do not need to adapt the SQL for Firebird atm. return _sSql; } @@ -490,7 +512,7 @@ void Connection::setupTransaction() aTPB); evaluateStatusVector(status_vector, - "isc_start_transaction", + u"isc_start_transaction", *this); } @@ -516,7 +538,7 @@ void SAL_CALL Connection::commit() disposeStatements(); isc_commit_transaction(status_vector, &m_aTransactionHandle); evaluateStatusVector(status_vector, - "isc_commit_transaction", + u"isc_commit_transaction", *this); } } @@ -569,7 +591,7 @@ isc_svc_handle Connection::attachServiceManager() aSPBBuffer)) { evaluateStatusVector(aStatusVector, - "isc_service_attach", + u"isc_service_attach", *this); } @@ -583,7 +605,7 @@ void Connection::detachServiceManager(isc_svc_handle aServiceHandle) &aServiceHandle)) { evaluateStatusVector(aStatusVector, - "isc_service_detach", + u"isc_service_detach", *this); } } @@ -600,22 +622,18 @@ void Connection::runBackupService(const short nAction) OString sFBKPath = OUStringToOString(m_sFBKPath, RTL_TEXTENCODING_UTF8); - OStringBuffer aRequest; // byte array - - - aRequest.append(static_cast<char>(nAction)); - - aRequest.append(char(isc_spb_dbname)); // .fdb sal_uInt16 nFDBLength = sFDBPath.getLength(); - aRequest.append(static_cast<char>(nFDBLength & 0xFF)); // least significant byte first - aRequest.append(static_cast<char>((nFDBLength >> 8) & 0xFF)); - aRequest.append(sFDBPath); - - aRequest.append(char(isc_spb_bkp_file)); // .fbk sal_uInt16 nFBKLength = sFBKPath.getLength(); - aRequest.append(static_cast<char>(nFBKLength & 0xFF)); - aRequest.append(static_cast<char>((nFBKLength >> 8) & 0xFF)); - aRequest.append(sFBKPath); + OStringBuffer aRequest( // byte array + OStringChar(static_cast<char>(nAction)) + + OStringChar(char(isc_spb_dbname)) // .fdb + + OStringChar(static_cast<char>(nFDBLength & 0xFF)) // least significant byte first + + OStringChar(static_cast<char>((nFDBLength >> 8) & 0xFF)) + + sFDBPath + + OStringChar(char(isc_spb_bkp_file)) // .fbk + + OStringChar(static_cast<char>(nFBKLength & 0xFF)) + + OStringChar(static_cast<char>((nFBKLength >> 8) & 0xFF)) + + sFBKPath); if (nAction == isc_action_svc_restore) { @@ -642,7 +660,7 @@ void Connection::runBackupService(const short nAction) aRequest.getLength(), aRequest.getStr())) { - evaluateStatusVector(aStatusVector, "isc_service_start", *this); + evaluateStatusVector(aStatusVector, u"isc_service_start", *this); } char aInfoSPB = isc_info_svc_line; @@ -658,7 +676,7 @@ void Connection::runBackupService(const short nAction) sizeof(aResults), aResults)) { - evaluateStatusVector(aStatusVector, "isc_service_query", *this); + evaluateStatusVector(aStatusVector, u"isc_service_query", *this); } detachServiceManager(aServiceHandle); @@ -798,42 +816,9 @@ void SAL_CALL Connection::documentEventOccured( const DocumentEvent& Event ) if ( !(m_bIsEmbedded && m_xEmbeddedStorage.is()) ) return; - SAL_INFO("connectivity.firebird", "Writing .fbk from running db"); - try - { - runBackupService(isc_action_svc_backup); - } - catch (const SQLException& e) - { - auto a = cppu::getCaughtException(); - throw WrappedTargetRuntimeException(e.Message, e.Context, a); - } - - - Reference< XStream > xDBStream(m_xEmbeddedStorage->openStreamElement(our_sFBKLocation, - ElementModes::WRITE)); - - // TODO: verify the backup actually exists -- the backup service - // can fail without giving any sane error messages / telling us - // that it failed. - using namespace ::comphelper; - Reference< XComponentContext > xContext = comphelper::getProcessComponentContext(); - Reference< XInputStream > xInputStream; - if (!xContext.is()) - return; - - xInputStream = - OStorageHelper::GetInputStreamFromURL(m_sFBKPath, xContext); - if (xInputStream.is()) - OStorageHelper::CopyInputToOutput( xInputStream, - xDBStream->getOutputStream()); - - // remove old fdb file if exists - uno::Reference< ucb::XSimpleFileAccess > xFileAccess = - ucb::SimpleFileAccess::create(xContext); - if (xFileAccess->exists(m_sFirebirdURL)) - xFileAccess->kill(m_sFirebirdURL); + storeDatabase(); } + // XEventListener void SAL_CALL Connection::disposing(const EventObject& /*rSource*/) { @@ -911,20 +896,46 @@ void Connection::disposing() { if (isc_detach_database(status, &m_aDBHandle)) { - evaluateStatusVector(status, "isc_detach_database", *this); + evaluateStatusVector(status, u"isc_detach_database", *this); } } - // TODO: write to storage again? + + storeDatabase(); cppu::WeakComponentImplHelperBase::disposing(); - if (m_pDatabaseFileDir) + m_pDatabaseFileDir.reset(); +} + +void Connection::storeDatabase() +{ + MutexGuard aGuard(m_aMutex); + if (m_bIsEmbedded && m_xEmbeddedStorage.is()) { - ::utl::removeTree(m_pDatabaseFileDir->GetURL()); - m_pDatabaseFileDir.reset(); + SAL_INFO("connectivity.firebird", "Writing .fbk from running db"); + try + { + runBackupService(isc_action_svc_backup); + } + catch (const SQLException& e) + { + auto a = cppu::getCaughtException(); + throw WrappedTargetRuntimeException(e.Message, e.Context, a); + } + Reference<XStream> xDBStream( + m_xEmbeddedStorage->openStreamElement(our_sFBKLocation, ElementModes::WRITE)); + using namespace ::comphelper; + Reference<XComponentContext> xContext = comphelper::getProcessComponentContext(); + Reference<XInputStream> xInputStream; + if (!xContext.is()) + return; + xInputStream = OStorageHelper::GetInputStreamFromURL(m_sFBKPath, xContext); + if (xInputStream.is()) + OStorageHelper::CopyInputToOutput(xInputStream, xDBStream->getOutputStream()); } } + void Connection::disposeStatements() { MutexGuard aGuard(m_aMutex); @@ -956,4 +967,4 @@ uno::Reference< XTablesSupplier > Connection::createCatalog() } - +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Connection.hxx b/connectivity/source/drivers/firebird/Connection.hxx index 9e2c9c24865d..16ac0ffa278d 100644 --- a/connectivity/source/drivers/firebird/Connection.hxx +++ b/connectivity/source/drivers/firebird/Connection.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -17,8 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_CONNECTION_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_CONNECTION_HXX +#pragma once #include <ibase.h> @@ -34,6 +33,7 @@ #include <com/sun/star/document/XDocumentEventListener.hpp> #include <com/sun/star/embed/XStorage.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> #include <com/sun/star/sdbc/XBlob.hpp> #include <com/sun/star/sdbc/XClob.hpp> #include <com/sun/star/sdbc/XConnection.hpp> @@ -46,6 +46,7 @@ namespace connectivity::firebird typedef ::cppu::WeakComponentImplHelper< css::document::XDocumentEventListener, css::lang::XServiceInfo, + css::lang::XUnoTunnel, css::sdbc::XConnection, css::sdbc::XWarningsSupplier > Connection_BASE; @@ -103,7 +104,7 @@ namespace connectivity::firebird * The extracted .fbk is written in firebird.fbk, the temporary * .fdb is stored as firebird.fdb. */ - std::unique_ptr< ::utl::TempFile > m_pDatabaseFileDir; + std::unique_ptr< ::utl::TempFileNamed > m_pDatabaseFileDir; /** * Path for our extracted .fbk file. * @@ -171,16 +172,6 @@ namespace connectivity::firebird isc_tr_handle& getTransaction(); /** - * Must be called anytime the underlying database is likely to have - * changed. - * - * This is used to notify the database document of any changes, so - * that the user is informed of any pending changes needing to be - * saved. - */ - void notifyDatabaseModified(); - - /** * Create a new Blob tied to this connection. Blobs are tied to a * transaction and not to a statement, hence the connection should * deal with their management. @@ -202,11 +193,19 @@ namespace connectivity::firebird css::uno::Reference< css::sdbcx::XTablesSupplier > createCatalog(); + /** + * Backup and store embedded extracted database to the .odb file + */ + void storeDatabase(); + // OComponentHelper virtual void SAL_CALL disposing() override; // XServiceInfo DECLARE_SERVICE_INFO(); + // XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething(const css::uno::Sequence<sal_Int8>& rId) override; + static const css::uno::Sequence<sal_Int8> & getUnoTunnelId(); // XConnection virtual css::uno::Reference< css::sdbc::XStatement > SAL_CALL createStatement( ) override; virtual css::uno::Reference< css::sdbc::XPreparedStatement > SAL_CALL prepareStatement( const OUString& sql ) override; @@ -239,6 +238,5 @@ namespace connectivity::firebird }; } -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_CONNECTION_HXX -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx index fdea4e4026eb..37c2ffe72c3d 100644 --- a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx +++ b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -771,7 +771,7 @@ sal_Bool SAL_CALL ODatabaseMetaData::supportsBatchUpdates() uno::Reference< XConnection > SAL_CALL ODatabaseMetaData::getConnection() { - return uno::Reference<XConnection>(m_pConnection.get()); + return m_pConnection; } // here follow all methods which return a resultset @@ -781,9 +781,8 @@ uno::Reference< XConnection > SAL_CALL ODatabaseMetaData::getConnection() uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTableTypes( ) { - ODatabaseMetaDataResultSet* pResultSet = new + rtl::Reference<ODatabaseMetaDataResultSet> pResultSet = new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTableTypes); - uno::Reference< XResultSet > xResultSet = pResultSet; ODatabaseMetaDataResultSet::ORows aResults; ODatabaseMetaDataResultSet::ORow aRow(2); @@ -802,8 +801,8 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTableTypes( ) aRow[1] = new ORowSetValueDecorator(OUString("SYSTEM TABLE")); aResults.push_back(aRow); - pResultSet->setRows(aResults); - return xResultSet; + pResultSet->setRows(std::move(aResults)); + return pResultSet; } uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo() @@ -812,9 +811,8 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo() // this returns an empty resultset where the column-names are already set // in special the metadata of the resultset already returns the right columns - ODatabaseMetaDataResultSet* pResultSet = + rtl::Reference<ODatabaseMetaDataResultSet> pResultSet = new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTypeInfo); - uno::Reference< XResultSet > xResultSet = pResultSet; static ODatabaseMetaDataResultSet::ORows aResults = []() { ODatabaseMetaDataResultSet::ORows tmp; @@ -823,14 +821,14 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo() // Common data aRow[4] = ODatabaseMetaDataResultSet::getQuoteValue(); // Literal quote marks aRow[5] = ODatabaseMetaDataResultSet::getQuoteValue(); // Literal quote marks - aRow[7] = new ORowSetValueDecorator(true); // Nullable - aRow[8] = new ORowSetValueDecorator(true); // Case sensitive - aRow[10] = new ORowSetValueDecorator(false); // Is unsigned + aRow[7] = new ORowSetValueDecorator(ORowSetValue(true)); // Nullable + aRow[8] = new ORowSetValueDecorator(ORowSetValue(true)); // Case sensitive + aRow[10] = new ORowSetValueDecorator(ORowSetValue(false)); // Is unsigned // FIXED_PREC_SCALE: docs state "can it be a money value? " however // in reality this causes Base to treat all numbers as money formatted // by default which is wrong (and formatting as money value is still // possible for all values). - aRow[11] = new ORowSetValueDecorator(false); + aRow[11] = new ORowSetValueDecorator(ORowSetValue(false)); // Localised Type Name -- TODO: implement (but can be null): aRow[13] = new ORowSetValueDecorator(); aRow[16] = new ORowSetValueDecorator(); // Unused @@ -844,7 +842,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo() aRow[6] = new ORowSetValueDecorator(OUString("length")); // Create Params aRow[9] = new ORowSetValueDecorator( sal_Int16(ColumnSearch::FULL)); // Searchable - aRow[12] = new ORowSetValueDecorator(false); // Autoincrement + aRow[12] = new ORowSetValueDecorator(ORowSetValue(false)); // Autoincrement aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale tmp.push_back(aRow); @@ -856,7 +854,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo() aRow[6] = new ORowSetValueDecorator(OUString("length")); // Create Params aRow[9] = new ORowSetValueDecorator( sal_Int16(ColumnSearch::FULL)); // Searchable - aRow[12] = new ORowSetValueDecorator(false); // Autoincrement + aRow[12] = new ORowSetValueDecorator(ORowSetValue(false)); // Autoincrement aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale tmp.push_back(aRow); @@ -890,7 +888,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo() aRow[6] = new ORowSetValueDecorator(); // Create Params aRow[9] = new ORowSetValueDecorator( sal_Int16(ColumnSearch::FULL)); // Searchable - aRow[12] = new ORowSetValueDecorator(false); // Autoincrement + aRow[12] = new ORowSetValueDecorator(ORowSetValue(false)); // Autoincrement aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale tmp.push_back(aRow); @@ -906,7 +904,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo() aRow[6] = new ORowSetValueDecorator(); // Create Params aRow[9] = new ORowSetValueDecorator( sal_Int16(ColumnSearch::FULL)); // Searchable - aRow[12] = new ORowSetValueDecorator(true); // Autoincrement + aRow[12] = new ORowSetValueDecorator(ORowSetValue(true)); // Autoincrement aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale } @@ -930,7 +928,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo() { aRow[9] = new ORowSetValueDecorator( sal_Int16(ColumnSearch::FULL)); // Searchable - aRow[12] = new ORowSetValueDecorator(true); // Autoincrement + aRow[12] = new ORowSetValueDecorator(ORowSetValue(true)); // Autoincrement } aRow[6] = new ORowSetValueDecorator(OUString("PRECISION,SCALE")); // Create params @@ -974,7 +972,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo() aRow[6] = new ORowSetValueDecorator(); // Create Params aRow[9] = new ORowSetValueDecorator( sal_Int16(ColumnSearch::FULL)); // Searchable - aRow[12] = new ORowSetValueDecorator(false); // Autoincrement + aRow[12] = new ORowSetValueDecorator(ORowSetValue(false)); // Autoincrement aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale tmp.push_back(aRow); @@ -986,7 +984,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo() aRow[6] = new ORowSetValueDecorator(); // Create Params aRow[9] = new ORowSetValueDecorator( sal_Int16(ColumnSearch::FULL)); // Searchable - aRow[12] = new ORowSetValueDecorator(false); // Autoincrement + aRow[12] = new ORowSetValueDecorator(ORowSetValue(false)); // Autoincrement aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale tmp.push_back(aRow); @@ -998,7 +996,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo() aRow[6] = new ORowSetValueDecorator(); // Create Params aRow[9] = new ORowSetValueDecorator( sal_Int16(ColumnSearch::FULL)); // Searchable - aRow[12] = new ORowSetValueDecorator(false); // Autoincrement + aRow[12] = new ORowSetValueDecorator(ORowSetValue(false)); // Autoincrement aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale tmp.push_back(aRow); @@ -1010,7 +1008,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo() aRow[6] = new ORowSetValueDecorator(); // Create Params aRow[9] = new ORowSetValueDecorator( sal_Int16(ColumnSearch::NONE)); // Searchable - aRow[12] = new ORowSetValueDecorator(false); // Autoincrement + aRow[12] = new ORowSetValueDecorator(ORowSetValue(false)); // Autoincrement aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale tmp.push_back(aRow); @@ -1022,14 +1020,15 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo() aRow[6] = new ORowSetValueDecorator(); // Create Params aRow[9] = new ORowSetValueDecorator( sal_Int16(ColumnSearch::BASIC)); // Searchable - aRow[12] = new ORowSetValueDecorator(false); // Autoincrement + aRow[12] = new ORowSetValueDecorator(ORowSetValue(false)); // Autoincrement aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale tmp.push_back(aRow); return tmp; }(); - pResultSet->setRows(aResults); - return xResultSet; + // [-loplugin:redundantfcast] false positive: + pResultSet->setRows(ODatabaseMetaDataResultSet::ORows(aResults)); + return pResultSet; } uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumnPrivileges( @@ -1042,9 +1041,8 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumnPrivileges( "Table: " << sTable << " & ColumnNamePattern: " << sColumnNamePattern); - ODatabaseMetaDataResultSet* pResultSet = new + rtl::Reference<ODatabaseMetaDataResultSet> pResultSet = new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eColumnPrivileges); - uno::Reference< XResultSet > xResultSet = pResultSet; uno::Reference< XStatement > statement = m_pConnection->createStatement(); static const char wld[] = "%"; @@ -1102,9 +1100,9 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumnPrivileges( aResults.push_back(aCurrentRow); } - pResultSet->setRows( aResults ); + pResultSet->setRows( std::move(aResults) ); - return xResultSet; + return pResultSet; } uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumns( @@ -1308,12 +1306,11 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumns( aResults.push_back(aCurrentRow); } - ODatabaseMetaDataResultSet* pResultSet = new + rtl::Reference<ODatabaseMetaDataResultSet> pResultSet = new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eColumns); - uno::Reference< XResultSet > xResultSet = pResultSet; - pResultSet->setRows( aResults ); + pResultSet->setRows( std::move(aResults) ); - return xResultSet; + return pResultSet; } uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTables( @@ -1325,9 +1322,8 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTables( SAL_INFO("connectivity.firebird", "getTables() with " "TableNamePattern: " << tableNamePattern); - ODatabaseMetaDataResultSet* pResultSet = new + rtl::Reference<ODatabaseMetaDataResultSet> pResultSet = new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTables); - uno::Reference< XResultSet > xResultSet = pResultSet; uno::Reference< XStatement > statement = m_pConnection->createStatement(); static const char wld[] = "%"; @@ -1344,8 +1340,10 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTables( // TODO: GLOBAL TEMPORARY, LOCAL TEMPORARY, ALIAS, SYNONYM if (!types.hasElements() || (types.getLength() == 1 && types[0].match(wld))) { + // from Firebird: src/jrd/constants.h + // rel_persistent = 0, rel_view = 1, rel_external = 2 // All table types? I.e. includes system tables. - queryBuf.append("(RDB$RELATION_TYPE = 0 OR RDB$RELATION_TYPE = 1) "); + queryBuf.append("(RDB$RELATION_TYPE = 0 OR RDB$RELATION_TYPE = 1 OR RDB$RELATION_TYPE = 2) "); } else { @@ -1411,7 +1409,8 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTables( } else { - if (nTableType == 0) + // see above about src/jrd/constants.h + if (nTableType == 0 || nTableType == 2) sTableType = "TABLE"; } @@ -1422,16 +1421,16 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTables( uno::Reference< XClob > xClob = xRow->getClob(4); if (xClob.is()) { - aCurrentRow[5] = new ORowSetValueDecorator(xClob->getSubString(0, xClob->length())); + aCurrentRow[5] = new ORowSetValueDecorator(xClob->getSubString(1, xClob->length())); } } aResults.push_back(aCurrentRow); } - pResultSet->setRows( aResults ); + pResultSet->setRows( std::move(aResults) ); - return xResultSet; + return pResultSet; } uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getProcedureColumns( @@ -1475,11 +1474,10 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getImportedKeys( return ODatabaseMetaData::lcl_getKeys(true, table); } -uno::Reference< XResultSet > ODatabaseMetaData::lcl_getKeys(const bool& bIsImport, std::u16string_view table ) +uno::Reference< XResultSet > ODatabaseMetaData::lcl_getKeys(const bool bIsImport, std::u16string_view table ) { - ODatabaseMetaDataResultSet* pResultSet = new - ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eImportedKeys); - uno::Reference< XResultSet > xResultSet = pResultSet; + rtl::Reference<ODatabaseMetaDataResultSet> pResultSet = new + ODatabaseMetaDataResultSet(bIsImport?ODatabaseMetaDataResultSet::eImportedKeys:ODatabaseMetaDataResultSet::eExportedKeys); uno::Reference< XStatement > statement = m_pConnection->createStatement(); @@ -1558,8 +1556,8 @@ uno::Reference< XResultSet > ODatabaseMetaData::lcl_getKeys(const bool& bIsImpor aResults.push_back(aCurrentRow); } - pResultSet->setRows( aResults ); - return xResultSet; + pResultSet->setRows( std::move(aResults) ); + return pResultSet; } uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getPrimaryKeys( @@ -1610,12 +1608,11 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getPrimaryKeys( aResults.push_back(aCurrentRow); } - ODatabaseMetaDataResultSet* pResultSet = new + rtl::Reference<ODatabaseMetaDataResultSet> pResultSet = new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::ePrimaryKeys); - uno::Reference< XResultSet > xResultSet = pResultSet; - pResultSet->setRows( aResults ); + pResultSet->setRows( std::move(aResults) ); - return xResultSet; + return pResultSet; } uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getIndexInfo( @@ -1683,7 +1680,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getIndexInfo( } // 4. NON_UNIQUE -- i.e. specifically negate here. - aCurrentRow[4] = new ORowSetValueDecorator(xRow->getShort(5) == 0); + aCurrentRow[4] = new ORowSetValueDecorator(ORowSetValue(xRow->getShort(5) == 0)); // 6. INDEX NAME aCurrentRow[6] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(4))); @@ -1704,12 +1701,11 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getIndexInfo( aResults.push_back(aCurrentRow); } - ODatabaseMetaDataResultSet* pResultSet = new - ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::ePrimaryKeys); - uno::Reference< XResultSet > xResultSet = pResultSet; - pResultSet->setRows( aResults ); + rtl::Reference<ODatabaseMetaDataResultSet> pResultSet = new + ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eIndexInfo); + pResultSet->setRows( std::move(aResults) ); - return xResultSet; + return pResultSet; } uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getBestRowIdentifier( @@ -1729,9 +1725,8 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTablePrivileges( SAL_INFO("connectivity.firebird", "getTablePrivileges() with " "TableNamePattern: " << sTableNamePattern); - ODatabaseMetaDataResultSet* pResultSet = new + rtl::Reference<ODatabaseMetaDataResultSet> pResultSet = new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTablePrivileges); - uno::Reference< XResultSet > xResultSet = pResultSet; uno::Reference< XStatement > statement = m_pConnection->createStatement(); // TODO: column specific privileges are included, we may need @@ -1778,14 +1773,14 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTablePrivileges( aRow[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(2))); // 4. GRANTOR aRow[5] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(3))); // 5. GRANTEE aRow[6] = new ORowSetValueDecorator(xRow->getString(4)); // 6. Privilege - aRow[7] = new ORowSetValueDecorator(bool(xRow->getBoolean(5))); // 7. Is Grantable + aRow[7] = new ORowSetValueDecorator(ORowSetValue(bool(xRow->getBoolean(5)))); // 7. Is Grantable aResults.push_back(aRow); } - pResultSet->setRows( aResults ); + pResultSet->setRows( std::move(aResults) ); - return xResultSet; + return pResultSet; } uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getCrossReference( @@ -1805,5 +1800,4 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getUDTs( const Any&, co return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eUDTs); } - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/DatabaseMetaData.hxx b/connectivity/source/drivers/firebird/DatabaseMetaData.hxx index fda5bb31bc88..c577f594d245 100644 --- a/connectivity/source/drivers/firebird/DatabaseMetaData.hxx +++ b/connectivity/source/drivers/firebird/DatabaseMetaData.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -17,8 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_DATABASEMETADATA_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_DATABASEMETADATA_HXX +#pragma once #include <sal/config.h> @@ -42,7 +41,7 @@ namespace connectivity::firebird { ::rtl::Reference<Connection> m_pConnection; private: - css::uno::Reference< css::sdbc::XResultSet > lcl_getKeys( const bool& bIsImport, std::u16string_view table ); + css::uno::Reference< css::sdbc::XResultSet > lcl_getKeys( bool bIsImport, std::u16string_view table ); public: explicit ODatabaseMetaData(Connection* _pCon); @@ -203,6 +202,4 @@ namespace connectivity::firebird } -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_DATABASEMETADATA_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Driver.cxx b/connectivity/source/drivers/firebird/Driver.cxx index 55e149e9de5c..3aa903d48abf 100644 --- a/connectivity/source/drivers/firebird/Driver.cxx +++ b/connectivity/source/drivers/firebird/Driver.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -25,12 +25,12 @@ #include <strings.hrc> #include <resource/sharedresources.hxx> +#include <comphelper/servicehelper.hxx> #include <cppuhelper/supportsservice.hxx> #include <osl/file.hxx> #include <osl/process.h> #include <rtl/bootstrap.hxx> #include <sal/log.hxx> -#include <unotools/localfilehelper.hxx> using namespace com::sun::star; using namespace com::sun::star::uno; @@ -45,11 +45,11 @@ using namespace connectivity::firebird; // Static const variables namespace { -constexpr OUStringLiteral our_sFirebirdTmpVar = u"FIREBIRD_TMP"; -constexpr OUStringLiteral our_sFirebirdLockVar = u"FIREBIRD_LOCK"; -constexpr OUStringLiteral our_sFirebirdMsgVar = u"FIREBIRD_MSG"; +constexpr OUString our_sFirebirdTmpVar = u"FIREBIRD_TMP"_ustr; +constexpr OUString our_sFirebirdLockVar = u"FIREBIRD_LOCK"_ustr; +constexpr OUString our_sFirebirdMsgVar = u"FIREBIRD_MSG"_ustr; #ifdef MACOSX -constexpr OUStringLiteral our_sFirebirdLibVar = u"LIBREOFFICE_FIREBIRD_LIB"; +constexpr OUString our_sFirebirdLibVar = u"LIBREOFFICE_FIREBIRD_LIB"_ustr; #endif }; @@ -62,12 +62,14 @@ FirebirdDriver::FirebirdDriver(const css::uno::Reference< css::uno::XComponentCo // ::utl::TempFile uses a unique temporary directory (subdirectory of // /tmp or other user specific tmp directory) per instance in which // we can create directories for firebird at will. + m_firebirdTMPDirectory.EnableKillingFile(true); + m_firebirdLockDirectory.EnableKillingFile(true); // Overrides firebird's default of /tmp or c:\temp - osl_setEnvironment(OUString(our_sFirebirdTmpVar).pData, m_firebirdTMPDirectory.GetFileName().pData); + osl_setEnvironment(our_sFirebirdTmpVar.pData, m_firebirdTMPDirectory.GetFileName().pData); // Overrides firebird's default of /tmp/firebird or c:\temp\firebird - osl_setEnvironment(OUString(our_sFirebirdLockVar).pData, m_firebirdLockDirectory.GetFileName().pData); + osl_setEnvironment(our_sFirebirdLockVar.pData, m_firebirdLockDirectory.GetFileName().pData); #ifndef SYSTEM_FIREBIRD // Overrides firebird's hardcoded default of /usr/local/firebird on *nix, @@ -76,7 +78,7 @@ FirebirdDriver::FirebirdDriver(const css::uno::Reference< css::uno::XComponentCo ::rtl::Bootstrap::expandMacros(sMsgURL); OUString sMsgPath; ::osl::FileBase::getSystemPathFromFileURL(sMsgURL, sMsgPath); - osl_setEnvironment(OUString(our_sFirebirdMsgVar).pData, sMsgPath.pData); + osl_setEnvironment(our_sFirebirdMsgVar.pData, sMsgPath.pData); #ifdef MACOSX // Set an env. variable to specify library location // for dlopen used in fbclient. @@ -84,16 +86,12 @@ FirebirdDriver::FirebirdDriver(const css::uno::Reference< css::uno::XComponentCo ::rtl::Bootstrap::expandMacros(sLibURL); OUString sLibPath; ::osl::FileBase::getSystemPathFromFileURL(sLibURL, sLibPath); - osl_setEnvironment(OUString(our_sFirebirdLibVar).pData, sLibPath.pData); + osl_setEnvironment(our_sFirebirdLibVar.pData, sLibPath.pData); #endif /*MACOSX*/ #endif /*!SYSTEM_FIREBIRD*/ } -FirebirdDriver::~FirebirdDriver() -{ - utl::removeTree(m_firebirdTMPDirectory.GetURL()); - utl::removeTree(m_firebirdLockDirectory.GetURL()); -} +FirebirdDriver::~FirebirdDriver() = default; void FirebirdDriver::disposing() { @@ -107,13 +105,13 @@ void FirebirdDriver::disposing() } m_xConnections.clear(); - osl_clearEnvironment(OUString(our_sFirebirdTmpVar).pData); - osl_clearEnvironment(OUString(our_sFirebirdLockVar).pData); + osl_clearEnvironment(our_sFirebirdTmpVar.pData); + osl_clearEnvironment(our_sFirebirdLockVar.pData); #ifndef SYSTEM_FIREBIRD - osl_clearEnvironment(OUString(our_sFirebirdMsgVar).pData); + osl_clearEnvironment(our_sFirebirdMsgVar.pData); #ifdef MACOSX - osl_clearEnvironment(OUString(our_sFirebirdLibVar).pData); + osl_clearEnvironment(our_sFirebirdLibVar.pData); #endif /*MACOSX*/ #endif /*!SYSTEM_FIREBIRD*/ @@ -150,13 +148,12 @@ Reference< XConnection > SAL_CALL FirebirdDriver::connect( if ( ! acceptsURL(url) ) return nullptr; - Connection* pCon = new Connection(); - Reference< XConnection > xCon = pCon; + rtl::Reference<Connection> pCon = new Connection(); pCon->construct(url, info); - m_xConnections.push_back(WeakReferenceHelper(*pCon)); + m_xConnections.emplace_back(*pCon); - return xCon; + return pCon; } sal_Bool SAL_CALL FirebirdDriver::acceptsURL( const OUString& url ) @@ -193,8 +190,9 @@ sal_Int32 SAL_CALL FirebirdDriver::getMinorVersion( ) uno::Reference< XTablesSupplier > SAL_CALL FirebirdDriver::getDataDefinitionByConnection( const uno::Reference< XConnection >& rConnection) { - Connection* pConnection = static_cast< Connection* >(rConnection.get()); - return pConnection->createCatalog(); + if (Connection* pConnection = comphelper::getFromUnoTunnel<Connection>(rConnection)) + return pConnection->createCatalog(); + return {}; } uno::Reference< XTablesSupplier > SAL_CALL FirebirdDriver::getDataDefinitionByURL( @@ -227,5 +225,4 @@ connectivity_FirebirdDriver_get_implementation( } } - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Driver.hxx b/connectivity/source/drivers/firebird/Driver.hxx index 59cb1c49db69..d884b5008d6a 100644 --- a/connectivity/source/drivers/firebird/Driver.hxx +++ b/connectivity/source/drivers/firebird/Driver.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -17,8 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_DRIVER_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_DRIVER_HXX +#pragma once #include "Connection.hxx" @@ -34,7 +33,9 @@ namespace connectivity::firebird // The SQL dialect in use // Has to be used in various isc_* calls. // 3: Is IB6 -- minimum required for delimited identifiers. - const int FIREBIRD_SQL_DIALECT = 3; + // SQL_DIALECT_V6 = 3, it's the last current version + // SQL_DIALECT_CURRENT is an alias for SQL_DIALECT_V6 + // See src/dsql/sqlda_pub.h for full details typedef ::cppu::WeakComponentImplHelper< css::sdbc::XDriver, css::sdbcx::XDataDefinitionSupplier, @@ -44,8 +45,8 @@ namespace connectivity::firebird { private: css::uno::Reference<css::uno::XComponentContext> m_aContext; - ::utl::TempFile m_firebirdTMPDirectory; - ::utl::TempFile m_firebirdLockDirectory; + ::utl::TempFileNamed m_firebirdTMPDirectory; + ::utl::TempFileNamed m_firebirdLockDirectory; protected: ::osl::Mutex m_aMutex; // mutex is need to control member access @@ -86,6 +87,4 @@ namespace connectivity::firebird } -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_DRIVER_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Indexes.cxx b/connectivity/source/drivers/firebird/Indexes.cxx index 6cdb8eb4ab5f..7bf783c79c7b 100644 --- a/connectivity/source/drivers/firebird/Indexes.cxx +++ b/connectivity/source/drivers/firebird/Indexes.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -13,12 +13,11 @@ using namespace ::connectivity; using namespace ::connectivity::firebird; using namespace ::osl; -using namespace ::std; using namespace ::com::sun::star; using namespace ::com::sun::star::sdbc; -Indexes::Indexes(Table* pTable, Mutex& rMutex, const vector<OUString>& rVector) +Indexes::Indexes(Table* pTable, Mutex& rMutex, const std::vector<OUString>& rVector) : OIndexesHelper(pTable, rMutex, rVector) , m_pTable(pTable) { @@ -30,3 +29,5 @@ void Indexes::dropObject(sal_Int32 /*nPosition*/, const OUString& sIndexName) OUString sSql("DROP INDEX \"" + sIndexName + "\""); m_pTable->getConnection()->createStatement()->execute(sSql); } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Indexes.hxx b/connectivity/source/drivers/firebird/Indexes.hxx index 7f1044cb8b0a..12d7dd198028 100644 --- a/connectivity/source/drivers/firebird/Indexes.hxx +++ b/connectivity/source/drivers/firebird/Indexes.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -7,8 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_INDEXES_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_INDEXES_HXX +#pragma once #include "Table.hxx" @@ -37,6 +36,4 @@ namespace connectivity::firebird } // namespace connectivity::firebird -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_INDEXES_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Keys.cxx b/connectivity/source/drivers/firebird/Keys.cxx index dd4cca47fb20..8de112ec6fc4 100644 --- a/connectivity/source/drivers/firebird/Keys.cxx +++ b/connectivity/source/drivers/firebird/Keys.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -51,4 +51,4 @@ void Keys::dropObject(sal_Int32 nPosition, const OUString& sName) } } -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Keys.hxx b/connectivity/source/drivers/firebird/Keys.hxx index 466ee9c81d0e..4e9ba5a7eede 100644 --- a/connectivity/source/drivers/firebird/Keys.hxx +++ b/connectivity/source/drivers/firebird/Keys.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -7,8 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_KEYS_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_KEYS_HXX +#pragma once #include <connectivity/TKeys.hxx> @@ -33,6 +32,5 @@ namespace connectivity::firebird }; } -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_KEYS_HXX -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/PreparedStatement.cxx b/connectivity/source/drivers/firebird/PreparedStatement.cxx index e4510b758055..35847d021ea0 100644 --- a/connectivity/source/drivers/firebird/PreparedStatement.cxx +++ b/connectivity/source/drivers/firebird/PreparedStatement.cxx @@ -20,8 +20,6 @@ #include <sal/config.h> #include <cmath> -#include <string_view> - #include "Connection.hxx" #include "PreparedStatement.hxx" #include "ResultSet.hxx" @@ -52,6 +50,8 @@ using namespace com::sun::star::util; IMPLEMENT_SERVICE_INFO(OPreparedStatement,"com.sun.star.sdbcx.firebird.PreparedStatement","com.sun.star.sdbc.PreparedStatement"); +constexpr size_t MAX_SIZE_SEGMENT = 65535; // max value of a segment of CLOB, if we want more than 65535 bytes, we need more segments + OPreparedStatement::OPreparedStatement( Connection* _pConnection, const OUString& sql) @@ -81,9 +81,7 @@ void OPreparedStatement::ensurePrepared() m_pInSqlda->sqln = 10; } - prepareAndDescribeStatement(m_sSqlStatement, - m_pOutSqlda, - m_pInSqlda); + prepareAndDescribeStatement(m_sSqlStatement, m_pOutSqlda); aErr = isc_dsql_describe_bind(m_statusVector, &m_aStatementHandle, @@ -118,12 +116,12 @@ OPreparedStatement::~OPreparedStatement() { } -void SAL_CALL OPreparedStatement::acquire() throw() +void SAL_CALL OPreparedStatement::acquire() noexcept { OStatementCommonBase::acquire(); } -void SAL_CALL OPreparedStatement::release() throw() +void SAL_CALL OPreparedStatement::release() noexcept { OStatementCommonBase::release(); } @@ -211,7 +209,8 @@ void SAL_CALL OPreparedStatement::setString(sal_Int32 nParameterIndex, { str = str.copy(0, max_varchar_len); } - const auto nLength = str.getLength(); + const sal_uInt16 nLength = str.getLength(); + static_assert(sizeof(nLength) == 2, "must match dest memcpy len"); memcpy(pVar->sqldata, &nLength, 2); // Actual data memcpy(pVar->sqldata + 2, str.getStr(), str.getLength()); @@ -264,6 +263,12 @@ void SAL_CALL OPreparedStatement::setString(sal_Int32 nParameterIndex, setBoolean(nParameterIndex, boolValue); break; } + case SQL_NULL: + { + // See https://www.firebirdsql.org/file/documentation/html/en/refdocs/fblangref25/firebird-25-language-reference.html#fblangref25-datatypes-special-sqlnull + pVar->sqldata = nullptr; + break; + } default: ::dbtools::throwSQLException( "Incorrect type for setString", @@ -277,7 +282,7 @@ Reference< XConnection > SAL_CALL OPreparedStatement::getConnection() MutexGuard aGuard( m_aMutex ); checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed); - return Reference<XConnection>(m_pConnection.get()); + return m_pConnection; } sal_Bool SAL_CALL OPreparedStatement::execute() @@ -307,7 +312,7 @@ sal_Bool SAL_CALL OPreparedStatement::execute() // Do not throw error. Trying to close a closed cursor is not a // critical mistake. OUString sErrMsg = StatusVectorToString(m_statusVector, - "isc_dsql_free_statement: close cursor"); + u"isc_dsql_free_statement: close cursor"); SAL_WARN("connectivity.firebird", sErrMsg); } } @@ -320,7 +325,7 @@ sal_Bool SAL_CALL OPreparedStatement::execute() if (aErr) { SAL_WARN("connectivity.firebird", "isc_dsql_execute failed" ); - evaluateStatusVector(m_statusVector, "isc_dsql_execute", *this); + evaluateStatusVector(m_statusVector, u"isc_dsql_execute", *this); } m_xResultSet = new OResultSet(m_pConnection.get(), @@ -329,9 +334,6 @@ sal_Bool SAL_CALL OPreparedStatement::execute() m_aStatementHandle, m_pOutSqlda); - if (getStatementChangeCount() > 0) - m_pConnection->notifyDatabaseModified(); - return m_xResultSet.is(); // TODO: implement handling of multiple ResultSets. } @@ -374,10 +376,10 @@ sal_Int64 toNumericWithoutDecimalPlace(const OUString& sSource) OUStringBuffer sBuffer(15); if(nDotIndex > 0) { - sBuffer.append(std::u16string_view(sNumber).substr(0, nDotIndex)); + sBuffer.append(sNumber.subView(0, nDotIndex)); } - sBuffer.append(std::u16string_view(sNumber).substr(nDotIndex + 1)); - return sBuffer.makeStringAndClear().toInt64(); + sBuffer.append(sNumber.subView(nDotIndex + 1)); + return o3tl::toInt64(sBuffer); } } @@ -565,7 +567,7 @@ void OPreparedStatement::openBlobForWriting(isc_blob_handle& rBlobHandle, ISC_QU if (aErr) { evaluateStatusVector(m_statusVector, - "setBlob failed on " + m_sSqlStatement, + Concat2View("setBlob failed on " + m_sSqlStatement), *this); assert(false); } @@ -580,7 +582,7 @@ void OPreparedStatement::closeBlobAfterWriting(isc_blob_handle& rBlobHandle) if (aErr) { evaluateStatusVector(m_statusVector, - "isc_close_blob failed", + u"isc_close_blob failed", *this); assert(false); } @@ -607,9 +609,9 @@ void SAL_CALL OPreparedStatement::setClob(sal_Int32 nParameterIndex, const Refer sal_Int64 nCharWritten = 1; // XClob is indexed from 1 ISC_STATUS aErr = 0; sal_Int64 nLen = xClob->length(); - while ( nLen > nCharWritten ) + while ( nLen >= nCharWritten ) { - sal_Int64 nCharRemain = nLen - nCharWritten; + sal_Int64 nCharRemain = nLen - nCharWritten + 1; constexpr sal_uInt16 MAX_SIZE = SAL_MAX_UINT16 / 4; sal_uInt16 nWriteSize = std::min<sal_Int64>(nCharRemain, MAX_SIZE); OString sData = OUStringToOString( @@ -632,7 +634,7 @@ void SAL_CALL OPreparedStatement::setClob(sal_Int32 nParameterIndex, const Refer if (aErr) { evaluateStatusVector(m_statusVector, - "isc_put_segment failed", + u"isc_put_segment failed", *this); assert(false); } @@ -658,10 +660,41 @@ void OPreparedStatement::setClob( sal_Int32 nParameterIndex, const OUString& rSt OString sData = OUStringToOString( rStr, RTL_TEXTENCODING_UTF8); - ISC_STATUS aErr = isc_put_segment( m_statusVector, + size_t nDataSize = sData.getLength(); + ISC_STATUS aErr = 0; + // we can't store more than MAX_SIZE_SEGMENT in a segment + if (nDataSize <= MAX_SIZE_SEGMENT) + { + aErr = isc_put_segment( m_statusVector, &aBlobHandle, sData.getLength(), sData.getStr() ); + } + else + { + // if we need more, let's split the input and first let's calculate the nb of entire chunks needed + size_t nNbEntireChunks = nDataSize / MAX_SIZE_SEGMENT; + for (size_t i = 0; i < nNbEntireChunks; ++i) + { + OString strCurrentChunk = sData.copy(i * MAX_SIZE_SEGMENT, MAX_SIZE_SEGMENT); + aErr = isc_put_segment( m_statusVector, + &aBlobHandle, + strCurrentChunk.getLength(), + strCurrentChunk.getStr() ); + if (aErr) + break; + } + size_t nRemainingBytes = nDataSize - (nNbEntireChunks * MAX_SIZE_SEGMENT); + if (nRemainingBytes && !aErr) + { + // then copy the remaining + OString strCurrentChunk = sData.copy(nNbEntireChunks * MAX_SIZE_SEGMENT, nRemainingBytes); + aErr = isc_put_segment( m_statusVector, + &aBlobHandle, + strCurrentChunk.getLength(), + strCurrentChunk.getStr() ); + } + } // We need to make sure we close the Blob even if there are errors, hence evaluate // errors after closing. @@ -670,7 +703,7 @@ void OPreparedStatement::setClob( sal_Int32 nParameterIndex, const OUString& rSt if (aErr) { evaluateStatusVector(m_statusVector, - "isc_put_segment failed", + u"isc_put_segment failed", *this); assert(false); } @@ -722,7 +755,7 @@ void SAL_CALL OPreparedStatement::setBlob(sal_Int32 nParameterIndex, if (aErr) { evaluateStatusVector(m_statusVector, - "isc_put_segment failed", + u"isc_put_segment failed", *this); assert(false); } @@ -780,7 +813,7 @@ void SAL_CALL OPreparedStatement::setObjectWithInfo( sal_Int32 parameterIndex, c sBuffer.append(sValue); if(sValue.indexOf('.') != -1) // there is a dot { - for(sal_Int32 i=sValue.copy(sValue.indexOf('.')+1).getLength(); i<scale;i++) + for(sal_Int32 i=sValue.subView(sValue.indexOf('.')+1).size(); i<scale;i++) { sBuffer.append('0'); } @@ -890,7 +923,7 @@ void SAL_CALL OPreparedStatement::setBytes(sal_Int32 nParameterIndex, if (aErr) { evaluateStatusVector(m_statusVector, - "isc_put_segment failed", + u"isc_put_segment failed", *this); assert(false); } @@ -906,7 +939,7 @@ void SAL_CALL OPreparedStatement::setBytes(sal_Int32 nParameterIndex, { xBytesCopy.realloc( nMaxSize ); } - const auto nSize = xBytesCopy.getLength(); + const sal_uInt16 nSize = xBytesCopy.getLength(); // 8000 corresponds to value from lcl_addDefaultParameters // in dbaccess/source/filter/hsqldb/createparser.cxx if (nSize > 8000) @@ -914,6 +947,7 @@ void SAL_CALL OPreparedStatement::setBytes(sal_Int32 nParameterIndex, free(pVar->sqldata); pVar->sqldata = static_cast<char *>(malloc(sizeof(char) * nSize + 2)); } + static_assert(sizeof(nSize) == 2, "must match dest memcpy len"); // First 2 bytes indicate string size memcpy(pVar->sqldata, &nSize, 2); // Actual data @@ -921,9 +955,12 @@ void SAL_CALL OPreparedStatement::setBytes(sal_Int32 nParameterIndex, } else if( dType == SQL_TEXT ) { + if (pVar->sqllen < xBytes.getLength()) + dbtools::throwSQLException("Data too big for this field", + dbtools::StandardSQLState::INVALID_SQL_DATA_TYPE, *this); setParameterNull(nParameterIndex, false); memcpy(pVar->sqldata, xBytes.getConstArray(), xBytes.getLength() ); - // Fill remainder with spaces + // Fill remainder with zeroes memset(pVar->sqldata + xBytes.getLength(), 0, pVar->sqllen - xBytes.getLength()); } else @@ -1015,4 +1052,4 @@ void OPreparedStatement::setParameterNull(sal_Int32 nParameterIndex, *pVar->sqlind = 0; } -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/PreparedStatement.hxx b/connectivity/source/drivers/firebird/PreparedStatement.hxx index db64c0b763e7..3e61436b5874 100644 --- a/connectivity/source/drivers/firebird/PreparedStatement.hxx +++ b/connectivity/source/drivers/firebird/PreparedStatement.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -17,8 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_PREPAREDSTATEMENT_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_PREPAREDSTATEMENT_HXX +#pragma once #include "StatementCommonBase.hxx" @@ -90,8 +89,8 @@ namespace connectivity::firebird //XInterface virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type & rType ) override; - virtual void SAL_CALL acquire() throw() override; - virtual void SAL_CALL release() throw() override; + virtual void SAL_CALL acquire() noexcept override; + virtual void SAL_CALL release() noexcept override; //XTypeProvider virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes( ) override; @@ -149,6 +148,5 @@ namespace connectivity::firebird }; } -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_PREPAREDSTATEMENT_HXX -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/ResultSet.cxx b/connectivity/source/drivers/firebird/ResultSet.cxx index 7ae77c607e0d..ea3ac86ae762 100644 --- a/connectivity/source/drivers/firebird/ResultSet.cxx +++ b/connectivity/source/drivers/firebird/ResultSet.cxx @@ -144,7 +144,7 @@ sal_Bool SAL_CALL OResultSet::next() { SAL_WARN("connectivity.firebird", "Error when fetching data"); // Throws sql exception as appropriate - evaluateStatusVector(m_statusVector, "isc_dsql_fetch", *this); + evaluateStatusVector(m_statusVector, u"isc_dsql_fetch", *this); return false; } } @@ -430,13 +430,29 @@ T OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT nType) if ((m_pSqlda->sqlvar[nColumnIndex-1].sqltype & ~1) == nType) return *reinterpret_cast<T*>(m_pSqlda->sqlvar[nColumnIndex-1].sqldata); else - return retrieveValue< ORowSetValue >(nColumnIndex, 0); + { + ORowSetValue row = retrieveValue< ORowSetValue >(nColumnIndex, 0); + if constexpr ( std::is_same_v<sal_Int64, T> ) + return row.getLong(); + else if constexpr ( std::is_same_v<sal_Int32, T> ) + return row.getInt32(); + else if constexpr ( std::is_same_v<sal_Int16, T> ) + return row.getInt16(); + else if constexpr ( std::is_same_v<float, T> ) + return row.getFloat(); + else if constexpr ( std::is_same_v<double, T> ) + return row.getDouble(); + else if constexpr ( std::is_same_v<bool, T> ) + return row.getBool(); + else + return row; + } } template <> ORowSetValue OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT /*nType*/) { - // See http://wiki.openoffice.org/wiki/Documentation/DevGuide/Database/Using_the_getXXX_Methods + // See https://wiki.documentfoundation.org/Documentation/DevGuide/Database_Access#Using_the_getXXX_Methods // (bottom of page) for a chart of possible conversions, we should allow all // of these -- Blob/Clob will probably need some specialist handling especially // w.r.t. to generating Strings for them. @@ -511,7 +527,7 @@ Date OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT /*n } else { - return retrieveValue< ORowSetValue >(nColumnIndex, 0); + return retrieveValue< ORowSetValue >(nColumnIndex, 0).getDate(); } } @@ -534,7 +550,7 @@ Time OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT /*n } else { - return retrieveValue< ORowSetValue >(nColumnIndex, 0); + return retrieveValue< ORowSetValue >(nColumnIndex, 0).getTime(); } } @@ -560,7 +576,7 @@ DateTime OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT } else { - return retrieveValue< ORowSetValue >(nColumnIndex, 0); + return retrieveValue< ORowSetValue >(nColumnIndex, 0).getDateTime(); } } @@ -579,10 +595,11 @@ OUString OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT else if (aSqlType == SQL_VARYING) { // First 2 bytes are a short containing the length of the string - // No idea if sqllen is still valid here? + // Under unclear conditions, it may be wrong and greater than sqllen. sal_uInt16 aLength = *reinterpret_cast<sal_uInt16*>(m_pSqlda->sqlvar[nColumnIndex-1].sqldata); + // Use greater signed type sal_Int32 to get the minimum of two 16-bit values return OUString(m_pSqlda->sqlvar[nColumnIndex-1].sqldata + 2, - aLength, + std::min<sal_Int32>(aLength, m_pSqlda->sqlvar[nColumnIndex-1].sqllen), RTL_TEXTENCODING_UTF8); } else if ((aSqlType == SQL_SHORT || aSqlType == SQL_LONG || @@ -610,11 +627,11 @@ OUString OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT else if(aSqlType == SQL_BLOB && aSqlSubType == static_cast<short>(BlobSubtype::Clob) ) { uno::Reference<XClob> xClob = getClob(nColumnIndex); - return xClob->getSubString( 0, xClob->length() ); + return xClob->getSubString( 1, xClob->length() ); } else { - return retrieveValue< ORowSetValue >(nColumnIndex, 0); + return retrieveValue< ORowSetValue >(nColumnIndex, 0).getString(); } } @@ -662,7 +679,7 @@ sal_Bool SAL_CALL OResultSet::getBoolean(sal_Int32 nColumnIndex) sal_Int8 SAL_CALL OResultSet::getByte(sal_Int32 nColumnIndex) { // Not a native firebird type hence we always have to convert. - return safelyRetrieveValue< ORowSetValue >(nColumnIndex); + return safelyRetrieveValue< ORowSetValue >(nColumnIndex).getInt8(); } Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes(sal_Int32 nColumnIndex) @@ -875,12 +892,12 @@ IPropertyArrayHelper & OResultSet::getInfoHelper() return *getArrayHelper(); } -void SAL_CALL OResultSet::acquire() throw() +void SAL_CALL OResultSet::acquire() noexcept { OResultSet_BASE::acquire(); } -void SAL_CALL OResultSet::release() throw() +void SAL_CALL OResultSet::release() noexcept { OResultSet_BASE::release(); } @@ -906,4 +923,4 @@ sal_Bool SAL_CALL OResultSet::supportsService(const OUString& _rServiceName) return cppu::supportsService(this, _rServiceName); } -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/ResultSet.hxx b/connectivity/source/drivers/firebird/ResultSet.hxx index 7306e0c42405..fdae21dfbaaf 100644 --- a/connectivity/source/drivers/firebird/ResultSet.hxx +++ b/connectivity/source/drivers/firebird/ResultSet.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -17,8 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_RESULTSET_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_RESULTSET_HXX +#pragma once #include "Connection.hxx" @@ -123,8 +122,8 @@ namespace connectivity::firebird // XInterface virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& rType) override; - virtual void SAL_CALL acquire() throw() override; - virtual void SAL_CALL release() throw() override; + virtual void SAL_CALL acquire() noexcept override; + virtual void SAL_CALL release() noexcept override; //XTypeProvider virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes( ) override; // XPropertySet @@ -213,6 +212,5 @@ namespace connectivity::firebird const ISC_SHORT nType); } -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_RESULTSET_HXX -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/ResultSetMetaData.cxx b/connectivity/source/drivers/firebird/ResultSetMetaData.cxx index d21115029df3..31a6796f5399 100644 --- a/connectivity/source/drivers/firebird/ResultSetMetaData.cxx +++ b/connectivity/source/drivers/firebird/ResultSetMetaData.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -53,8 +53,8 @@ OUString OResultSetMetaData::getCharacterSet( sal_Int32 nIndex ) "JOIN RDB$RELATION_FIELDS relfields " "ON (fields.RDB$FIELD_NAME = relfields.RDB$FIELD_SOURCE) " "WHERE relfields.RDB$RELATION_NAME = '" - + escapeWith(sTable, '\'', '\'') + "' AND " - "relfields.RDB$FIELD_NAME = '"+ escapeWith(sColumnName, '\'', '\'') +"'"; + + sTable.replaceAll("'", "''") + "' AND " + "relfields.RDB$FIELD_NAME = '"+ sColumnName.replaceAll("'", "''") +"'"; Reference<XStatement> xStmt= m_pConnection->createStatement(); @@ -128,9 +128,15 @@ OUString SAL_CALL OResultSetMetaData::getSchemaName(sal_Int32) OUString SAL_CALL OResultSetMetaData::getColumnName(sal_Int32 column) { verifyValidColumn(column); - OUString sRet(m_pSqlda->sqlvar[column-1].sqlname, - m_pSqlda->sqlvar[column-1].sqlname_length, - RTL_TEXTENCODING_UTF8); + char* pColumnName = m_pSqlda->sqlvar[column - 1].sqlname; + sal_Int32 nColumnNameLength = m_pSqlda->sqlvar[column - 1].sqlname_length; + // tdf#132924 - return column alias if specified + if (m_pSqlda->sqlvar[column - 1].aliasname_length > 0) + { + pColumnName = m_pSqlda->sqlvar[column - 1].aliasname; + nColumnNameLength = m_pSqlda->sqlvar[column - 1].aliasname_length; + } + OUString sRet(pColumnName, nColumnNameLength, RTL_TEXTENCODING_UTF8); sanitizeIdentifier(sRet); return sRet; } @@ -184,34 +190,34 @@ sal_Bool SAL_CALL OResultSetMetaData::isCurrency(sal_Int32) sal_Bool SAL_CALL OResultSetMetaData::isAutoIncrement(sal_Int32 column) { OUString sTable = getTableName(column); - if( !sTable.isEmpty() ) - { - OUString sColumnName = getColumnName( column ); + if( sTable.isEmpty() ) + return false; - OUString sSql = "SELECT RDB$IDENTITY_TYPE FROM RDB$RELATION_FIELDS " - "WHERE RDB$RELATION_NAME = '" - + escapeWith(sTable, '\'', '\'') + "' AND " - "RDB$FIELD_NAME = '"+ escapeWith(sColumnName, '\'', '\'') +"'"; + OUString sColumnName = getColumnName( column ); - Reference<XStatement> xStmt =m_pConnection ->createStatement(); + OUString sSql = "SELECT RDB$IDENTITY_TYPE FROM RDB$RELATION_FIELDS " + "WHERE RDB$RELATION_NAME = '" + + sTable.replaceAll("'", "''") + "' AND " + "RDB$FIELD_NAME = '"+ sColumnName.replaceAll("'", "''") +"'"; - Reference<XResultSet> xRes = - xStmt->executeQuery(sSql); - Reference<XRow> xRow ( xRes, UNO_QUERY); - if(xRes->next()) - { - int iType = xRow->getShort(1); - if(iType == 1) // IDENTITY - return true; - } - else - { - SAL_WARN("connectivity.firebird","Column '" - << sColumnName - << "' not found in database"); + Reference<XStatement> xStmt =m_pConnection ->createStatement(); - return false; - } + Reference<XResultSet> xRes = + xStmt->executeQuery(sSql); + Reference<XRow> xRow ( xRes, UNO_QUERY); + if(xRes->next()) + { + int iType = xRow->getShort(1); + if(iType == 1) // IDENTITY + return true; + } + else + { + SAL_WARN("connectivity.firebird","Column '" + << sColumnName + << "' not found in database"); + + return false; } return false; } @@ -226,34 +232,34 @@ sal_Bool SAL_CALL OResultSetMetaData::isSigned(sal_Int32) sal_Int32 SAL_CALL OResultSetMetaData::getPrecision(sal_Int32 column) { sal_Int32 nType = getColumnType(column); - if( nType == DataType::NUMERIC || nType == DataType::DECIMAL ) + if( nType != DataType::NUMERIC && nType != DataType::DECIMAL ) + return 0; + + OUString sColumnName = getColumnName( column ); + + // RDB$FIELD_SOURCE is a unique name of column per database + OUString sSql = "SELECT RDB$FIELD_PRECISION FROM RDB$FIELDS " + " INNER JOIN RDB$RELATION_FIELDS " + " ON RDB$RELATION_FIELDS.RDB$FIELD_SOURCE = RDB$FIELDS.RDB$FIELD_NAME " + "WHERE RDB$RELATION_FIELDS.RDB$RELATION_NAME = '" + + getTableName(column).replaceAll("'", "''") + "' AND " + "RDB$RELATION_FIELDS.RDB$FIELD_NAME = '" + + sColumnName.replaceAll("'", "''") +"'"; + Reference<XStatement> xStmt= m_pConnection->createStatement(); + + Reference<XResultSet> xRes = + xStmt->executeQuery(sSql); + Reference<XRow> xRow ( xRes, UNO_QUERY); + if(xRes->next()) { - OUString sColumnName = getColumnName( column ); - - // RDB$FIELD_SOURCE is a unique name of column per database - OUString sSql = "SELECT RDB$FIELD_PRECISION FROM RDB$FIELDS " - " INNER JOIN RDB$RELATION_FIELDS " - " ON RDB$RELATION_FIELDS.RDB$FIELD_SOURCE = RDB$FIELDS.RDB$FIELD_NAME " - "WHERE RDB$RELATION_FIELDS.RDB$RELATION_NAME = '" - + escapeWith(getTableName(column), '\'', '\'') + "' AND " - "RDB$RELATION_FIELDS.RDB$FIELD_NAME = '" - + escapeWith(sColumnName, '\'', '\'') +"'"; - Reference<XStatement> xStmt= m_pConnection->createStatement(); - - Reference<XResultSet> xRes = - xStmt->executeQuery(sSql); - Reference<XRow> xRow ( xRes, UNO_QUERY); - if(xRes->next()) - { - return static_cast<sal_Int32>(xRow->getShort(1)); - } - else - { - SAL_WARN("connectivity.firebird","Column '" - << sColumnName - << "' not found in database"); - return 0; - } + return static_cast<sal_Int32>(xRow->getShort(1)); + } + else + { + SAL_WARN("connectivity.firebird","Column '" + << sColumnName + << "' not found in database"); + return 0; } return 0; } @@ -292,5 +298,4 @@ sal_Bool SAL_CALL OResultSetMetaData::isWritable( sal_Int32 ) return !m_pConnection->isReadOnly(); } - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/ResultSetMetaData.hxx b/connectivity/source/drivers/firebird/ResultSetMetaData.hxx index 95c36ab958d4..a32c206213aa 100644 --- a/connectivity/source/drivers/firebird/ResultSetMetaData.hxx +++ b/connectivity/source/drivers/firebird/ResultSetMetaData.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -17,8 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_RESULTSETMETADATA_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_RESULTSETMETADATA_HXX +#pragma once #include "Connection.hxx" @@ -78,6 +77,4 @@ namespace connectivity::firebird } -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_RESULTSETMETADATA_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Statement.cxx b/connectivity/source/drivers/firebird/Statement.cxx index 418c66a7d0cd..d135c4e4cda4 100644 --- a/connectivity/source/drivers/firebird/Statement.cxx +++ b/connectivity/source/drivers/firebird/Statement.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -40,7 +40,6 @@ using namespace com::sun::star::util; using namespace ::comphelper; using namespace ::osl; -using namespace ::std; // ---- XBatchExecution - UNSUPPORTED ---------------------------------------- void SAL_CALL OStatement::addBatch(const OUString&) @@ -58,12 +57,12 @@ Sequence< sal_Int32 > SAL_CALL OStatement::executeBatch() IMPLEMENT_SERVICE_INFO(OStatement,"com.sun.star.sdbcx.OStatement","com.sun.star.sdbc.Statement"); -void SAL_CALL OStatement::acquire() throw() +void SAL_CALL OStatement::acquire() noexcept { OStatementCommonBase::acquire(); } -void SAL_CALL OStatement::release() throw() +void SAL_CALL OStatement::release() noexcept { OStatementCommonBase::release(); } @@ -71,7 +70,8 @@ void SAL_CALL OStatement::release() throw() void OStatement::disposeResultSet() { MutexGuard aGuard(m_aMutex); - checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed); + if (OStatementCommonBase_Base::rBHelper.bDisposed) + return; OStatementCommonBase::disposeResultSet(); @@ -126,11 +126,6 @@ uno::Reference< XResultSet > SAL_CALL OStatement::executeQuery(const OUString& s if (isDDLStatement()) { m_pConnection->commit(); - m_pConnection->notifyDatabaseModified(); - } - else if (getStatementChangeCount() > 0) - { - m_pConnection->notifyDatabaseModified(); } return m_xResultSet; @@ -148,7 +143,7 @@ uno::Reference< XConnection > SAL_CALL OStatement::getConnection() MutexGuard aGuard(m_aMutex); checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed); - return uno::Reference<XConnection>(m_pConnection.get()); + return m_pConnection; } Any SAL_CALL OStatement::queryInterface( const Type & rType ) @@ -172,4 +167,5 @@ void SAL_CALL OStatement::disposing() disposeResultSet(); close(); } -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Statement.hxx b/connectivity/source/drivers/firebird/Statement.hxx index 903f12407ee8..d1b967def1d5 100644 --- a/connectivity/source/drivers/firebird/Statement.hxx +++ b/connectivity/source/drivers/firebird/Statement.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -17,8 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_STATEMENT_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_STATEMENT_HXX +#pragma once #include "StatementCommonBase.hxx" @@ -51,8 +50,8 @@ namespace connectivity::firebird DECLARE_SERVICE_INFO(); - virtual void SAL_CALL acquire() throw() override; - virtual void SAL_CALL release() throw() override; + virtual void SAL_CALL acquire() noexcept override; + virtual void SAL_CALL release() noexcept override; // XStatement virtual css::uno::Reference< css::sdbc::XResultSet > SAL_CALL @@ -81,6 +80,5 @@ namespace connectivity::firebird }; } -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_STATEMENT_HXX -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/StatementCommonBase.cxx b/connectivity/source/drivers/firebird/StatementCommonBase.cxx index 1d7d5ef32bdf..29ef5925657d 100644 --- a/connectivity/source/drivers/firebird/StatementCommonBase.cxx +++ b/connectivity/source/drivers/firebird/StatementCommonBase.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -17,7 +17,6 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#include "Driver.hxx" #include "StatementCommonBase.hxx" #include "Util.hxx" @@ -44,7 +43,6 @@ using namespace ::com::sun::star::util; using namespace ::comphelper; using namespace ::osl; -using namespace ::std; OStatementCommonBase::OStatementCommonBase(Connection* _pConnection) : OStatementCommonBase_Base(m_aMutex), @@ -78,7 +76,7 @@ void OStatementCommonBase::freeStatementHandle() &m_aStatementHandle, DSQL_drop); evaluateStatusVector(m_statusVector, - "isc_dsql_free_statement", + u"isc_dsql_free_statement", *this); } } @@ -124,9 +122,7 @@ void SAL_CALL OStatementCommonBase::close() dispose(); } -void OStatementCommonBase::prepareAndDescribeStatement(std::u16string_view sql, - XSQLDA*& pOutSqlda, - XSQLDA* pInSqlda) +void OStatementCommonBase::prepareAndDescribeStatement(std::u16string_view sql, XSQLDA*& pOutSqlda) { SolarMutexGuard g; // tdf#122129 @@ -146,7 +142,7 @@ void OStatementCommonBase::prepareAndDescribeStatement(std::u16string_view sql, if (aErr) { evaluateStatusVector(m_statusVector, - "isc_dsql_allocate_statement", + u"isc_dsql_allocate_statement", *this); } else @@ -156,56 +152,41 @@ void OStatementCommonBase::prepareAndDescribeStatement(std::u16string_view sql, &m_aStatementHandle, 0, OUStringToOString(sql, RTL_TEXTENCODING_UTF8).getStr(), - FIREBIRD_SQL_DIALECT, - pInSqlda); + SQL_DIALECT_CURRENT, + pOutSqlda); if (aErr) { evaluateStatusVector(m_statusVector, - "isc_dsql_prepare", + u"isc_dsql_prepare", *this); } else { - aErr = isc_dsql_describe(m_statusVector, - &m_aStatementHandle, - 1, - pOutSqlda); + // Ensure we have enough space in pOutSqlda + if (pOutSqlda->sqld > pOutSqlda->sqln) + { + int n = pOutSqlda->sqld; + free(pOutSqlda); + pOutSqlda = static_cast<XSQLDA*>(calloc(1, XSQLDA_LENGTH(n))); + pOutSqlda->version = SQLDA_VERSION1; + pOutSqlda->sqln = n; + aErr = isc_dsql_describe(m_statusVector, + &m_aStatementHandle, + 1, + pOutSqlda); + } + // Process each XSQLVAR parameter structure in the output XSQLDA if (aErr) { - // TODO: free statement handle, etc.? evaluateStatusVector(m_statusVector, - "isc_dsql_describe", + u"isc_dsql_describe", *this); } else { - // Ensure we have enough space in pOutSqlda - if (pOutSqlda->sqld > pOutSqlda->sqln) - { - int n = pOutSqlda->sqld; - free(pOutSqlda); - pOutSqlda = static_cast<XSQLDA*>(calloc(1, XSQLDA_LENGTH(n))); - pOutSqlda->version = SQLDA_VERSION1; - pOutSqlda->sqln = n; - aErr = isc_dsql_describe(m_statusVector, - &m_aStatementHandle, - 1, - pOutSqlda); - } - - // Process each XSQLVAR parameter structure in the output XSQLDA - if (aErr) - { - evaluateStatusVector(m_statusVector, - "isc_dsql_describe", - *this); - } - else - { - mallocSQLVAR(pOutSqlda); - } + mallocSQLVAR(pOutSqlda); } } if(aErr) @@ -260,31 +241,71 @@ void SAL_CALL OStatementCommonBase::clearWarnings() { // this properties are define by the service statement // they must in alphabetic order - Sequence< Property > aProps(10); - Property* pProperties = aProps.getArray(); - sal_Int32 nPos = 0; - pProperties[nPos++] = css::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_CURSORNAME), - PROPERTY_ID_CURSORNAME, cppu::UnoType<OUString>::get(), 0); - pProperties[nPos++] = css::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ESCAPEPROCESSING), - PROPERTY_ID_ESCAPEPROCESSING, cppu::UnoType<bool>::get(), 0); - pProperties[nPos++] = css::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION), - PROPERTY_ID_FETCHDIRECTION, cppu::UnoType<sal_Int32>::get(), 0); - pProperties[nPos++] = css::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE), - PROPERTY_ID_FETCHSIZE, cppu::UnoType<sal_Int32>::get(), 0); - pProperties[nPos++] = css::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXFIELDSIZE), - PROPERTY_ID_MAXFIELDSIZE, cppu::UnoType<sal_Int32>::get(), 0); - pProperties[nPos++] = css::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXROWS), - PROPERTY_ID_MAXROWS, cppu::UnoType<sal_Int32>::get(), 0); - pProperties[nPos++] = css::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_QUERYTIMEOUT), - PROPERTY_ID_QUERYTIMEOUT, cppu::UnoType<sal_Int32>::get(), 0); - pProperties[nPos++] = css::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY), - PROPERTY_ID_RESULTSETCONCURRENCY, cppu::UnoType<sal_Int32>::get(), 0); - pProperties[nPos++] = css::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE), - PROPERTY_ID_RESULTSETTYPE, cppu::UnoType<sal_Int32>::get(), 0); - pProperties[nPos++] = css::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_USEBOOKMARKS), - PROPERTY_ID_USEBOOKMARKS, cppu::UnoType<bool>::get(), 0); - - return new ::cppu::OPropertyArrayHelper(aProps); + return new ::cppu::OPropertyArrayHelper + { + { + { + ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_CURSORNAME), + PROPERTY_ID_CURSORNAME, + cppu::UnoType<OUString>::get(), + 0 + }, + { + ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ESCAPEPROCESSING), + PROPERTY_ID_ESCAPEPROCESSING, + cppu::UnoType<bool>::get(), + 0 + }, + { + ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION), + PROPERTY_ID_FETCHDIRECTION, + cppu::UnoType<sal_Int32>::get(), + 0 + }, + { + ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE), + PROPERTY_ID_FETCHSIZE, + cppu::UnoType<sal_Int32>::get(), + 0 + }, + { + ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXFIELDSIZE), + PROPERTY_ID_MAXFIELDSIZE, + cppu::UnoType<sal_Int32>::get(), + 0 + }, + { + ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXROWS), + PROPERTY_ID_MAXROWS, + cppu::UnoType<sal_Int32>::get(), + 0 + }, + { + ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_QUERYTIMEOUT), + PROPERTY_ID_QUERYTIMEOUT, + cppu::UnoType<sal_Int32>::get(), + 0 + }, + { + ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY), + PROPERTY_ID_RESULTSETCONCURRENCY, + cppu::UnoType<sal_Int32>::get(), + 0 + }, + { + ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE), + PROPERTY_ID_RESULTSETTYPE, + cppu::UnoType<sal_Int32>::get(), + 0 + }, + { + ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_USEBOOKMARKS), + PROPERTY_ID_USEBOOKMARKS, + cppu::UnoType<bool>::get(), + 0 + } + } + }; } @@ -342,12 +363,12 @@ void OStatementCommonBase::getFastPropertyValue(Any&,sal_Int32 nHandle) const } } -void SAL_CALL OStatementCommonBase::acquire() throw() +void SAL_CALL OStatementCommonBase::acquire() noexcept { OStatementCommonBase_Base::acquire(); } -void SAL_CALL OStatementCommonBase::release() throw() +void SAL_CALL OStatementCommonBase::release() noexcept { OStatementCommonBase_Base::release(); } @@ -379,7 +400,7 @@ short OStatementCommonBase::getSqlInfoItem(char aInfoItem) } evaluateStatusVector(aStatusVector, - "isc_dsq_sql_info", + u"isc_dsq_sql_info", *this); return 0; } @@ -411,7 +432,7 @@ sal_Int32 OStatementCommonBase::getStatementChangeCount() if (aErr) { evaluateStatusVector(aStatusVector, - "isc_dsq_sql_info", + u"isc_dsq_sql_info", *this); return 0; } @@ -432,32 +453,34 @@ sal_Int32 OStatementCommonBase::getStatementChangeCount() aDesiredInfoType = isc_info_req_delete_count; break; case isc_info_sql_stmt_exec_procedure: + case isc_info_sql_stmt_ddl: return 0; // cannot determine default: throw SQLException(); // TODO: better error message? } char* pResults = aResultsBuffer; - if (static_cast<short>(*pResults++) == isc_info_sql_records) - { -// const short aTotalLength = (short) isc_vax_integer(pResults, 2); - pResults += 2; + if (static_cast<short>(*pResults++) != isc_info_sql_records) + return 0; - // Seems to be of form TOKEN (1 byte), LENGTH (2 bytes), DATA (LENGTH bytes) - while (*pResults != isc_info_rsb_end) - { - const char aToken = *pResults; - const short aLength = static_cast<short>(isc_vax_integer(pResults+1, 2)); +// const short aTotalLength = (short) isc_vax_integer(pResults, 2); + pResults += 2; - if (aToken == aDesiredInfoType) - { - return isc_vax_integer(pResults + 3, aLength); - } + // Seems to be of form TOKEN (1 byte), LENGTH (2 bytes), DATA (LENGTH bytes) + while (*pResults != isc_info_rsb_end) + { + const char aToken = *pResults; + const short aLength = static_cast<short>(isc_vax_integer(pResults+1, 2)); - pResults += (3 + aLength); + if (aToken == aDesiredInfoType) + { + return isc_vax_integer(pResults + 3, aLength); } + + pResults += (3 + aLength); } return 0; } -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/StatementCommonBase.hxx b/connectivity/source/drivers/firebird/StatementCommonBase.hxx index c92dd8634109..fa9cd790272e 100644 --- a/connectivity/source/drivers/firebird/StatementCommonBase.hxx +++ b/connectivity/source/drivers/firebird/StatementCommonBase.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -17,8 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_STATEMENTCOMMONBASE_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_STATEMENTCOMMONBASE_HXX +#pragma once #include <sal/config.h> @@ -85,9 +84,7 @@ namespace connectivity::firebird virtual ~OStatementCommonBase() override; /// @throws css::sdbc::SQLException - void prepareAndDescribeStatement(std::u16string_view sqlIn, - XSQLDA*& pOutSqlda, - XSQLDA* pInSqlda=nullptr); + void prepareAndDescribeStatement(std::u16string_view sqlIn, XSQLDA*& pOutSqlda); /// @throws css::sdbc::SQLException short getSqlInfoItem(char aInfoItem); @@ -107,8 +104,8 @@ namespace connectivity::firebird OStatementCommonBase_Base::disposing(); } // XInterface - virtual void SAL_CALL release() throw() override; - virtual void SAL_CALL acquire() throw() override; + virtual void SAL_CALL release() noexcept override; + virtual void SAL_CALL acquire() noexcept override; // XInterface virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type & rType ) override; //XTypeProvider @@ -134,6 +131,4 @@ namespace connectivity::firebird } -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_STATEMENTCOMMONBASE_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/SubComponent.hxx b/connectivity/source/drivers/firebird/SubComponent.hxx index 4d9c107213f5..bea5d76d423d 100644 --- a/connectivity/source/drivers/firebird/SubComponent.hxx +++ b/connectivity/source/drivers/firebird/SubComponent.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -17,8 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_SUBCOMPONENT_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_SUBCOMPONENT_HXX +#pragma once #include <cppuhelper/propshlp.hxx> #include <osl/diagnose.h> @@ -108,6 +107,5 @@ namespace connectivity::firebird } } -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_SUBCOMPONENT_HXX -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Table.cxx b/connectivity/source/drivers/firebird/Table.cxx index 02718c78e731..871febcf5122 100644 --- a/connectivity/source/drivers/firebird/Table.cxx +++ b/connectivity/source/drivers/firebird/Table.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -155,27 +155,14 @@ void SAL_CALL Table::alterColumnByName(const OUString& rColName, if (nNullable != ColumnValue::NULLABLE_UNKNOWN) { - OUString sSql; - // Dirty hack: can't change null directly in sql, we have to fiddle - // the system tables manually. + OUString sSql(getAlterTableColumn(rColName)); if (nNullable == ColumnValue::NULLABLE) { - sSql = "UPDATE RDB$RELATION_FIELDS SET RDB$NULL_FLAG = NULL " - "WHERE RDB$FIELD_NAME = '" + rColName + "' " - "AND RDB$RELATION_NAME = '" + getName() + "'"; + sSql += "DROP NOT NULL"; } else if (nNullable == ColumnValue::NO_NULLS) { - // And if we are making NOT NULL then we have to make sure we have - // no nulls left in the column. - OUString sFillNulls("UPDATE \"" + getName() + "\" SET \"" - + rColName + "\" = 0 " - "WHERE \"" + rColName + "\" IS NULL"); - getConnection()->createStatement()->execute(sFillNulls); - - sSql = "UPDATE RDB$RELATION_FIELDS SET RDB$NULL_FLAG = 1 " - "WHERE RDB$FIELD_NAME = '" + rColName + "' " - "AND RDB$RELATION_NAME = '" + getName() + "'"; + sSql += "SET NOT NULL"; } getConnection()->createStatement()->execute(sSql); } @@ -237,26 +224,9 @@ Any SAL_CALL Table::queryInterface(const Type& rType) return OTableHelper::queryInterface(rType); } -// ----- XTypeProvider -------------------------------------------------------- -uno::Sequence< Type > SAL_CALL Table::getTypes() -{ - uno::Sequence< Type > aTypes = OTableHelper::getTypes(); - - for (int i = 0; i < aTypes.getLength(); i++) - { - if (aTypes[i].getTypeName() == "com.sun.star.sdbcx.XRename") - { - ::comphelper::removeElementAt(aTypes, i); - break; - } - } - - return OTableHelper::getTypes(); -} - OUString Table::getAlterTableColumn(std::u16string_view rColumn) { return ("ALTER TABLE \"" + getName() + "\" ALTER COLUMN \"" + rColumn + "\" "); } -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Table.hxx b/connectivity/source/drivers/firebird/Table.hxx index d2646dcd168d..ed638a9c88ac 100644 --- a/connectivity/source/drivers/firebird/Table.hxx +++ b/connectivity/source/drivers/firebird/Table.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -7,8 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_TABLE_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_TABLE_HXX +#pragma once #include <sal/config.h> @@ -75,14 +74,8 @@ namespace connectivity::firebird virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type & rType) override; - //XTypeProvider - virtual css::uno::Sequence< css::uno::Type > - SAL_CALL getTypes() override; - }; } // namespace connectivity::firebird -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_TABLE_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Tables.cxx b/connectivity/source/drivers/firebird/Tables.cxx index 5acb391caeb5..e3440137381a 100644 --- a/connectivity/source/drivers/firebird/Tables.cxx +++ b/connectivity/source/drivers/firebird/Tables.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -9,8 +9,8 @@ #include "Table.hxx" #include "Tables.hxx" +#include "Views.hxx" #include "Catalog.hxx" -#include "Util.hxx" #include <TConnection.hxx> @@ -30,7 +30,6 @@ using namespace ::osl; using namespace ::com::sun::star; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::container; -using namespace ::com::sun::star::lang; using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::sdbcx; using namespace ::com::sun::star::uno; @@ -81,7 +80,7 @@ OUString Tables::createStandardColumnPart(const Reference< XPropertySet >& xColP xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT)) >>= bIsAutoIncrement; const OUString sQuoteString = xMetaData->getIdentifierQuoteString(); - OUStringBuffer aSql = ::dbtools::quoteName(sQuoteString,::comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)))); + OUStringBuffer aSql(::dbtools::quoteName(sQuoteString,::comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME))))); // check if the user enter a specific string to create autoincrement values OUString sAutoIncrementValue; @@ -90,9 +89,8 @@ OUString Tables::createStandardColumnPart(const Reference< XPropertySet >& xColP if ( xPropInfo.is() && xPropInfo->hasPropertyByName(rPropMap.getNameByIndex(PROPERTY_ID_AUTOINCREMENTCREATION)) ) xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_AUTOINCREMENTCREATION)) >>= sAutoIncrementValue; - aSql.append(" "); - - aSql.append(dbtools::createStandardTypePart(xColProp, _xConnection)); + aSql.append(" " + + dbtools::createStandardTypePart(xColProp, _xConnection)); // Add character set for (VAR)BINARY (fix) types: // (VAR) BINARY is distinguished from other CHAR types by its character set. // Octets is a special character set for binary data. @@ -104,15 +102,13 @@ OUString Tables::createStandardColumnPart(const Reference< XPropertySet >& xColP >>= aType; if(aType == DataType::BINARY || aType == DataType::VARBINARY) { - aSql.append(" "); - aSql.append("CHARACTER SET OCTETS"); + aSql.append(" CHARACTER SET OCTETS"); } } if ( bIsAutoIncrement && !sAutoIncrementValue.isEmpty()) { - aSql.append(" "); - aSql.append(sAutoIncrementValue); + aSql.append(" " + sAutoIncrementValue); } // AutoIncrement "IDENTITY" is implicitly "NOT NULL" else if(::comphelper::getINT32(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_ISNULLABLE))) == ColumnValue::NO_NULLS) @@ -149,8 +145,8 @@ ObjectType Tables::appendObject(const OUString& rName, if ( sComposedName.isEmpty() ) ::dbtools::throwFunctionSequenceException(xConnection); - aSqlBuffer.append(sComposedName); - aSqlBuffer.append(" ("); + aSqlBuffer.append(sComposedName + + " ("); // columns Reference<XColumnsSupplier> xColumnSup(rDescriptor,UNO_QUERY); @@ -166,8 +162,8 @@ ObjectType Tables::appendObject(const OUString& rName, { if ( (xColumns->getByIndex(i) >>= xColProp) && xColProp.is() ) { - aSqlBuffer.append(createStandardColumnPart(xColProp,xConnection)); - aSqlBuffer.append(","); + aSqlBuffer.append(createStandardColumnPart(xColProp,xConnection) + + ","); } } OUString sSql = aSqlBuffer.makeStringAndClear(); @@ -178,7 +174,7 @@ ObjectType Tables::appendObject(const OUString& rName, else { if ( sSql.endsWith(",") ) - sSql = sSql.replaceAt(sSql.getLength()-1, 1, ")"); + sSql = sSql.replaceAt(sSql.getLength()-1, 1, u")"); else sSql += ")"; } @@ -196,16 +192,34 @@ void Tables::dropObject(sal_Int32 nPosition, const OUString& sName) if (ODescriptor::isNew(xTable)) return; - OUStringBuffer sSql("DROP "); - OUString sType; xTable->getPropertyValue("Type") >>= sType; - sSql.append(sType); const OUString sQuoteString = m_xMetaData->getIdentifierQuoteString(); - sSql.append(::dbtools::quoteName(sQuoteString,sName)); - m_xMetaData->getConnection()->createStatement()->execute(sSql.makeStringAndClear()); + m_xMetaData->getConnection()->createStatement()->execute( + "DROP " + sType + " " + ::dbtools::quoteName(sQuoteString,sName)); + + if (sType == "VIEW") + { + Views* pViews = static_cast<Views*>(static_cast<Catalog&>(m_rParent).getPrivateViews()); + if ( pViews && pViews->hasByName(sName) ) + pViews->dropByNameImpl(sName); + } } -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +void connectivity::firebird::Tables::appendNew(const OUString& _rsNewTable) +{ + insertElement(_rsNewTable, nullptr); + + // notify our container listeners + css::container::ContainerEvent aEvent(static_cast<XContainer*>(this), + css::uno::Any(_rsNewTable), css::uno::Any(), + css::uno::Any()); + comphelper::OInterfaceIteratorHelper3 aListenerLoop(m_aContainerListeners); + while (aListenerLoop.hasMoreElements()) + aListenerLoop.next()->elementInserted(aEvent); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Tables.hxx b/connectivity/source/drivers/firebird/Tables.hxx index 3f36b9865c3b..ada1827097a5 100644 --- a/connectivity/source/drivers/firebird/Tables.hxx +++ b/connectivity/source/drivers/firebird/Tables.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -7,13 +7,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_TABLES_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_TABLES_HXX +#pragma once #include <com/sun/star/sdbc/XConnection.hpp> #include <com/sun/star/sdbc/XDatabaseMetaData.hpp> #include <connectivity/sdbcx/VCollection.hxx> +#include <utility> namespace connectivity::firebird { @@ -41,10 +41,10 @@ namespace connectivity::firebird const css::uno::Reference< css::beans::XPropertySet >& rDescriptor) override; public: - Tables(const css::uno::Reference< css::sdbc::XDatabaseMetaData >& rMetaData, + Tables(css::uno::Reference< css::sdbc::XDatabaseMetaData > xMetaData, ::cppu::OWeakObject& rParent, ::osl::Mutex& rMutex, - ::std::vector< OUString> const & rNames) : sdbcx::OCollection(rParent, true, rMutex, rNames), m_xMetaData(rMetaData) {} + ::std::vector< OUString> const & rNames) : sdbcx::OCollection(rParent, true, rMutex, rNames), m_xMetaData(std::move(xMetaData)) {} // TODO: we should also implement XDataDescriptorFactory, XRefreshable, // XAppend, etc., but all are optional. @@ -52,11 +52,10 @@ namespace connectivity::firebird // XDrop virtual void dropObject(sal_Int32 nPosition, const OUString& rName) override; + void appendNew(const OUString& _rsNewTable); + }; } // namespace connectivity::firebird - -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_TABLES_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/User.cxx b/connectivity/source/drivers/firebird/User.cxx index 3a9682fb8264..9f647713a663 100644 --- a/connectivity/source/drivers/firebird/User.cxx +++ b/connectivity/source/drivers/firebird/User.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -49,3 +49,5 @@ void User::refreshGroups() { // TODO: implement. } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/User.hxx b/connectivity/source/drivers/firebird/User.hxx index 16fa138976b9..e47565f5d52e 100644 --- a/connectivity/source/drivers/firebird/User.hxx +++ b/connectivity/source/drivers/firebird/User.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -7,8 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_USER_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_USER_HXX +#pragma once #include <sdbcx/VUser.hxx> #include <com/sun/star/sdbc/XConnection.hpp> @@ -44,7 +43,4 @@ namespace connectivity::firebird } // namespace connectivity::firebird - -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_USER_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Users.cxx b/connectivity/source/drivers/firebird/Users.cxx index fc8914250ee6..10912d6be0ab 100644 --- a/connectivity/source/drivers/firebird/Users.cxx +++ b/connectivity/source/drivers/firebird/Users.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -17,8 +17,6 @@ using namespace ::cppu; using namespace ::osl; using namespace ::com::sun::star; using namespace ::com::sun::star::beans; -using namespace ::com::sun::star::container; -using namespace ::com::sun::star::lang; using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::uno; @@ -75,4 +73,4 @@ void Users::dropObject(sal_Int32 nPosition, const OUString&) } } -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Users.hxx b/connectivity/source/drivers/firebird/Users.hxx index 6a6be1ead6a6..7e78444d1199 100644 --- a/connectivity/source/drivers/firebird/Users.hxx +++ b/connectivity/source/drivers/firebird/Users.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -7,8 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_USERS_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_USERS_HXX +#pragma once #include <connectivity/sdbcx/VCollection.hxx> #include <com/sun/star/sdbc/XDatabaseMetaData.hpp> @@ -51,7 +50,4 @@ namespace connectivity::firebird } // namespace connectivity::firebird - -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_USERS_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Util.cxx b/connectivity/source/drivers/firebird/Util.cxx index 82d69a123c97..3cee5dab6e0b 100644 --- a/connectivity/source/drivers/firebird/Util.cxx +++ b/connectivity/source/drivers/firebird/Util.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -13,6 +13,7 @@ #include <com/sun/star/sdbc/DataType.hpp> #include <com/sun/star/sdbc/SQLException.hpp> +#include <o3tl/string_view.hxx> using namespace ::connectivity; @@ -22,16 +23,16 @@ using namespace ::com::sun::star::uno; using namespace firebird; -OUString firebird::sanitizeIdentifier(const OUString& rIdentifier) +OUString firebird::sanitizeIdentifier(std::u16string_view rIdentifier) { - OUString sRet = rIdentifier.trim(); - assert(sRet.getLength() <= 31); // Firebird identifiers cannot be longer than this. + std::u16string_view sRet = o3tl::trim(rIdentifier); + assert(sRet.size() <= 31); // Firebird identifiers cannot be longer than this. - return sRet; + return OUString(sRet); } OUString firebird::StatusVectorToString(const ISC_STATUS_ARRAY& rStatusVector, - const OUString& rCause) + std::u16string_view rCause) { OUStringBuffer buf; const ISC_STATUS* pStatus = reinterpret_cast<const ISC_STATUS*>(&rStatusVector); @@ -43,15 +44,15 @@ OUString firebird::StatusVectorToString(const ISC_STATUS_ARRAY& rStatusVector, while(fb_interpret(msg, sizeof(msg), &pStatus)) { // TODO: verify encoding - buf.append("\n*"); - buf.append(OUString(msg, strlen(msg), RTL_TEXTENCODING_UTF8)); + buf.append("\n*" + + OUString(msg, strlen(msg), RTL_TEXTENCODING_UTF8)); } } catch (...) { SAL_WARN("connectivity.firebird", "ignore fb_interpret exception"); } - buf.append("\ncaused by\n'").append(rCause).append("'\n"); + buf.append(OUString::Concat("\ncaused by\n'") + rCause + "'\n"); OUString error = buf.makeStringAndClear(); SAL_WARN("connectivity.firebird", error); @@ -59,7 +60,7 @@ OUString firebird::StatusVectorToString(const ISC_STATUS_ARRAY& rStatusVector, } void firebird::evaluateStatusVector(const ISC_STATUS_ARRAY& rStatusVector, - const OUString& rCause, + std::u16string_view rCause, const uno::Reference< XInterface >& _rxContext) { if (IndicatesError(rStatusVector)) @@ -342,8 +343,9 @@ void firebird::mallocSQLVAR(XSQLDA* pSqlda) case SQL_BOOLEAN: pVar->sqldata = static_cast<char *>(malloc(sizeof(sal_Bool))); break; + // See https://www.firebirdsql.org/file/documentation/html/en/refdocs/fblangref25/firebird-25-language-reference.html#fblangref25-datatypes-special-sqlnull case SQL_NULL: - assert(false); // TODO: implement + pVar->sqldata = nullptr; break; case SQL_QUAD: assert(false); // TODO: implement @@ -388,7 +390,8 @@ void firebird::freeSQLVAR(XSQLDA* pSqlda) } break; case SQL_NULL: - assert(false); // TODO: implement + // See SQL_NULL case in mallocSQLVAR + assert(pVar->sqldata == nullptr); break; case SQL_QUAD: assert(false); // TODO: implement @@ -408,22 +411,6 @@ void firebird::freeSQLVAR(XSQLDA* pSqlda) } -OUString firebird::escapeWith( const OUString& sText, const char aKey, const char aEscapeChar) -{ - OUString sRet(sText); - sal_Int32 aIndex = 0; - for (;;) - { - aIndex = sRet.indexOf(aKey, aIndex); - if ( aIndex <= 0 || aIndex >= sRet.getLength()) - break; - sRet = sRet.replaceAt(aIndex, 1, OUStringChar(aEscapeChar) + OUStringChar(aKey) ); - aIndex += 2; - } - - return sRet; -} - sal_Int64 firebird::pow10Integer(int nDecimalCount) { sal_Int64 nRet = 1; @@ -433,4 +420,5 @@ sal_Int64 firebird::pow10Integer(int nDecimalCount) } return nRet; } -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Util.hxx b/connectivity/source/drivers/firebird/Util.hxx index efb222f3ff22..db407ef98b38 100644 --- a/connectivity/source/drivers/firebird/Util.hxx +++ b/connectivity/source/drivers/firebird/Util.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -7,14 +7,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_UTIL_HXX -#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_UTIL_HXX +#pragma once #include <ibase.h> #include <rtl/ustring.hxx> #include <com/sun/star/uno/XInterface.hpp> +#include <utility> namespace connectivity::firebird { @@ -58,16 +58,16 @@ public: * */ explicit ColumnTypeInfo( short aType, short aSubType = 0, - short nScale = 0, const OUString& sCharset = OUString() ) + short nScale = 0, OUString sCharset = OUString() ) : m_aType(aType) , m_aSubType(aSubType) , m_nScale(nScale) - , m_sCharsetName(sCharset) {} - explicit ColumnTypeInfo( short aType, const OUString& sCharset ) + , m_sCharsetName(std::move(sCharset)) {} + explicit ColumnTypeInfo( short aType, OUString sCharset ) : m_aType(aType) , m_aSubType(0) , m_nScale(0) - , m_sCharsetName(sCharset) {} + , m_sCharsetName(std::move(sCharset)) {} short getType() const { return m_aType; } short getSubType() const { return m_aSubType; } short getScale() const { return m_nScale; } @@ -87,7 +87,7 @@ public: * for such shorter strings, however any trailing padding makes the gui * editing of such names harder, hence we remove all trailing whitespace. */ - OUString sanitizeIdentifier(const OUString& rIdentifier); + OUString sanitizeIdentifier(std::u16string_view rIdentifier); inline bool IndicatesError(const ISC_STATUS_ARRAY& rStatusVector) { @@ -95,7 +95,7 @@ public: } OUString StatusVectorToString(const ISC_STATUS_ARRAY& rStatusVector, - const OUString& rCause); + std::u16string_view rCause); /** * Evaluate a firebird status vector and throw exceptions as necessary. @@ -104,7 +104,7 @@ public: * @throws css::sdbc::SQLException */ void evaluateStatusVector(const ISC_STATUS_ARRAY& rStatusVector, - const OUString& aCause, + std::u16string_view aCause, const css::uno::Reference< css::uno::XInterface >& _rxContext); /** @@ -119,10 +119,8 @@ public: void freeSQLVAR(XSQLDA* pSqlda); - OUString escapeWith( const OUString& sText, const char aKey, const char aEscapeChar); sal_Int64 pow10Integer( int nDecimalCount ); } -#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_UTIL_HXX -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/View.cxx b/connectivity/source/drivers/firebird/View.cxx new file mode 100644 index 000000000000..6dcbf6bce2b2 --- /dev/null +++ b/connectivity/source/drivers/firebird/View.cxx @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include "View.hxx" + +#include <propertyids.hxx> + +#include <com/sun/star/sdbc/XRow.hpp> + +namespace connectivity::firebird +{ +View::View(const css::uno::Reference<css::sdbc::XConnection>& _rxConnection, bool _bCaseSensitive, + const OUString& _rSchemaName, const OUString& _rName) + : View_Base(_bCaseSensitive, _rName, _rxConnection->getMetaData(), OUString(), _rSchemaName, + OUString()) + , m_xConnection(_rxConnection) +{ +} + +View::~View() {} + +void SAL_CALL View::acquire() noexcept { View_Base::acquire(); }; +void SAL_CALL View::release() noexcept { View_Base::release(); }; +css::uno::Any SAL_CALL View::queryInterface(const css::uno::Type& _rType) +{ + css::uno::Any aReturn = View_Base::queryInterface(_rType); + if (!aReturn.hasValue()) + aReturn = View_IBASE::queryInterface(_rType); + return aReturn; +} + +css::uno::Sequence<css::uno::Type> SAL_CALL View::getTypes() +{ + return ::comphelper::concatSequences(View_Base::getTypes(), View_IBASE::getTypes()); +} + +css::uno::Sequence<sal_Int8> SAL_CALL View::getImplementationId() +{ + return css::uno::Sequence<sal_Int8>(); +} + +void SAL_CALL View::alterCommand(const OUString& _rNewCommand) +{ + OUString aCommand = "ALTER VIEW \"" + m_Name + "\" AS " + _rNewCommand; + m_xMetaData->getConnection()->createStatement()->execute(aCommand); +} + +void SAL_CALL View::getFastPropertyValue(css::uno::Any& _rValue, sal_Int32 _nHandle) const +{ + if (_nHandle == PROPERTY_ID_COMMAND) + { + // retrieve the very current command, don't rely on the base classes cached value + // (which we initialized empty, anyway) + _rValue <<= impl_getCommand(); + return; + } + + View_Base::getFastPropertyValue(_rValue, _nHandle); +} + +OUString View::impl_getCommand() const +{ + OUString aCommand("SELECT RDB$VIEW_SOURCE FROM RDB$RELATIONS WHERE RDB$RELATION_NAME = '" + + m_Name + "'"); + css::uno::Reference<css::sdbc::XStatement> statement = m_xConnection->createStatement(); + css::uno::Reference<css::sdbc::XResultSet> xResult = statement->executeQuery(aCommand); + + css::uno::Reference<css::sdbc::XRow> xRow(xResult, css::uno::UNO_QUERY_THROW); + if (!xResult->next()) + { + // hmm. There is no view the name as we know it. Can only mean some other instance + // dropped this view meanwhile... + std::abort(); + } + + return xRow->getString(1); +} + +} // namespace connectivity::firebird +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/View.hxx b/connectivity/source/drivers/firebird/View.hxx new file mode 100644 index 000000000000..2b300a8d06d9 --- /dev/null +++ b/connectivity/source/drivers/firebird/View.hxx @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include <connectivity/sdbcx/VView.hxx> + +#include <com/sun/star/sdbcx/XAlterView.hpp> +#include <com/sun/star/sdbc/XConnection.hpp> + +#include <comphelper/sequence.hxx> +#include <cppuhelper/implbase1.hxx> + +namespace connectivity::firebird +{ +typedef ::connectivity::sdbcx::OView View_Base; +typedef ::cppu::ImplHelper1<css::sdbcx::XAlterView> View_IBASE; + +class View : public View_Base, public View_IBASE +{ +public: + View(const css::uno::Reference<css::sdbc::XConnection>& _rxConnection, bool _bCaseSensitive, + const OUString& _rSchemaName, const OUString& _rName); + + // UNO + virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type& aType) override; + virtual void SAL_CALL acquire() noexcept override; + virtual void SAL_CALL release() noexcept override; + + virtual css::uno::Sequence<css::uno::Type> SAL_CALL getTypes() override; + virtual css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() override; + + // XAlterView + virtual void SAL_CALL alterCommand(const OUString& NewCommand) override; + +protected: + virtual ~View() override; + +protected: + // OPropertyContainer + virtual void SAL_CALL getFastPropertyValue(css::uno::Any& _rValue, + sal_Int32 _nHandle) const override; + +private: + /** retrieves the current command of the View */ + OUString impl_getCommand() const; + +private: + css::uno::Reference<css::sdbc::XConnection> m_xConnection; + + using View_Base::getFastPropertyValue; +}; + +} // namespace connectivity::firebird +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Views.cxx b/connectivity/source/drivers/firebird/Views.cxx new file mode 100644 index 000000000000..2e5bec42adc3 --- /dev/null +++ b/connectivity/source/drivers/firebird/Views.cxx @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include "Tables.hxx" +#include "Views.hxx" +#include "View.hxx" +#include "Catalog.hxx" +#include <connectivity/dbtools.hxx> +#include <comphelper/types.hxx> +#include <TConnection.hxx> + +connectivity::firebird::Views::Views( + const css::uno::Reference<css::sdbc::XConnection>& _rxConnection, ::cppu::OWeakObject& _rParent, + ::osl::Mutex& _rMutex, const ::std::vector<OUString>& _rVector) + : sdbcx::OCollection(_rParent, true, _rMutex, _rVector) + , m_xConnection(_rxConnection) + , m_xMetaData(_rxConnection->getMetaData()) + , m_bInDrop(false) +{ +} + +connectivity::sdbcx::ObjectType connectivity::firebird::Views::createObject(const OUString& _rName) +{ + OUString sCatalog, sSchema, sTable; + ::dbtools::qualifiedNameComponents(m_xMetaData, _rName, sCatalog, sSchema, sTable, + ::dbtools::EComposeRule::InDataManipulation); + return new View(m_xConnection, isCaseSensitive(), sSchema, sTable); +} + +void connectivity::firebird::Views::impl_refresh() +{ + static_cast<Catalog&>(m_rParent).refreshViews(); +} + +css::uno::Reference<css::beans::XPropertySet> connectivity::firebird::Views::createDescriptor() +{ + return new connectivity::sdbcx::OView(true, m_xMetaData); +} + +// XAppend +connectivity::sdbcx::ObjectType connectivity::firebird::Views::appendObject( + const OUString& _rForName, const css::uno::Reference<css::beans::XPropertySet>& descriptor) +{ + createView(descriptor); + return createObject(_rForName); +} + +// XDrop +void connectivity::firebird::Views::dropObject(sal_Int32 _nPos, const OUString& /*_sElementName*/) +{ + if (m_bInDrop) + return; + + css::uno::Reference<XInterface> xObject(getObject(_nPos)); + bool bIsNew = connectivity::sdbcx::ODescriptor::isNew(xObject); + if (!bIsNew) + { + OUString aSql("DROP VIEW"); + + css::uno::Reference<css::beans::XPropertySet> xProp(xObject, css::uno::UNO_QUERY); + aSql += ::dbtools::composeTableName(m_xMetaData, xProp, + ::dbtools::EComposeRule::InTableDefinitions, true); + + css::uno::Reference<css::sdbc::XConnection> xConnection = m_xMetaData->getConnection(); + css::uno::Reference<css::sdbc::XStatement> xStmt = xConnection->createStatement(); + xStmt->execute(aSql); + ::comphelper::disposeComponent(xStmt); + } +} + +void connectivity::firebird::Views::dropByNameImpl(const OUString& elementName) +{ + m_bInDrop = true; + connectivity::sdbcx::OCollection::dropByName(elementName); + m_bInDrop = false; +} + +void connectivity::firebird::Views::createView( + const css::uno::Reference<css::beans::XPropertySet>& descriptor) +{ + css::uno::Reference<css::sdbc::XConnection> xConnection = m_xMetaData->getConnection(); + + OUString sCommand; + descriptor->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_COMMAND)) + >>= sCommand; + + OUString aSql = "CREATE VIEW " + + ::dbtools::composeTableName(m_xMetaData, descriptor, + ::dbtools::EComposeRule::InTableDefinitions, true) + + " AS " + sCommand; + + css::uno::Reference<css::sdbc::XStatement> xStmt = xConnection->createStatement(); + if (xStmt.is()) + { + xStmt->execute(aSql); + ::comphelper::disposeComponent(xStmt); + } + connectivity::firebird::Tables* pTables = static_cast<connectivity::firebird::Tables*>( + static_cast<connectivity::firebird::Catalog&>(m_rParent).getPrivateTables()); + if (pTables) + { + OUString sName = ::dbtools::composeTableName( + m_xMetaData, descriptor, ::dbtools::EComposeRule::InDataManipulation, false); + pTables->appendNew(sName); + } +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/connectivity/source/drivers/firebird/Views.hxx b/connectivity/source/drivers/firebird/Views.hxx new file mode 100644 index 000000000000..6887bdc66ed0 --- /dev/null +++ b/connectivity/source/drivers/firebird/Views.hxx @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include <connectivity/sdbcx/VCollection.hxx> +#include <com/sun/star/sdbc/XDatabaseMetaData.hpp> +namespace connectivity::firebird +{ +class Views final : public connectivity::sdbcx::OCollection +{ + css::uno::Reference<css::sdbc::XConnection> m_xConnection; + css::uno::Reference<css::sdbc::XDatabaseMetaData> m_xMetaData; + bool m_bInDrop; + + // OCollection + virtual connectivity::sdbcx::ObjectType createObject(const OUString& _rName) override; + virtual void impl_refresh() override; + virtual css::uno::Reference<css::beans::XPropertySet> createDescriptor() override; + virtual sdbcx::ObjectType + appendObject(const OUString& _rForName, + const css::uno::Reference<css::beans::XPropertySet>& descriptor) override; + + void createView(const css::uno::Reference<css::beans::XPropertySet>& descriptor); + +public: + Views(const css::uno::Reference<css::sdbc::XConnection>& _rxConnection, + ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex, + const ::std::vector<OUString>& _rVector); + + // XDrop + virtual void dropObject(sal_Int32 _nPos, const OUString& _sElementName) override; + + void dropByNameImpl(const OUString& elementName); +}; +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |