diff options
Diffstat (limited to 'connectivity/source/drivers/ado')
30 files changed, 11805 insertions, 0 deletions
diff --git a/connectivity/source/drivers/ado/ACallableStatement.cxx b/connectivity/source/drivers/ado/ACallableStatement.cxx new file mode 100644 index 000000000..94ad744d0 --- /dev/null +++ b/connectivity/source/drivers/ado/ACallableStatement.cxx @@ -0,0 +1,253 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/ACallableStatement.hxx> +#include <connectivity/dbexception.hxx> +#include <cppuhelper/queryinterface.hxx> + +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::container; + +IMPLEMENT_SERVICE_INFO(OCallableStatement,"com.sun.star.sdbcx.ACallableStatement","com.sun.star.sdbc.CallableStatement"); + +//************ Class: java.sql.CallableStatement + +OCallableStatement::OCallableStatement( OConnection* _pConnection, const OUString& sql ) + : OPreparedStatement( _pConnection, sql ) +{ + m_Command.put_CommandType(adCmdStoredProc); +} + + +Any SAL_CALL OCallableStatement::queryInterface( const Type & rType ) +{ + Any aRet = OPreparedStatement::queryInterface(rType); + return aRet.hasValue() ? aRet : ::cppu::queryInterface(rType,static_cast< XRow*>(this)); +} + + +sal_Bool SAL_CALL OCallableStatement::wasNull( ) +{ + return m_aValue.isNull(); +} + + +sal_Bool SAL_CALL OCallableStatement::getBoolean( sal_Int32 columnIndex ) +{ + ADOParameter* pParam = nullptr; + m_pParameters->get_Item(OLEVariant(sal_Int32(columnIndex-1)),&pParam); + if(pParam) + pParam->get_Value(&m_aValue); + return m_aValue.getBool(); +} + +sal_Int8 SAL_CALL OCallableStatement::getByte( sal_Int32 columnIndex ) +{ + ADOParameter* pParam = nullptr; + m_pParameters->get_Item(OLEVariant(sal_Int32(columnIndex-1)),&pParam); + if(pParam) + pParam->get_Value(&m_aValue); + return m_aValue.getInt8(); +} + +Sequence< sal_Int8 > SAL_CALL OCallableStatement::getBytes( sal_Int32 columnIndex ) +{ + ADOParameter* pParam = nullptr; + m_pParameters->get_Item(OLEVariant(sal_Int32(columnIndex-1)),&pParam); + if(pParam) + pParam->get_Value(&m_aValue); + return m_aValue.getByteSequence(); +} + +css::util::Date SAL_CALL OCallableStatement::getDate( sal_Int32 columnIndex ) +{ + ADOParameter* pParam = nullptr; + m_pParameters->get_Item(OLEVariant(sal_Int32(columnIndex-1)),&pParam); + if(pParam) + pParam->get_Value(&m_aValue); + return m_aValue.getDate(); +} + +double SAL_CALL OCallableStatement::getDouble( sal_Int32 columnIndex ) +{ + ADOParameter* pParam = nullptr; + m_pParameters->get_Item(OLEVariant(sal_Int32(columnIndex-1)),&pParam); + if(pParam) + pParam->get_Value(&m_aValue); + return m_aValue.getDouble(); +} + + +float SAL_CALL OCallableStatement::getFloat( sal_Int32 columnIndex ) +{ + ADOParameter* pParam = nullptr; + m_pParameters->get_Item(OLEVariant(sal_Int32(columnIndex-1)),&pParam); + if(pParam) + pParam->get_Value(&m_aValue); + return m_aValue.getFloat(); +} + + +sal_Int32 SAL_CALL OCallableStatement::getInt( sal_Int32 columnIndex ) +{ + ADOParameter* pParam = nullptr; + m_pParameters->get_Item(OLEVariant(sal_Int32(columnIndex-1)),&pParam); + if(pParam) + pParam->get_Value(&m_aValue); + return m_aValue.getInt32(); +} + + +sal_Int64 SAL_CALL OCallableStatement::getLong( sal_Int32 columnIndex ) +{ + ADOParameter* pParam = nullptr; + m_pParameters->get_Item(OLEVariant(sal_Int32(columnIndex-1)),&pParam); + if(pParam) + pParam->get_Value(&m_aValue); + return static_cast<sal_Int64>(m_aValue.getCurrency().int64); +} + + +Any SAL_CALL OCallableStatement::getObject( sal_Int32 /*columnIndex*/, const Reference< css::container::XNameAccess >& /*typeMap*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getObject", *this ); + return Any(); +} + + +sal_Int16 SAL_CALL OCallableStatement::getShort( sal_Int32 columnIndex ) +{ + ADOParameter* pParam = nullptr; + m_pParameters->get_Item(OLEVariant(sal_Int32(columnIndex-1)),&pParam); + if(pParam) + pParam->get_Value(&m_aValue); + return m_aValue.getInt16(); +} + + +OUString SAL_CALL OCallableStatement::getString( sal_Int32 columnIndex ) +{ + ADOParameter* pParam = nullptr; + m_pParameters->get_Item(OLEVariant(sal_Int32(columnIndex-1)),&pParam); + if(pParam) + pParam->get_Value(&m_aValue); + return m_aValue.getString(); +} + + + css::util::Time SAL_CALL OCallableStatement::getTime( sal_Int32 columnIndex ) +{ + ADOParameter* pParam = nullptr; + m_pParameters->get_Item(OLEVariant(sal_Int32(columnIndex-1)),&pParam); + if(pParam) + pParam->get_Value(&m_aValue); + return m_aValue.getTime(); +} + + + css::util::DateTime SAL_CALL OCallableStatement::getTimestamp( sal_Int32 columnIndex ) +{ + ADOParameter* pParam = nullptr; + m_pParameters->get_Item(OLEVariant(sal_Int32(columnIndex-1)),&pParam); + if(pParam) + pParam->get_Value(&m_aValue); + return m_aValue.getDateTime(); +} + + +void SAL_CALL OCallableStatement::registerOutParameter( sal_Int32 parameterIndex, sal_Int32 sqlType, const OUString& /*typeName*/ ) +{ + ADOParameter* pParam = nullptr; + m_pParameters->get_Item(OLEVariant(sal_Int32(parameterIndex-1)),&pParam); + if(pParam) + { + pParam->put_Type(ADOS::MapJdbc2ADOType(sqlType,m_pConnection->getEngineType())); + pParam->put_Direction(adParamOutput); + } +} + +void SAL_CALL OCallableStatement::registerNumericOutParameter( sal_Int32 parameterIndex, sal_Int32 sqlType, sal_Int32 scale ) +{ + ADOParameter* pParam = nullptr; + m_pParameters->get_Item(OLEVariant(sal_Int32(parameterIndex-1)),&pParam); + if(pParam) + { + pParam->put_Type(ADOS::MapJdbc2ADOType(sqlType,m_pConnection->getEngineType())); + pParam->put_Direction(adParamOutput); + pParam->put_NumericScale(static_cast<sal_Int8>(scale)); + } +} + + +Reference< css::io::XInputStream > SAL_CALL OCallableStatement::getBinaryStream( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getBinaryStream", *this ); + return nullptr; +} + +Reference< css::io::XInputStream > SAL_CALL OCallableStatement::getCharacterStream( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getCharacterStream", *this ); + return nullptr; +} + + +Reference< XArray > SAL_CALL OCallableStatement::getArray( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getArray", *this ); + return nullptr; +} + + +Reference< XClob > SAL_CALL OCallableStatement::getClob( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getClob", *this ); + return nullptr; +} + +Reference< XBlob > SAL_CALL OCallableStatement::getBlob( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getBlob", *this ); + return nullptr; +} + + +Reference< XRef > SAL_CALL OCallableStatement::getRef( sal_Int32 /*columnIndex*/) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getRef", *this ); + return nullptr; +} + + +void SAL_CALL OCallableStatement::acquire() noexcept +{ + OPreparedStatement::acquire(); +} + +void SAL_CALL OCallableStatement::release() noexcept +{ + OPreparedStatement::release(); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/ACatalog.cxx b/connectivity/source/drivers/ado/ACatalog.cxx new file mode 100644 index 000000000..efab28344 --- /dev/null +++ b/connectivity/source/drivers/ado/ACatalog.cxx @@ -0,0 +1,115 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/ACatalog.hxx> +#include <ado/AConnection.hxx> +#include <ado/AGroups.hxx> +#include <ado/AUsers.hxx> +#include <ado/ATables.hxx> +#include <ado/AViews.hxx> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> + + +using namespace connectivity; +using namespace connectivity::ado; + +OCatalog::OCatalog(_ADOCatalog* _pCatalog,OConnection* _pCon) : connectivity::sdbcx::OCatalog(_pCon) + ,m_aCatalog(_pCatalog) + ,m_pConnection(_pCon) +{ +} + +OCatalog::~OCatalog() +{ + if(m_aCatalog.IsValid()) + m_aCatalog.putref_ActiveConnection(nullptr); + m_aCatalog.clear(); +} + +void OCatalog::refreshTables() +{ + ::std::vector< OUString> aVector; + + WpADOTables aTables(m_aCatalog.get_Tables()); + if ( aTables.IsValid() ) + { + aTables.Refresh(); + sal_Int32 nCount = aTables.GetItemCount(); + aVector.reserve(nCount); + for(sal_Int32 i=0;i< nCount;++i) + { + WpADOTable aElement = aTables.GetItem(i); + if ( aElement.IsValid() ) + { + OUString sTypeName = aElement.get_Type(); + if ( !sTypeName.equalsIgnoreAsciiCase("SYSTEM TABLE") + && !sTypeName.equalsIgnoreAsciiCase("ACCESS TABLE") ) + aVector.push_back(aElement.get_Name()); + } + } + } + + if(m_pTables) + m_pTables->reFill(aVector); + else + m_pTables.reset( new OTables(this,m_aMutex,aVector,aTables,m_pConnection->getMetaData()->supportsMixedCaseQuotedIdentifiers()) ); +} + +void OCatalog::refreshViews() +{ + ::std::vector< OUString> aVector; + + WpADOViews aViews = m_aCatalog.get_Views(); + aViews.fillElementNames(aVector); + + if(m_pViews) + m_pViews->reFill(aVector); + else + m_pViews.reset( new OViews(this,m_aMutex,aVector,aViews,m_pConnection->getMetaData()->supportsMixedCaseQuotedIdentifiers()) ); +} + +void OCatalog::refreshGroups() +{ + ::std::vector< OUString> aVector; + + WpADOGroups aGroups = m_aCatalog.get_Groups(); + aGroups.fillElementNames(aVector); + + if(m_pGroups) + m_pGroups->reFill(aVector); + else + m_pGroups.reset( new OGroups(this,m_aMutex,aVector,aGroups,m_pConnection->getMetaData()->supportsMixedCaseQuotedIdentifiers()) ); +} + +void OCatalog::refreshUsers() +{ + ::std::vector< OUString> aVector; + + WpADOUsers aUsers = m_aCatalog.get_Users(); + aUsers.fillElementNames(aVector); + + if(m_pUsers) + m_pUsers->reFill(aVector); + else + m_pUsers.reset( new OUsers(this,m_aMutex,aVector,aUsers,m_pConnection->getMetaData()->supportsMixedCaseQuotedIdentifiers()) ); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AColumn.cxx b/connectivity/source/drivers/ado/AColumn.cxx new file mode 100644 index 000000000..a521586b9 --- /dev/null +++ b/connectivity/source/drivers/ado/AColumn.cxx @@ -0,0 +1,248 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <string_view> + +#include <ado/AColumn.hxx> +#include <ado/AConnection.hxx> +#include <ado/Awrapado.hxx> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <comphelper/extract.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/types.hxx> +#include <ado/ACatalog.hxx> + +using namespace ::comphelper; + +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; + +void WpADOColumn::Create() +{ + pInterface.CoCreateInstance(ADOS::CLSID_ADOCOLUMN_25, nullptr, CLSCTX_INPROC_SERVER); +} + +OAdoColumn::OAdoColumn(bool _bCase,OConnection* _pConnection,_ADOColumn* _pColumn) + : connectivity::sdbcx::OColumn(_bCase) + ,m_pConnection(_pConnection) +{ + construct(); + OSL_ENSURE(_pColumn,"Column can not be null!"); + m_aColumn.set(_pColumn); + // m_aColumn.put_ParentCatalog(_pConnection->getAdoCatalog()->getCatalog()); + fillPropertyValues(); +} + +OAdoColumn::OAdoColumn(bool _bCase,OConnection* _pConnection) + : connectivity::sdbcx::OColumn(_bCase) + ,m_pConnection(_pConnection) +{ + m_aColumn.Create(); + m_aColumn.put_ParentCatalog(_pConnection->getAdoCatalog()->getCatalog()); + construct(); + fillPropertyValues(); + m_Type = DataType::OTHER; +} + + +Sequence< sal_Int8 > OAdoColumn::getUnoTunnelId() +{ + static const comphelper::UnoIdInit implId; + return implId.getSeq(); +} + +// css::lang::XUnoTunnel + +sal_Int64 OAdoColumn::getSomething( const Sequence< sal_Int8 > & rId ) +{ + return comphelper::getSomethingImpl(rId, this, + comphelper::FallbackToGetSomethingOf<OColumn_ADO>{}); +} + +void OAdoColumn::construct() +{ + sal_Int32 nAttrib = isNew() ? 0 : PropertyAttribute::READONLY; + + registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISASCENDING), PROPERTY_ID_ISASCENDING, nAttrib,&m_IsAscending, cppu::UnoType<bool>::get()); + registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RELATEDCOLUMN), PROPERTY_ID_RELATEDCOLUMN, nAttrib,&m_ReferencedColumn, ::cppu::UnoType<OUString>::get()); +} + +void OAdoColumn::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) +{ + if(m_aColumn.IsValid()) + { + std::u16string_view sAdoPropertyName; + + switch(nHandle) + { + case PROPERTY_ID_ISASCENDING: + m_aColumn.put_SortOrder(::cppu::any2bool(rValue) ? adSortAscending : adSortDescending); + break; + case PROPERTY_ID_RELATEDCOLUMN: + { + OUString aVal; + rValue >>= aVal; + m_aColumn.put_RelatedColumn(aVal); + } + break; + case PROPERTY_ID_NAME: + { + OUString aVal; + rValue >>= aVal; + m_aColumn.put_Name(aVal); + } + break; + case PROPERTY_ID_TYPE: + { + sal_Int32 nVal=0; + rValue >>= nVal; + m_aColumn.put_Type(ADOS::MapJdbc2ADOType(nVal,m_pConnection->getEngineType())); + } + break; + case PROPERTY_ID_TYPENAME: + // rValue <<= m_pTable->getCatalog()->getConnection()->getTypeInfo()->find(); + break; + case PROPERTY_ID_PRECISION: + { + sal_Int32 nVal=0; + rValue >>= nVal; + m_aColumn.put_Precision(nVal); + } + break; + case PROPERTY_ID_SCALE: + { + sal_Int32 nVal=0; + rValue >>= nVal; + if ( !m_IsCurrency ) + m_aColumn.put_NumericScale(static_cast<sal_Int8>(nVal)); + } + break; + case PROPERTY_ID_ISNULLABLE: + { + sal_Int32 nVal=0; + rValue >>= nVal; + if ( nVal == ColumnValue::NULLABLE ) + m_aColumn.put_Attributes( adColNullable ); + } + break; + case PROPERTY_ID_ISROWVERSION: + break; + + case PROPERTY_ID_ISAUTOINCREMENT: + OTools::putValue( + m_aColumn.get_Properties(), std::u16string_view(u"Autoincrement"), + getBOOL(rValue)); + break; + + case PROPERTY_ID_IM001: + case PROPERTY_ID_DESCRIPTION: + sAdoPropertyName = u"Description"; + break; + + case PROPERTY_ID_DEFAULTVALUE: + sAdoPropertyName = u"Default"; + break; + } + + if (!sAdoPropertyName.empty()) + OTools::putValue(m_aColumn.get_Properties(), sAdoPropertyName, getString(rValue)); + } + OColumn_ADO::setFastPropertyValue_NoBroadcast(nHandle,rValue); +} + +void OAdoColumn::fillPropertyValues() +{ + if(m_aColumn.IsValid()) + { + m_IsAscending = m_aColumn.get_SortOrder() == adSortAscending; + m_ReferencedColumn = m_aColumn.get_RelatedColumn(); + m_Name = m_aColumn.get_Name(); + m_Precision = m_aColumn.get_Precision(); + m_Scale = m_aColumn.get_NumericScale(); + m_IsNullable = ((m_aColumn.get_Attributes() & adColNullable) == adColNullable) ? ColumnValue::NULLABLE : ColumnValue::NO_NULLS; + + DataTypeEnum eType = m_aColumn.get_Type(); + m_IsCurrency = (eType == adCurrency); + if ( m_IsCurrency && !m_Scale) + m_Scale = 4; + m_Type = ADOS::MapADOType2Jdbc(eType); + + bool bForceTo = true; + const OTypeInfoMap* pTypeInfoMap = m_pConnection->getTypeInfo(); + const OExtendedTypeInfo* pTypeInfo = OConnection::getTypeInfoFromType(*m_pConnection->getTypeInfo(),eType,OUString(),m_Precision,m_Scale,bForceTo); + if ( pTypeInfo ) + m_TypeName = pTypeInfo->aSimpleType.aTypeName; + else if ( eType == adVarBinary && ADOS::isJetEngine(m_pConnection->getEngineType()) ) + { + ::comphelper::UStringMixEqual aCase(false); + OTypeInfoMap::const_iterator aFind = std::find_if(pTypeInfoMap->begin(), pTypeInfoMap->end(), + [&aCase] (const OTypeInfoMap::value_type& typeInfo) { + return aCase(typeInfo.second->getDBName(), u"VarBinary"); + }); + + if ( aFind != pTypeInfoMap->end() ) // change column type if necessary + { + eType = aFind->first; + pTypeInfo = aFind->second; + } + + if ( !pTypeInfo ) + { + pTypeInfo = OConnection::getTypeInfoFromType(*m_pConnection->getTypeInfo(),adBinary,OUString(),m_Precision,m_Scale,bForceTo); + eType = adBinary; + } + + if ( pTypeInfo ) + { + m_TypeName = pTypeInfo->aSimpleType.aTypeName; + m_Type = ADOS::MapADOType2Jdbc(eType); + } + } + + + // fill some specific props + { + WpADOProperties aProps( m_aColumn.get_Properties() ); + + if ( aProps.IsValid() ) + { + m_IsAutoIncrement + = OTools::getValue(aProps, std::u16string_view(u"Autoincrement")).getBool(); + + m_Description + = OTools::getValue(aProps, std::u16string_view(u"Description")).getString(); + + m_DefaultValue + = OTools::getValue(aProps, std::u16string_view(u"Default")).getString(); + } + } + } +} + +WpADOColumn OAdoColumn::getColumnImpl() const +{ + return m_aColumn; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AColumns.cxx b/connectivity/source/drivers/ado/AColumns.cxx new file mode 100644 index 000000000..229903502 --- /dev/null +++ b/connectivity/source/drivers/ado/AColumns.cxx @@ -0,0 +1,125 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/AColumns.hxx> +#include <ado/AColumn.hxx> +#include <ado/AConnection.hxx> +#include <ado/Awrapado.hxx> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <comphelper/property.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/types.hxx> +#include <connectivity/dbexception.hxx> +#include <rtl/ref.hxx> +#include <algorithm> +#include <string_view> +#include <strings.hrc> + +using namespace connectivity::ado; +using namespace connectivity; +using namespace comphelper; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::container; + +sdbcx::ObjectType OColumns::createObject(const OUString& _rName) +{ + return new OAdoColumn(isCaseSensitive(),m_pConnection,m_aCollection.GetItem(_rName)); +} + + +void OColumns::impl_refresh() +{ + m_aCollection.Refresh(); +} + +Reference< XPropertySet > OColumns::createDescriptor() +{ + return new OAdoColumn(isCaseSensitive(),m_pConnection); +} + +// XAppend +sdbcx::ObjectType OColumns::appendObject( const OUString&, const Reference< XPropertySet >& descriptor ) +{ + rtl::Reference<OAdoColumn> pColumn = getFromUnoTunnel<OAdoColumn>( descriptor ); + Reference< XPropertySet > xColumn; + if ( !pColumn.is() ) + { + // m_pConnection->throwGenericSQLException( STR_INVALID_COLUMN_DESCRIPTOR_ERROR,static_cast<XTypeProvider*>(this) ); + pColumn = new OAdoColumn(isCaseSensitive(),m_pConnection); + xColumn = pColumn; + ::comphelper::copyProperties(descriptor,xColumn); + } + + WpADOColumn aColumn = pColumn->getColumnImpl(); + + OUString sTypeName; + pColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME)) >>= sTypeName; + + const OTypeInfoMap* pTypeInfoMap = m_pConnection->getTypeInfo(); + ::comphelper::UStringMixEqual aCase(false); + // search for typeinfo where the typename is equal sTypeName + OTypeInfoMap::const_iterator aFind = std::find_if(pTypeInfoMap->begin(), pTypeInfoMap->end(), + [&aCase, &sTypeName] (const OTypeInfoMap::value_type& typeInfo) { + return aCase(typeInfo.second->getDBName(), sTypeName); + }); + + if ( aFind != pTypeInfoMap->end() ) // change column type if necessary + aColumn.put_Type(aFind->first); + + if ( SUCCEEDED(static_cast<ADOColumns*>(m_aCollection)->Append(OLEVariant(aColumn.get_Name()),aColumn.get_Type(),aColumn.get_DefinedSize())) ) + { + WpADOColumn aAddedColumn = m_aCollection.GetItem(OLEVariant(aColumn.get_Name())); + if ( aAddedColumn.IsValid() ) + { + bool bAutoIncrement = false; + pColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT)) >>= bAutoIncrement; + if ( bAutoIncrement ) + OTools::putValue( + aAddedColumn.get_Properties(), std::u16string_view(u"Autoincrement"), + bAutoIncrement); + + if ( aFind != pTypeInfoMap->end() && aColumn.get_Type() != aAddedColumn.get_Type() ) // change column type if necessary + aColumn.put_Type(aFind->first); + aAddedColumn.put_Precision(aColumn.get_Precision()); + aAddedColumn.put_NumericScale(aColumn.get_NumericScale()); + aAddedColumn.put_Attributes(aColumn.get_Attributes()); + aAddedColumn.put_SortOrder(aColumn.get_SortOrder()); + aAddedColumn.put_RelatedColumn(aColumn.get_RelatedColumn()); + } + } + ADOS::ThrowException(m_pConnection->getConnection(),static_cast<XTypeProvider*>(this)); + + return new OAdoColumn(isCaseSensitive(),m_pConnection,pColumn->getColumnImpl()); +} + +// XDrop +void OColumns::dropObject(sal_Int32 /*_nPos*/,const OUString& _sElementName) +{ + if(!m_aCollection.Delete(_sElementName)) + ADOS::ThrowException(m_pConnection->getConnection(),static_cast<XTypeProvider*>(this)); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AConnection.cxx b/connectivity/source/drivers/ado/AConnection.cxx new file mode 100644 index 000000000..686a9fed5 --- /dev/null +++ b/connectivity/source/drivers/ado/AConnection.cxx @@ -0,0 +1,568 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <cstddef> +#include <string_view> + +#include <ado/AConnection.hxx> +#include <ado/ADatabaseMetaData.hxx> +#include <ado/ADriver.hxx> +#include <ado/AStatement.hxx> +#include <ado/ACallableStatement.hxx> +#include <ado/APreparedStatement.hxx> +#include <ado/ACatalog.hxx> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <com/sun/star/sdbc/TransactionIsolation.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <comphelper/servicehelper.hxx> +#include <connectivity/dbexception.hxx> +#include <o3tl/string_view.hxx> +#include <osl/file.hxx> +#include <systools/win32/oleauto.hxx> +#include <strings.hrc> + +using namespace dbtools; +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::sdbcx; + + +IMPLEMENT_SERVICE_INFO(OConnection,"com.sun.star.sdbcx.AConnection","com.sun.star.sdbc.Connection"); + +OConnection::OConnection(ODriver* _pDriver) + : m_xCatalog(nullptr), + m_pDriver(_pDriver), + m_pCatalog(nullptr), + m_nEngineType(0), + m_bClosed(false), + m_bAutocommit(true) +{ + osl_atomic_increment( &m_refCount ); + + sal::systools::COMReference<IClassFactory2> pIUnknown; + if (!FAILED(pIUnknown.CoGetClassObject(ADOS::CLSID_ADOCONNECTION_21, CLSCTX_INPROC_SERVER))) + { + HRESULT hr = pIUnknown->CreateInstanceLic(nullptr, + nullptr, + ADOS::IID_ADOCONNECTION_21, + ADOS::GetKeyStr(), + reinterpret_cast<void**>(&m_aAdoConnection)); + + if( !FAILED( hr ) ) + { + OSL_ENSURE(m_aAdoConnection, "OConnection::OConnection: invalid ADO object!"); + } + } + + osl_atomic_decrement( &m_refCount ); +} + +OConnection::~OConnection() +{ +} + +void OConnection::construct(std::u16string_view url,const Sequence< PropertyValue >& info) +{ + osl_atomic_increment( &m_refCount ); + + setConnectionInfo(info); + + std::size_t nLen = url.find(':'); + nLen = url.find(':',nLen == std::u16string_view::npos ? 0 : nLen+1); + std::u16string_view aDSN(url.substr(nLen == std::u16string_view::npos ? 0 : nLen+1)); + OUString aUID,aPWD; + o3tl::starts_with(aDSN, u"access:", &aDSN); + + sal_Int32 nTimeout = 20; + const PropertyValue *pIter = info.getConstArray(); + const PropertyValue *pEnd = pIter + info.getLength(); + for(;pIter != pEnd;++pIter) + { + if(pIter->Name == "Timeout") + pIter->Value >>= nTimeout; + else if(pIter->Name == "user") + pIter->Value >>= aUID; + else if(pIter->Name == "password") + pIter->Value >>= aPWD; + } + try + { + if(m_aAdoConnection) + { + if(m_aAdoConnection.Open(aDSN,aUID,aPWD,adConnectUnspecified)) + m_aAdoConnection.PutCommandTimeout(nTimeout); + else + ADOS::ThrowException(m_aAdoConnection,*this); + if(m_aAdoConnection.get_State() != adStateOpen) + throwGenericSQLException( STR_NO_CONNECTION,*this ); + + WpADOProperties aProps = m_aAdoConnection.get_Properties(); + if(aProps.IsValid()) + { + OTools::putValue(aProps, std::u16string_view(u"Jet OLEDB:ODBC Parsing"), true); + OLEVariant aVar( + OTools::getValue(aProps, std::u16string_view(u"Jet OLEDB:Engine Type"))); + if(!aVar.isNull() && !aVar.isEmpty()) + m_nEngineType = aVar.getInt32(); + } + buildTypeInfo(); + //bErg = TRUE; + } + else + ::dbtools::throwFunctionSequenceException(*this); + + } + catch(const Exception& ) + { + osl_atomic_decrement( &m_refCount ); + throw; + } + osl_atomic_decrement( &m_refCount ); +} + +Reference< XStatement > SAL_CALL OConnection::createStatement( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + Reference< XStatement > xStmt = new OStatement(this); + m_aStatements.push_back(WeakReferenceHelper(xStmt)); + return xStmt; +} + +Reference< XPreparedStatement > SAL_CALL OConnection::prepareStatement( const OUString& sql ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + Reference< XPreparedStatement > xPStmt = new OPreparedStatement(this, sql); + m_aStatements.push_back(WeakReferenceHelper(xPStmt)); + return xPStmt; +} + +Reference< XPreparedStatement > SAL_CALL OConnection::prepareCall( const OUString& sql ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + Reference< XPreparedStatement > xPStmt = new OCallableStatement(this, sql); + m_aStatements.push_back(WeakReferenceHelper(xPStmt)); + return xPStmt; +} + +OUString SAL_CALL OConnection::nativeSQL( const OUString& _sql ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + OUString sql = _sql; + WpADOProperties aProps = m_aAdoConnection.get_Properties(); + if(aProps.IsValid()) + { + OTools::putValue(aProps, std::u16string_view(u"Jet OLEDB:ODBC Parsing"), true); + WpADOCommand aCommand; + aCommand.Create(); + aCommand.put_ActiveConnection(static_cast<IDispatch*>(m_aAdoConnection)); + aCommand.put_CommandText(sql); + sql = aCommand.get_CommandText(); + } + + return sql; +} + +void SAL_CALL OConnection::setAutoCommit( sal_Bool autoCommit ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + m_bAutocommit = autoCommit; + if(!autoCommit) + m_aAdoConnection.BeginTrans(); + else + m_aAdoConnection.RollbackTrans(); +} + +sal_Bool SAL_CALL OConnection::getAutoCommit( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + return m_bAutocommit; +} + +void SAL_CALL OConnection::commit( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + m_aAdoConnection.CommitTrans(); +} + +void SAL_CALL OConnection::rollback( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + m_aAdoConnection.RollbackTrans(); +} + +sal_Bool SAL_CALL OConnection::isClosed( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + return OConnection_BASE::rBHelper.bDisposed && !m_aAdoConnection.get_State(); +} + +Reference< XDatabaseMetaData > SAL_CALL OConnection::getMetaData( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + Reference< XDatabaseMetaData > xMetaData = m_xMetaData; + if(!xMetaData.is()) + { + xMetaData = new ODatabaseMetaData(this); + m_xMetaData = xMetaData; + } + + return xMetaData; +} + +void SAL_CALL OConnection::setReadOnly( sal_Bool readOnly ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + m_aAdoConnection.put_Mode(readOnly ? adModeRead : adModeReadWrite); + ADOS::ThrowException(m_aAdoConnection,*this); +} + +sal_Bool SAL_CALL OConnection::isReadOnly( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + return m_aAdoConnection.get_Mode() == adModeRead; +} + +void SAL_CALL OConnection::setCatalog( const OUString& catalog ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + m_aAdoConnection.PutDefaultDatabase(catalog); + ADOS::ThrowException(m_aAdoConnection,*this); +} + +OUString SAL_CALL OConnection::getCatalog( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + return m_aAdoConnection.GetDefaultDatabase(); +} + +void SAL_CALL OConnection::setTransactionIsolation( sal_Int32 level ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + IsolationLevelEnum eIso; + switch(level) + { + case TransactionIsolation::NONE: + eIso = adXactUnspecified; + break; + case TransactionIsolation::READ_UNCOMMITTED: + eIso = adXactReadUncommitted; + break; + case TransactionIsolation::READ_COMMITTED: + eIso = adXactReadCommitted; + break; + case TransactionIsolation::REPEATABLE_READ: + eIso = adXactRepeatableRead; + break; + case TransactionIsolation::SERIALIZABLE: + eIso = adXactSerializable; + break; + default: + OSL_FAIL("OConnection::setTransactionIsolation invalid level"); + return; + } + m_aAdoConnection.put_IsolationLevel(eIso); + ADOS::ThrowException(m_aAdoConnection,*this); +} + +sal_Int32 SAL_CALL OConnection::getTransactionIsolation( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + sal_Int32 nRet = 0; + switch(m_aAdoConnection.get_IsolationLevel()) + { + case adXactUnspecified: + nRet = TransactionIsolation::NONE; + break; + case adXactReadUncommitted: + nRet = TransactionIsolation::READ_UNCOMMITTED; + break; + case adXactReadCommitted: + nRet = TransactionIsolation::READ_COMMITTED; + break; + case adXactRepeatableRead: + nRet = TransactionIsolation::REPEATABLE_READ; + break; + case adXactSerializable: + nRet = TransactionIsolation::SERIALIZABLE; + break; + default: + OSL_FAIL("OConnection::setTransactionIsolation invalid level"); + } + ADOS::ThrowException(m_aAdoConnection,*this); + return nRet; +} + +Reference< css::container::XNameAccess > SAL_CALL OConnection::getTypeMap( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + return nullptr; +} + +void SAL_CALL OConnection::setTypeMap( const Reference< css::container::XNameAccess >& /*typeMap*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XConnection::setTypeMap", *this ); +} + +// XCloseable +void SAL_CALL OConnection::close( ) +{ + { + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + } + dispose(); +} + +// XWarningsSupplier +Any SAL_CALL OConnection::getWarnings( ) +{ + return Any(); +} + +void SAL_CALL OConnection::clearWarnings( ) +{ +} + +void OConnection::buildTypeInfo() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + ADORecordset *pRecordset = m_aAdoConnection.getTypeInfo(); + if ( pRecordset ) + { + pRecordset->AddRef(); + VARIANT_BOOL bIsAtBOF; + pRecordset->get_BOF(&bIsAtBOF); + + bool bOk = true; + if ( bIsAtBOF == VARIANT_TRUE ) + bOk = SUCCEEDED(pRecordset->MoveNext()); + + if ( bOk ) + { + // HACK for access + static const char s_sVarChar[] = "VarChar"; + do + { + sal_Int32 nPos = 1; + OExtendedTypeInfo* aInfo = new OExtendedTypeInfo; + aInfo->aSimpleType.aTypeName = ADOS::getField(pRecordset,nPos++).get_Value().getString(); + aInfo->eType = static_cast<DataTypeEnum>(ADOS::getField(pRecordset,nPos++).get_Value().getInt32()); + if ( aInfo->eType == adWChar && aInfo->aSimpleType.aTypeName == s_sVarChar ) + aInfo->eType = adVarWChar; + aInfo->aSimpleType.nType = static_cast<sal_Int16>(ADOS::MapADOType2Jdbc(aInfo->eType)); + aInfo->aSimpleType.nPrecision = ADOS::getField(pRecordset,nPos++).get_Value().getInt32(); + nPos++; // aLiteralPrefix + nPos++; // aLiteralSuffix + nPos++; // aCreateParams + nPos++; // bNullable + nPos++; // bCaseSensitive + nPos++; // nSearchType + nPos++; // bUnsigned + nPos++; // bCurrency + nPos++; // bAutoIncrement + aInfo->aSimpleType.aLocalTypeName = ADOS::getField(pRecordset,nPos++).get_Value().getString(); + nPos++; // nMinimumScale + aInfo->aSimpleType.nMaximumScale = ADOS::getField(pRecordset,nPos++).get_Value().getInt16(); + if ( adCurrency == aInfo->eType && !aInfo->aSimpleType.nMaximumScale) + { + aInfo->aSimpleType.nMaximumScale = 4; + } + nPos++; // nNumPrecRadix + // Now that we have the type info, save it + // in the Hashtable if we don't already have an + // entry for this SQL type. + + m_aTypeInfo.emplace(aInfo->eType,aInfo); + } + while ( SUCCEEDED(pRecordset->MoveNext()) ); + } + pRecordset->Release(); + } +} + +void OConnection::disposing() +{ + ::osl::MutexGuard aGuard(m_aMutex); + + OConnection_BASE::disposing(); + + m_bClosed = true; + m_xMetaData = css::uno::WeakReference< css::sdbc::XDatabaseMetaData>(); + m_xCatalog = css::uno::WeakReference< css::sdbcx::XTablesSupplier>(); + m_pDriver = nullptr; + + m_aAdoConnection.Close(); + + for (auto& rEntry : m_aTypeInfo) + delete rEntry.second; + + m_aTypeInfo.clear(); + + m_aAdoConnection.clear(); +} + +sal_Int64 SAL_CALL OConnection::getSomething( const css::uno::Sequence< sal_Int8 >& rId ) +{ + return comphelper::getSomethingImpl(rId, this, + comphelper::FallbackToGetSomethingOf<OConnection_BASE>{}); +} + +Sequence< sal_Int8 > OConnection::getUnoTunnelId() +{ + static const comphelper::UnoIdInit implId; + return implId.getSeq(); +} + +const OExtendedTypeInfo* OConnection::getTypeInfoFromType(const OTypeInfoMap& _rTypeInfo, + DataTypeEnum _nType, + const OUString& _sTypeName, + sal_Int32 _nPrecision, + sal_Int32 _nScale, + bool& _brForceToType) +{ + const OExtendedTypeInfo* pTypeInfo = nullptr; + _brForceToType = false; + // search for type + std::pair<OTypeInfoMap::const_iterator, OTypeInfoMap::const_iterator> aPair = _rTypeInfo.equal_range(_nType); + OTypeInfoMap::const_iterator aIter = aPair.first; + if(aIter != _rTypeInfo.end()) // compare with end is correct here + { + for(;aIter != aPair.second;++aIter) + { + // search the best matching type + OExtendedTypeInfo* pInfo = aIter->second; + if ( ( !_sTypeName.getLength() + || (pInfo->aSimpleType.aTypeName.equalsIgnoreAsciiCase(_sTypeName)) + ) + && (pInfo->aSimpleType.nPrecision >= _nPrecision) + && (pInfo->aSimpleType.nMaximumScale >= _nScale) + + ) + break; + } + + if (aIter == aPair.second) + { + for(aIter = aPair.first; aIter != aPair.second; ++aIter) + { + // search the best matching type (now comparing the local names) + if ( (aIter->second->aSimpleType.aLocalTypeName.equalsIgnoreAsciiCase(_sTypeName)) + && (aIter->second->aSimpleType.nPrecision >= _nPrecision) + && (aIter->second->aSimpleType.nMaximumScale >= _nScale) + ) + { +// we can not assert here because we could be in d&d +/* + OSL_FAIL(( OString("getTypeInfoFromType: assuming column type ") + += OString(aIter->second->aTypeName.getStr(), aIter->second->aTypeName.getLength(), osl_getThreadTextEncoding()) + += OString("\" (expected type name ") + += OString(_sTypeName.getStr(), _sTypeName.getLength(), osl_getThreadTextEncoding()) + += OString(" matches the type's local name).")).getStr()); +*/ + break; + } + } + } + + if (aIter == aPair.second) + { // no match for the names, no match for the local names + // -> drop the precision and the scale restriction, accept any type with the property + // type id (nType) + + // we can not assert here because we could be in d&d + pTypeInfo = aPair.first->second; + _brForceToType = true; + } + else + pTypeInfo = aIter->second; + } + else if ( _sTypeName.getLength() ) + { + ::comphelper::UStringMixEqual aCase(false); + // search for typeinfo where the typename is equal _sTypeName + OTypeInfoMap::const_iterator aFind = std::find_if(_rTypeInfo.begin(), _rTypeInfo.end(), + [&aCase, &_sTypeName] (const OTypeInfoMap::value_type& typeInfo) { + return aCase(typeInfo.second->getDBName(), _sTypeName); + }); + + if(aFind != _rTypeInfo.end()) + pTypeInfo = aFind->second; + } + +// we can not assert here because we could be in d&d +// OSL_ENSURE(pTypeInfo, "getTypeInfoFromType: no type info found for this type!"); + return pTypeInfo; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/ADatabaseMetaData.cxx b/connectivity/source/drivers/ado/ADatabaseMetaData.cxx new file mode 100644 index 000000000..65e0a80f5 --- /dev/null +++ b/connectivity/source/drivers/ado/ADatabaseMetaData.cxx @@ -0,0 +1,1034 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/ADatabaseMetaData.hxx> +#include <ado/ADatabaseMetaDataResultSet.hxx> +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/ResultSetType.hpp> +#include <com/sun/star/sdbc/ResultSetConcurrency.hpp> +#include <com/sun/star/sdbc/TransactionIsolation.hpp> +#include <ado/AConnection.hxx> +#include <ado/adoimp.hxx> +#include <FDatabaseMetaDataResultSet.hxx> +#include <comphelper/types.hxx> +#include <connectivity/dbexception.hxx> +#include <rtl/ref.hxx> + +using namespace ::comphelper; + +using namespace connectivity; +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; + + +ODatabaseMetaData::ODatabaseMetaData(OConnection* _pCon) + : ::connectivity::ODatabaseMetaDataBase(_pCon,_pCon->getConnectionInfo()) + ,m_rADOConnection(_pCon->getConnection()) + ,m_pConnection(_pCon) +{ +} + +sal_Int32 ODatabaseMetaData::getInt32Property(const OUString& _aProperty) +{ + connectivity::ado::WpADOProperties aProps(m_rADOConnection.get_Properties()); + // ADOS::ThrowException(m_rADOConnection,*this); + OSL_ENSURE(aProps.IsValid(),"There are no properties at the connection"); + ADO_PROP(_aProperty); + sal_Int32 nValue(0); + if(!aVar.isNull() && !aVar.isEmpty()) + nValue = aVar.getInt32(); + return nValue; +} + + +bool ODatabaseMetaData::getBoolProperty(const OUString& _aProperty) +{ + connectivity::ado::WpADOProperties aProps(m_rADOConnection.get_Properties()); + ADOS::ThrowException(m_rADOConnection,*this); + OSL_ENSURE(aProps.IsValid(),"There are no properties at the connection"); + ADO_PROP(_aProperty); + return !aVar.isNull() && !aVar.isEmpty() && aVar.getBool(); +} + +OUString ODatabaseMetaData::getStringProperty(const OUString& _aProperty) +{ + connectivity::ado::WpADOProperties aProps(m_rADOConnection.get_Properties()); + ADOS::ThrowException(m_rADOConnection,*this); + OSL_ENSURE(aProps.IsValid(),"There are no properties at the connection"); + + ADO_PROP(_aProperty); + OUString aValue; + if(!aVar.isNull() && !aVar.isEmpty() && aVar.getType() == VT_BSTR) + aValue = aVar.getString(); + + return aValue; +} + +Reference< XResultSet > ODatabaseMetaData::impl_getTypeInfo_throw( ) +{ + ADORecordset *pRecordset = m_rADOConnection.getTypeInfo(); + + rtl::Reference<ODatabaseMetaDataResultSet> pResult = new ODatabaseMetaDataResultSet(pRecordset); + pResult->setTypeInfoMap(ADOS::isJetEngine(m_pConnection->getEngineType())); + return pResult; +} + +Reference< XResultSet > SAL_CALL ODatabaseMetaData::getCatalogs( ) +{ + OLEVariant vtEmpty; + vtEmpty.setNoArg(); + + ADORecordset *pRecordset = nullptr; + m_rADOConnection.OpenSchema(adSchemaCatalogs,vtEmpty,vtEmpty,&pRecordset); + ADOS::ThrowException(m_rADOConnection,*this); + + rtl::Reference<ODatabaseMetaDataResultSet> pResult = new ODatabaseMetaDataResultSet(pRecordset); + pResult->setCatalogsMap(); + + return pResult; +} + +OUString ODatabaseMetaData::impl_getCatalogSeparator_throw( ) +{ + return getLiteral(DBLITERAL_CATALOG_SEPARATOR); +} + +Reference< XResultSet > SAL_CALL ODatabaseMetaData::getSchemas( ) +{ + OLEVariant vtEmpty; + vtEmpty.setNoArg(); + + ADORecordset *pRecordset = nullptr; + m_rADOConnection.OpenSchema(adSchemaSchemata,vtEmpty,vtEmpty,&pRecordset); + ADOS::ThrowException(m_rADOConnection,*this); + + rtl::Reference<ODatabaseMetaDataResultSet> pResult = new ODatabaseMetaDataResultSet(pRecordset); + pResult->setSchemasMap(); + return pResult; +} + +Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumnPrivileges( + const Any& catalog, const OUString& schema, const OUString& table, + const OUString& columnNamePattern ) +{ + ADORecordset *pRecordset = m_rADOConnection.getColumnPrivileges(catalog,schema,table,columnNamePattern); + ADOS::ThrowException(m_rADOConnection,*this); + + rtl::Reference<ODatabaseMetaDataResultSet> pResult = new ODatabaseMetaDataResultSet(pRecordset); + pResult->setColumnPrivilegesMap(); + return pResult; +} + +Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumns( + const Any& catalog, const OUString& schemaPattern, const OUString& tableNamePattern, + const OUString& columnNamePattern ) +{ + ADORecordset *pRecordset = m_rADOConnection.getColumns(catalog,schemaPattern,tableNamePattern,columnNamePattern); + ADOS::ThrowException(m_rADOConnection,*this); + + rtl::Reference<ODatabaseMetaDataResultSet> pResult = new ODatabaseMetaDataResultSet(pRecordset); + pResult->setColumnsMap(); + + return pResult; +} + +Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTables( + const Any& catalog, const OUString& schemaPattern, + const OUString& tableNamePattern, const Sequence< OUString >& types ) +{ + ADORecordset *pRecordset = m_rADOConnection.getTables(catalog,schemaPattern,tableNamePattern,types); + ADOS::ThrowException(m_rADOConnection,*this); + + rtl::Reference<ODatabaseMetaDataResultSet> pResult = new ODatabaseMetaDataResultSet(pRecordset); + pResult->setTablesMap(); + + return pResult; +} + +Reference< XResultSet > SAL_CALL ODatabaseMetaData::getProcedureColumns( + const Any& catalog, const OUString& schemaPattern, + const OUString& procedureNamePattern, const OUString& columnNamePattern ) +{ + ADORecordset *pRecordset = m_rADOConnection.getProcedureColumns(catalog,schemaPattern,procedureNamePattern,columnNamePattern); + ADOS::ThrowException(m_rADOConnection,*this); + + rtl::Reference<ODatabaseMetaDataResultSet> pResult = new ODatabaseMetaDataResultSet(pRecordset); + pResult->setProcedureColumnsMap(); + + return pResult; +} + +Reference< XResultSet > SAL_CALL ODatabaseMetaData::getProcedures( + const Any& catalog, const OUString& schemaPattern, + const OUString& procedureNamePattern ) +{ + // Create elements used in the array + ADORecordset *pRecordset = m_rADOConnection.getProcedures(catalog,schemaPattern,procedureNamePattern); + ADOS::ThrowException(m_rADOConnection,*this); + + rtl::Reference<ODatabaseMetaDataResultSet> pResult = new ODatabaseMetaDataResultSet(pRecordset); + pResult->setProceduresMap(); + + return pResult; +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxBinaryLiteralLength( ) +{ + return getMaxSize(DBLITERAL_BINARY_LITERAL); +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxRowSize( ) +{ + return getInt32Property("Maximum Row Size"); +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCatalogNameLength( ) +{ + return getMaxSize(DBLITERAL_CATALOG_NAME); +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCharLiteralLength( ) +{ + return getMaxSize(DBLITERAL_CHAR_LITERAL); +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnNameLength( ) +{ + return getMaxSize(DBLITERAL_COLUMN_NAME); +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInIndex( ) +{ + return 0; +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCursorNameLength( ) +{ + return getMaxSize(DBLITERAL_CURSOR_NAME); +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxConnections( ) +{ + return getInt32Property("Active Sessions"); +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInTable( ) +{ + return getInt32Property("Max Columns in Table"); +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxStatementLength( ) +{ + return getMaxSize(DBLITERAL_TEXT_COMMAND); +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxTableNameLength( ) +{ + return getMaxSize(DBLITERAL_TABLE_NAME); +} + +sal_Int32 ODatabaseMetaData::impl_getMaxTablesInSelect_throw( ) +{ + return getInt32Property("Maximum Tables in SELECT"); +} + +Reference< XResultSet > SAL_CALL ODatabaseMetaData::getExportedKeys( + const Any& catalog, const OUString& schema, const OUString& table ) +{ + ADORecordset *pRecordset = m_rADOConnection.getExportedKeys(catalog,schema,table); + ADOS::ThrowException(m_rADOConnection,*this); + + rtl::Reference<ODatabaseMetaDataResultSet> pResult = new ODatabaseMetaDataResultSet(pRecordset); + pResult->setCrossReferenceMap(); + + return pResult; +} + +Reference< XResultSet > SAL_CALL ODatabaseMetaData::getImportedKeys( + const Any& catalog, const OUString& schema, const OUString& table ) +{ + ADORecordset *pRecordset = m_rADOConnection.getImportedKeys(catalog,schema,table); + ADOS::ThrowException(m_rADOConnection,*this); + + rtl::Reference<ODatabaseMetaDataResultSet> pResult = new ODatabaseMetaDataResultSet(pRecordset); + pResult->setCrossReferenceMap(); + + return pResult; +} + +Reference< XResultSet > SAL_CALL ODatabaseMetaData::getPrimaryKeys( + const Any& catalog, const OUString& schema, const OUString& table ) +{ + ADORecordset *pRecordset = m_rADOConnection.getPrimaryKeys(catalog,schema,table); + ADOS::ThrowException(m_rADOConnection,*this); + + rtl::Reference<ODatabaseMetaDataResultSet> pResult = new ODatabaseMetaDataResultSet(pRecordset); + pResult->setPrimaryKeysMap(); + + return pResult; +} + +Reference< XResultSet > SAL_CALL ODatabaseMetaData::getIndexInfo( + const Any& catalog, const OUString& schema, const OUString& table, + sal_Bool unique, sal_Bool approximate ) +{ + ADORecordset *pRecordset = m_rADOConnection.getIndexInfo(catalog,schema,table,unique,approximate); + ADOS::ThrowException(m_rADOConnection,*this); + + rtl::Reference<ODatabaseMetaDataResultSet> pResult = new ODatabaseMetaDataResultSet(pRecordset); + pResult->setIndexInfoMap(); + + return pResult; +} + +Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTablePrivileges( + const Any& catalog, const OUString& schemaPattern, const OUString& tableNamePattern ) +{ + Reference< XResultSet > xRef; + if(!ADOS::isJetEngine(m_pConnection->getEngineType())) + { // the jet provider doesn't support this method + // Create elements used in the array + + ADORecordset *pRecordset = m_rADOConnection.getTablePrivileges(catalog,schemaPattern,tableNamePattern); + ADOS::ThrowException(m_rADOConnection,*this); + + rtl::Reference<ODatabaseMetaDataResultSet> pResult = new ODatabaseMetaDataResultSet(pRecordset); + pResult->setTablePrivilegesMap(); + xRef = pResult; + } + else + { + rtl::Reference<::connectivity::ODatabaseMetaDataResultSet> pResult = new ::connectivity::ODatabaseMetaDataResultSet(::connectivity::ODatabaseMetaDataResultSet::eTablePrivileges); + xRef = pResult; + ::connectivity::ODatabaseMetaDataResultSet::ORows aRows; + ::connectivity::ODatabaseMetaDataResultSet::ORow aRow(8); + aRows.reserve(8); + + aRow[0] = ::connectivity::ODatabaseMetaDataResultSet::getEmptyValue(); + aRow[1] = ::connectivity::ODatabaseMetaDataResultSet::getEmptyValue(); + aRow[2] = new ::connectivity::ORowSetValueDecorator(tableNamePattern); + aRow[3] = ::connectivity::ODatabaseMetaDataResultSet::getEmptyValue(); + aRow[4] = ::connectivity::ODatabaseMetaDataResultSet::getEmptyValue(); + aRow[5] = new ::connectivity::ORowSetValueDecorator(getUserName()); + aRow[6] = ::connectivity::ODatabaseMetaDataResultSet::getSelectValue(); + aRow[7] = new ::connectivity::ORowSetValueDecorator(OUString("NO")); + + aRows.push_back(aRow); + aRow[6] = ::connectivity::ODatabaseMetaDataResultSet::getInsertValue(); + aRows.push_back(aRow); + aRow[6] = ::connectivity::ODatabaseMetaDataResultSet::getDeleteValue(); + aRows.push_back(aRow); + aRow[6] = ::connectivity::ODatabaseMetaDataResultSet::getUpdateValue(); + aRows.push_back(aRow); + aRow[6] = ::connectivity::ODatabaseMetaDataResultSet::getCreateValue(); + aRows.push_back(aRow); + aRow[6] = ::connectivity::ODatabaseMetaDataResultSet::getReadValue(); + aRows.push_back(aRow); + aRow[6] = ::connectivity::ODatabaseMetaDataResultSet::getAlterValue(); + aRows.push_back(aRow); + aRow[6] = ::connectivity::ODatabaseMetaDataResultSet::getDropValue(); + aRows.push_back(aRow); + pResult->setRows(std::move(aRows)); + } + + return xRef; +} + +Reference< XResultSet > SAL_CALL ODatabaseMetaData::getCrossReference( + const Any& primaryCatalog, const OUString& primarySchema, + const OUString& primaryTable, const Any& foreignCatalog, + const OUString& foreignSchema, const OUString& foreignTable ) +{ + ADORecordset *pRecordset = m_rADOConnection.getCrossReference(primaryCatalog,primarySchema,primaryTable,foreignCatalog,foreignSchema,foreignTable); + ADOS::ThrowException(m_rADOConnection,*this); + + rtl::Reference<ODatabaseMetaDataResultSet> pResult = new ODatabaseMetaDataResultSet(pRecordset); + pResult->setCrossReferenceMap(); + + return pResult; +} + +sal_Bool SAL_CALL ODatabaseMetaData::doesMaxRowSizeIncludeBlobs( ) +{ + return getBoolProperty("Maximum Row Size Includes BLOB"); +} + +sal_Bool SAL_CALL ODatabaseMetaData::storesLowerCaseQuotedIdentifiers( ) +{ + return (getInt32Property("Identifier Case Sensitivity") & DBPROPVAL_IC_LOWER) == DBPROPVAL_IC_LOWER ; +} + +sal_Bool SAL_CALL ODatabaseMetaData::storesLowerCaseIdentifiers( ) +{ + return (getInt32Property("Identifier Case Sensitivity") & DBPROPVAL_IC_LOWER) == DBPROPVAL_IC_LOWER ; +} + +bool ODatabaseMetaData::impl_storesMixedCaseQuotedIdentifiers_throw( ) +{ + return (getInt32Property("Identifier Case Sensitivity") & DBPROPVAL_IC_MIXED) == DBPROPVAL_IC_MIXED ; +} + +sal_Bool SAL_CALL ODatabaseMetaData::storesMixedCaseIdentifiers( ) +{ + return (getInt32Property("Identifier Case Sensitivity") & DBPROPVAL_IC_MIXED) == DBPROPVAL_IC_MIXED ; +} + +sal_Bool SAL_CALL ODatabaseMetaData::storesUpperCaseQuotedIdentifiers( ) +{ + return (getInt32Property("Identifier Case Sensitivity") & DBPROPVAL_IC_UPPER) == DBPROPVAL_IC_UPPER ; +} + +sal_Bool SAL_CALL ODatabaseMetaData::storesUpperCaseIdentifiers( ) +{ + return (getInt32Property("Identifier Case Sensitivity") & DBPROPVAL_IC_UPPER) == DBPROPVAL_IC_UPPER ; +} + +bool ODatabaseMetaData::impl_supportsAlterTableWithAddColumn_throw( ) +{ + return true; +} + +bool ODatabaseMetaData::impl_supportsAlterTableWithDropColumn_throw( ) +{ + return true; +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxIndexLength( ) +{ + return getInt32Property("Maximum Index Size"); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsNonNullableColumns( ) +{ + return getInt32Property("NULL Concatenation Behavior") == DBPROPVAL_CB_NON_NULL; +} + +OUString SAL_CALL ODatabaseMetaData::getCatalogTerm( ) +{ + return getStringProperty("Catalog Term"); +} + +OUString ODatabaseMetaData::impl_getIdentifierQuoteString_throw( ) +{ + return getLiteral(DBLITERAL_QUOTE_PREFIX); + +} + +OUString SAL_CALL ODatabaseMetaData::getExtraNameCharacters( ) +{ + return OUString(); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsDifferentTableCorrelationNames( ) +{ + return isCapable(DBLITERAL_CORRELATION_NAME); +} + +bool ODatabaseMetaData::impl_isCatalogAtStart_throw( ) +{ + return getInt32Property("Catalog Location") == DBPROPVAL_CL_START; +} + +sal_Bool SAL_CALL ODatabaseMetaData::dataDefinitionIgnoredInTransactions( ) +{ + return getInt32Property("Transaction DDL") == DBPROPVAL_TC_DDL_IGNORE; +} + +sal_Bool SAL_CALL ODatabaseMetaData::dataDefinitionCausesTransactionCommit( ) +{ + return getInt32Property("Transaction DDL") == DBPROPVAL_TC_DDL_COMMIT; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsDataManipulationTransactionsOnly( ) +{ + return getInt32Property("Transaction DDL") == DBPROPVAL_TC_DML; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsDataDefinitionAndDataManipulationTransactions( ) +{ + return getInt32Property("Transaction DDL") == DBPROPVAL_TC_ALL; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsPositionedDelete( ) +{ + return true; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsPositionedUpdate( ) +{ + return true; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenStatementsAcrossRollback( ) +{ + return getInt32Property("Prepare Abort Behavior") == DBPROPVAL_CB_PRESERVE; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenStatementsAcrossCommit( ) +{ + return getInt32Property("Prepare Commit Behavior") == DBPROPVAL_CB_PRESERVE; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenCursorsAcrossCommit( ) +{ + return (getInt32Property("Isolation Retention") & DBPROPVAL_TR_COMMIT) == DBPROPVAL_TR_COMMIT; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenCursorsAcrossRollback( ) +{ + return (getInt32Property("Isolation Retention") & DBPROPVAL_TR_ABORT) == DBPROPVAL_TR_ABORT; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsTransactionIsolationLevel( sal_Int32 level ) +{ + bool bValue(false); + + sal_Int32 nTxn = getInt32Property("Isolation Levels"); + if(level == TransactionIsolation::NONE) + bValue = true; + else if(level == TransactionIsolation::READ_UNCOMMITTED) + bValue = (nTxn & DBPROPVAL_TI_READUNCOMMITTED) == DBPROPVAL_TI_READUNCOMMITTED; + else if(level == TransactionIsolation::READ_COMMITTED) + bValue = (nTxn & DBPROPVAL_TI_READCOMMITTED) == DBPROPVAL_TI_READCOMMITTED; + else if(level == TransactionIsolation::REPEATABLE_READ) + bValue = (nTxn & DBPROPVAL_TI_REPEATABLEREAD) == DBPROPVAL_TI_REPEATABLEREAD; + else if(level == TransactionIsolation::SERIALIZABLE) + bValue = (nTxn & DBPROPVAL_TI_SERIALIZABLE) == DBPROPVAL_TI_SERIALIZABLE; + + return bValue; +} + +bool ODatabaseMetaData::impl_supportsSchemasInDataManipulation_throw( ) +{ + return (getInt32Property("Schema Usage") & DBPROPVAL_SU_DML_STATEMENTS) == DBPROPVAL_SU_DML_STATEMENTS; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsANSI92FullSQL( ) +{ + sal_Int32 nProp = getInt32Property("SQL Support"); + return (nProp == 512) || ((nProp & DBPROPVAL_SQL_ANSI92_FULL) == DBPROPVAL_SQL_ANSI92_FULL); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsANSI92EntryLevelSQL( ) +{ + sal_Int32 nProp = getInt32Property("SQL Support"); + return (nProp == 512) || ((nProp & DBPROPVAL_SQL_ANSI92_ENTRY) == DBPROPVAL_SQL_ANSI92_ENTRY); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsIntegrityEnhancementFacility( ) +{ + sal_Int32 nProp = getInt32Property("SQL Support"); + return (nProp == 512) || ((nProp & DBPROPVAL_SQL_ANSI89_IEF) == DBPROPVAL_SQL_ANSI89_IEF); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInIndexDefinitions( ) +{ + return (getInt32Property("Schema Usage") & DBPROPVAL_SU_INDEX_DEFINITION) == DBPROPVAL_SU_INDEX_DEFINITION; +} + +bool ODatabaseMetaData::impl_supportsSchemasInTableDefinitions_throw( ) +{ + return (getInt32Property("Schema Usage") & DBPROPVAL_SU_TABLE_DEFINITION) == DBPROPVAL_SU_TABLE_DEFINITION; +} + +bool ODatabaseMetaData::impl_supportsCatalogsInTableDefinitions_throw( ) +{ + return false; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInIndexDefinitions( ) +{ + return false; +} + +bool ODatabaseMetaData::impl_supportsCatalogsInDataManipulation_throw( ) +{ + return false; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsOuterJoins( ) +{ + if ( ADOS::isJetEngine(m_pConnection->getEngineType()) ) + return true; + return getBoolProperty("Outer Join Capabilities"); +} + +Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTableTypes( ) +{ + return new ::connectivity::ODatabaseMetaDataResultSet(::connectivity::ODatabaseMetaDataResultSet::eTableTypes); +} + +sal_Int32 ODatabaseMetaData::impl_getMaxStatements_throw( ) +{ + return 0; +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxProcedureNameLength( ) +{ + return getMaxSize(DBLITERAL_PROCEDURE_NAME); +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxSchemaNameLength( ) +{ + return getMaxSize(DBLITERAL_SCHEMA_NAME); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsTransactions( ) +{ + return getInt32Property("Transaction DDL") == DBPROPVAL_TC_NONE; +} + +sal_Bool SAL_CALL ODatabaseMetaData::allProceduresAreCallable( ) +{ + return true; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsStoredProcedures( ) +{ + return true; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsSelectForUpdate( ) +{ + return true; +} + +sal_Bool SAL_CALL ODatabaseMetaData::allTablesAreSelectable( ) +{ + return true; +} + +sal_Bool SAL_CALL ODatabaseMetaData::isReadOnly( ) +{ + return getBoolProperty("Read-Only Data Source"); +} + +sal_Bool SAL_CALL ODatabaseMetaData::usesLocalFiles( ) +{ + return false; +} + +sal_Bool SAL_CALL ODatabaseMetaData::usesLocalFilePerTable( ) +{ + return false; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsTypeConversion( ) +{ + return true; +} + +sal_Bool SAL_CALL ODatabaseMetaData::nullPlusNonNullIsNull( ) +{ + return getInt32Property("NULL Concatenation Behavior") == DBPROPVAL_CB_NULL; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsColumnAliasing( ) +{ + return isCapable(DBLITERAL_COLUMN_ALIAS); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsTableCorrelationNames( ) +{ + return isCapable(DBLITERAL_CORRELATION_NAME); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsConvert( sal_Int32 /*fromType*/, sal_Int32 /*toType*/ ) +{ + return getBoolProperty("Rowset Conversions on Command"); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsExpressionsInOrderBy( ) +{ + return getBoolProperty("ORDER BY Columns in Select List"); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupBy( ) +{ + return getInt32Property("GROUP BY Support") != DBPROPVAL_GB_NOT_SUPPORTED; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupByBeyondSelect( ) +{ + return getInt32Property("GROUP BY Support") != DBPROPVAL_GB_CONTAINS_SELECT; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupByUnrelated( ) +{ + return getInt32Property("GROUP BY Support") == DBPROPVAL_GB_NO_RELATION; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsMultipleTransactions( ) +{ + return true; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsMultipleResultSets( ) +{ + return false; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsLikeEscapeClause( ) +{ + return isCapable(DBLITERAL_ESCAPE_PERCENT); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsOrderByUnrelated( ) +{ + return getBoolProperty("ORDER BY Columns in Select List"); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsUnion( ) +{ + return true; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsUnionAll( ) +{ + return true; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsMixedCaseIdentifiers( ) +{ + return (getInt32Property("Identifier Case Sensitivity") & DBPROPVAL_IC_MIXED) == DBPROPVAL_IC_MIXED; +} + +bool ODatabaseMetaData::impl_supportsMixedCaseQuotedIdentifiers_throw( ) +{ + return (getInt32Property("Identifier Case Sensitivity") & DBPROPVAL_IC_MIXED) == DBPROPVAL_IC_MIXED; +} + +sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedAtEnd( ) +{ + return (getInt32Property("NULL Collation Order") & DBPROPVAL_NC_END) == DBPROPVAL_NC_END; +} + +sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedAtStart( ) +{ + return (getInt32Property("NULL Collation Order") & DBPROPVAL_NC_START) == DBPROPVAL_NC_START; +} + +sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedHigh( ) +{ + return (getInt32Property("NULL Collation Order") & DBPROPVAL_NC_HIGH) == DBPROPVAL_NC_HIGH; +} + +sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedLow( ) +{ + return (getInt32Property("NULL Collation Order") & DBPROPVAL_NC_LOW) == DBPROPVAL_NC_LOW; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInProcedureCalls( ) +{ + return false; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInPrivilegeDefinitions( ) +{ + return (getInt32Property("Schema Usage") & DBPROPVAL_SU_PRIVILEGE_DEFINITION) == DBPROPVAL_SU_PRIVILEGE_DEFINITION; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInProcedureCalls( ) +{ + return false; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInPrivilegeDefinitions( ) +{ + return false; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsCorrelatedSubqueries( ) +{ + return (getInt32Property("Subquery Support") & DBPROPVAL_SQ_CORRELATEDSUBQUERIES) == DBPROPVAL_SQ_CORRELATEDSUBQUERIES; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInComparisons( ) +{ + return (getInt32Property("Subquery Support") & DBPROPVAL_SQ_COMPARISON) == DBPROPVAL_SQ_COMPARISON; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInExists( ) +{ + return (getInt32Property("Subquery Support") & DBPROPVAL_SQ_EXISTS) == DBPROPVAL_SQ_EXISTS; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInIns( ) +{ + return (getInt32Property("Subquery Support") & DBPROPVAL_SQ_IN) == DBPROPVAL_SQ_IN; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInQuantifieds( ) +{ + return (getInt32Property("Subquery Support") & DBPROPVAL_SQ_QUANTIFIED) == DBPROPVAL_SQ_QUANTIFIED; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsANSI92IntermediateSQL( ) +{ + sal_Int32 nProp = getInt32Property("SQL Support"); + return (nProp == 512) || ((nProp & DBPROPVAL_SQL_ANSI92_INTERMEDIATE) == DBPROPVAL_SQL_ANSI92_INTERMEDIATE); +} + +OUString SAL_CALL ODatabaseMetaData::getURL( ) +{ + return "sdbc:ado:"+ m_rADOConnection.GetConnectionString(); +} + +OUString SAL_CALL ODatabaseMetaData::getUserName( ) +{ + return getStringProperty("User Name"); +} + +OUString SAL_CALL ODatabaseMetaData::getDriverName( ) +{ + return getStringProperty("Provider Friendly Name"); +} + +OUString SAL_CALL ODatabaseMetaData::getDriverVersion( ) +{ + return getStringProperty("Provider Version"); +} + +OUString SAL_CALL ODatabaseMetaData::getDatabaseProductVersion( ) +{ + return getStringProperty("DBMS Version"); +} + +OUString SAL_CALL ODatabaseMetaData::getDatabaseProductName( ) +{ + return getStringProperty("DBMS Name"); +} + +OUString SAL_CALL ODatabaseMetaData::getProcedureTerm( ) +{ + return getStringProperty("Procedure Term"); +} + +OUString SAL_CALL ODatabaseMetaData::getSchemaTerm( ) +{ + return getStringProperty("Schema Term"); +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getDriverMajorVersion( ) +{ + return 1; +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getDefaultTransactionIsolation( ) +{ + sal_Int32 nRet = TransactionIsolation::NONE; + switch(m_rADOConnection.get_IsolationLevel()) + { + case adXactReadCommitted: + nRet = TransactionIsolation::READ_COMMITTED; + break; + case adXactRepeatableRead: + nRet = TransactionIsolation::REPEATABLE_READ; + break; + case adXactSerializable: + nRet = TransactionIsolation::SERIALIZABLE; + break; + case adXactReadUncommitted: + nRet = TransactionIsolation::READ_UNCOMMITTED; + break; + default: + ; + } + return nRet; +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getDriverMinorVersion( ) +{ + return 0; +} + +OUString SAL_CALL ODatabaseMetaData::getSQLKeywords( ) +{ + WpADORecordset aRecordset; + OLEVariant vtEmpty; + vtEmpty.setNoArg(); + m_rADOConnection.OpenSchema(adSchemaDBInfoKeywords,vtEmpty,vtEmpty,&aRecordset); + OSL_ENSURE(aRecordset,"getSQLKeywords: no resultset!"); + ADOS::ThrowException(m_rADOConnection,*this); + if ( aRecordset ) + { + aRecordset.MoveFirst(); + OLEVariant aValue; + OUString aRet; + while(!aRecordset.IsAtEOF()) + { + WpOLEAppendCollection<ADOFields, WpADOField> aFields(aRecordset.GetFields()); + WpADOField aField(aFields.GetItem(0)); + aField.get_Value(aValue); + aRet += aValue.getString() + ","; + aRecordset.MoveNext(); + } + aRecordset.Close(); + if ( !aRet.isEmpty() ) + return aRet.copy(0,aRet.lastIndexOf(',')); + } + return OUString(); +} + +OUString SAL_CALL ODatabaseMetaData::getSearchStringEscape( ) +{ + return getLiteral(DBLITERAL_ESCAPE_PERCENT); +} + +OUString SAL_CALL ODatabaseMetaData::getStringFunctions( ) +{ + return OUString(); +} + +OUString SAL_CALL ODatabaseMetaData::getTimeDateFunctions( ) +{ + return OUString(); +} + +OUString SAL_CALL ODatabaseMetaData::getSystemFunctions( ) +{ + return OUString(); +} + +OUString SAL_CALL ODatabaseMetaData::getNumericFunctions( ) +{ + return OUString(); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsExtendedSQLGrammar( ) +{ + sal_Int32 nProp = getInt32Property("SQL Support"); + return (nProp == 512) || ((nProp & DBPROPVAL_SQL_ODBC_EXTENDED) == DBPROPVAL_SQL_ODBC_EXTENDED); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsCoreSQLGrammar( ) +{ + sal_Int32 nProp = getInt32Property("SQL Support"); + return (nProp == 512) || ((nProp & DBPROPVAL_SQL_ODBC_CORE) == DBPROPVAL_SQL_ODBC_CORE); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsMinimumSQLGrammar( ) +{ + sal_Int32 nProp = getInt32Property("SQL Support"); + return (nProp == 512) || ((nProp & DBPROPVAL_SQL_ODBC_MINIMUM) == DBPROPVAL_SQL_ODBC_MINIMUM); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsFullOuterJoins( ) +{ + if ( ADOS::isJetEngine(m_pConnection->getEngineType()) ) + return true; + return (getInt32Property("Outer Join Capabilities") & 0x00000004L) == 0x00000004L; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsLimitedOuterJoins( ) +{ + return supportsFullOuterJoins( ); +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInGroupBy( ) +{ + return getInt32Property("Max Columns in GROUP BY"); +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInOrderBy( ) +{ + return getInt32Property("Max Columns in ORDER BY"); +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInSelect( ) +{ + return 0; +} + +sal_Int32 SAL_CALL ODatabaseMetaData::getMaxUserNameLength( ) +{ + return getMaxSize(DBLITERAL_USER_NAME); +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsResultSetType( sal_Int32 /*setType*/ ) +{ + return true; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsResultSetConcurrency( sal_Int32 /*setType*/, sal_Int32 /*concurrency*/ ) +{ + return true; +} + +sal_Bool SAL_CALL ODatabaseMetaData::ownUpdatesAreVisible( sal_Int32 setType ) +{ + return ResultSetType::FORWARD_ONLY != setType; +} + +sal_Bool SAL_CALL ODatabaseMetaData::ownDeletesAreVisible( sal_Int32 setType ) +{ + return ResultSetType::FORWARD_ONLY != setType; +} + +sal_Bool SAL_CALL ODatabaseMetaData::ownInsertsAreVisible( sal_Int32 setType ) +{ + return ResultSetType::FORWARD_ONLY != setType; +} + +sal_Bool SAL_CALL ODatabaseMetaData::othersUpdatesAreVisible( sal_Int32 setType ) +{ + return ResultSetType::FORWARD_ONLY != setType; +} + +sal_Bool SAL_CALL ODatabaseMetaData::othersDeletesAreVisible( sal_Int32 setType ) +{ + return ResultSetType::FORWARD_ONLY != setType; +} + +sal_Bool SAL_CALL ODatabaseMetaData::othersInsertsAreVisible( sal_Int32 setType ) +{ + return ResultSetType::FORWARD_ONLY != setType; +} + +sal_Bool SAL_CALL ODatabaseMetaData::updatesAreDetected( sal_Int32 setType ) +{ + return ResultSetType::FORWARD_ONLY != setType; +} + +sal_Bool SAL_CALL ODatabaseMetaData::deletesAreDetected( sal_Int32 setType ) +{ + return ResultSetType::FORWARD_ONLY != setType; +} + +sal_Bool SAL_CALL ODatabaseMetaData::insertsAreDetected( sal_Int32 setType ) +{ + return ResultSetType::FORWARD_ONLY != setType; +} + +sal_Bool SAL_CALL ODatabaseMetaData::supportsBatchUpdates( ) +{ + return true; +} + +Reference< XResultSet > SAL_CALL ODatabaseMetaData::getUDTs( const Any& /*catalog*/, const OUString& /*schemaPattern*/, const OUString& /*typeNamePattern*/, const Sequence< sal_Int32 >& /*types*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XDatabaseMetaData::getUDTs", *this ); + return Reference< XResultSet >(); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/ADatabaseMetaDataImpl.cxx b/connectivity/source/drivers/ado/ADatabaseMetaDataImpl.cxx new file mode 100644 index 000000000..b78720706 --- /dev/null +++ b/connectivity/source/drivers/ado/ADatabaseMetaDataImpl.cxx @@ -0,0 +1,543 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <string_view> + +#include <ado/ADatabaseMetaData.hxx> +#include <ado/ADatabaseMetaDataResultSetMetaData.hxx> +#include <ado/Awrapado.hxx> +#include <ado/AGroup.hxx> +#include <ado/adoimp.hxx> +#include <ado/AIndex.hxx> +#include <ado/AKey.hxx> +#include <ado/ATable.hxx> + +#include <systools/win32/oleauto.hxx> + +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/ProcedureResult.hpp> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#ifdef DELETE +#undef DELETE +#endif +#include <com/sun/star/sdbcx/Privilege.hpp> +#include <com/sun/star/sdbcx/PrivilegeObject.hpp> +#include <com/sun/star/sdbc/KeyRule.hpp> +#include <com/sun/star/sdbcx/KeyType.hpp> + +using namespace connectivity::ado; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::uno; + + +void ODatabaseMetaData::fillLiterals() +{ + WpADORecordset aRecordset; + OLEVariant vtEmpty; + vtEmpty.setNoArg(); + m_rADOConnection.OpenSchema(adSchemaDBInfoLiterals,vtEmpty,vtEmpty,&aRecordset); + + ADOS::ThrowException(m_rADOConnection,*this); + + OSL_ENSURE(aRecordset,"fillLiterals: no resultset!"); + if ( aRecordset ) + { + aRecordset.MoveFirst(); + OLEVariant aValue; + LiteralInfo aInfo; + while(!aRecordset.IsAtEOF()) + { + WpOLEAppendCollection<ADOFields, WpADOField> aFields(aRecordset.GetFields()); + WpADOField aField(aFields.GetItem(1)); + aInfo.pwszLiteralValue = aField.get_Value().getString(); + aField = aFields.GetItem(5); + aInfo.fSupported = aField.get_Value().getBool(); + aField = aFields.GetItem(6); + aInfo.cchMaxLen = aField.get_Value().getUInt32(); + + aField = aFields.GetItem(4); + sal_uInt32 nId = aField.get_Value().getUInt32(); + m_aLiteralInfo[nId] = aInfo; + + aRecordset.MoveNext(); + } + aRecordset.Close(); + } +} + +sal_Int32 ODatabaseMetaData::getMaxSize(sal_uInt32 _nId) +{ + if(m_aLiteralInfo.empty()) + fillLiterals(); + + sal_Int32 nSize = 0; + std::map<sal_uInt32,LiteralInfo>::const_iterator aIter = m_aLiteralInfo.find(_nId); + if(aIter != m_aLiteralInfo.end() && (*aIter).second.fSupported) + nSize = (static_cast<sal_Int32>((*aIter).second.cchMaxLen) == -1) ? 0 : (*aIter).second.cchMaxLen; + return nSize; +} + +bool ODatabaseMetaData::isCapable(sal_uInt32 _nId) +{ + if(m_aLiteralInfo.empty()) + fillLiterals(); + bool bSupported = false; + std::map<sal_uInt32,LiteralInfo>::const_iterator aIter = m_aLiteralInfo.find(_nId); + if(aIter != m_aLiteralInfo.end()) + bSupported = (*aIter).second.fSupported; + return bSupported; +} + + +OUString ODatabaseMetaData::getLiteral(sal_uInt32 _nId) +{ + if(m_aLiteralInfo.empty()) + fillLiterals(); + OUString sStr; + std::map<sal_uInt32,LiteralInfo>::const_iterator aIter = m_aLiteralInfo.find(_nId); + if(aIter != m_aLiteralInfo.end() && (*aIter).second.fSupported) + sStr = (*aIter).second.pwszLiteralValue; + return sStr; +} + + +void ODatabaseMetaDataResultSetMetaData::setColumnPrivilegesMap() +{ + m_mColumns[8] = OColumn(OUString(),"IS_GRANTABLE", + ColumnValue::NULLABLE, + 3,3,0, + DataType::VARCHAR); +} + +void ODatabaseMetaDataResultSetMetaData::setColumnsMap() +{ + m_mColumns[6] = OColumn(OUString(),"TYPE_NAME", + ColumnValue::NO_NULLS, + 0,0,0, + DataType::VARCHAR); + m_mColumns[11] = OColumn(OUString(),"NULLABLE", + ColumnValue::NO_NULLS, + 1,1,0, + DataType::INTEGER); + m_mColumns[12] = OColumn(OUString(),"REMARKS", + ColumnValue::NULLABLE, + 0,0,0, + DataType::VARCHAR); + m_mColumns[13] = OColumn(OUString(),"COLUMN_DEF", + ColumnValue::NULLABLE, + 0,0,0, + DataType::VARCHAR); + m_mColumns[14] = OColumn(OUString(),"SQL_DATA_TYPE", + ColumnValue::NO_NULLS, + 1,1,0, + DataType::INTEGER); + m_mColumns[15] = OColumn(OUString(),"SQL_DATETIME_SUB", + ColumnValue::NO_NULLS, + 1,1,0, + DataType::INTEGER); + m_mColumns[16] = OColumn(OUString(),"CHAR_OCTET_LENGTH", + ColumnValue::NO_NULLS, + 1,1,0, + DataType::INTEGER); +} + +void ODatabaseMetaDataResultSetMetaData::setTablesMap() +{ + m_mColumns[5] = OColumn(OUString(),"REMARKS", + ColumnValue::NULLABLE, + 0,0,0, + DataType::VARCHAR); +} + +void ODatabaseMetaDataResultSetMetaData::setProcedureColumnsMap() +{ + m_mColumns[12] = OColumn(OUString(),"NULLABLE", + ColumnValue::NO_NULLS, + 1,1,0, + DataType::INTEGER); +} + +void ODatabaseMetaDataResultSetMetaData::setPrimaryKeysMap() +{ + m_mColumns[5] = OColumn(OUString(),"KEY_SEQ", + ColumnValue::NO_NULLS, + 1,1,0, + DataType::INTEGER); + m_mColumns[6] = OColumn(OUString(),"PK_NAME", + ColumnValue::NULLABLE, + 0,0,0, + DataType::VARCHAR); +} + +void ODatabaseMetaDataResultSetMetaData::setIndexInfoMap() +{ + m_mColumns[4] = OColumn(OUString(),"NON_UNIQUE", + ColumnValue::NO_NULLS, + 1,1,0, + DataType::BIT); + m_mColumns[5] = OColumn(OUString(),"INDEX_QUALIFIER", + ColumnValue::NULLABLE, + 0,0,0, + DataType::VARCHAR); + m_mColumns[10] = OColumn(OUString(),"ASC_OR_DESC", + ColumnValue::NULLABLE, + 0,0,0, + DataType::VARCHAR); +} + +void ODatabaseMetaDataResultSetMetaData::setTablePrivilegesMap() +{ + m_mColumns[6] = OColumn(OUString(),"PRIVILEGE", + ColumnValue::NULLABLE, + 0,0,0, + DataType::VARCHAR); + m_mColumns[7] = OColumn(OUString(),"IS_GRANTABLE", + ColumnValue::NULLABLE, + 0,0,0, + DataType::VARCHAR); +} + +void ODatabaseMetaDataResultSetMetaData::setCrossReferenceMap() +{ + m_mColumns[9] = OColumn(OUString(),"KEY_SEQ", + ColumnValue::NO_NULLS, + 1,1,0, + DataType::INTEGER); +} + +void ODatabaseMetaDataResultSetMetaData::setTypeInfoMap() +{ + m_mColumns[3] = OColumn(OUString(),"PRECISION", + ColumnValue::NO_NULLS, + 1,1,0, + DataType::INTEGER); + m_mColumns[7] = OColumn(OUString(),"NULLABLE", + ColumnValue::NO_NULLS, + 1,1,0, + DataType::INTEGER); + m_mColumns[12] = OColumn(OUString(),"AUTO_INCREMENT", + ColumnValue::NO_NULLS, + 1,1,0, + DataType::BIT); + m_mColumns[16] = OColumn(OUString(),"SQL_DATA_TYPE", + ColumnValue::NO_NULLS, + 1,1,0, + DataType::INTEGER); + m_mColumns[17] = OColumn(OUString(),"SQL_DATETIME_SUB", + ColumnValue::NO_NULLS, + 1,1,0, + DataType::INTEGER); + m_mColumns[18] = OColumn(OUString(),"NUM_PREC_RADIX", + ColumnValue::NO_NULLS, + 1,1,0, + DataType::INTEGER); +} + +void ODatabaseMetaDataResultSetMetaData::setProceduresMap() +{ + m_mColumns[7] = OColumn(OUString(),"REMARKS", + ColumnValue::NULLABLE, + 0,0,0, + DataType::VARCHAR); +} + +sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isSearchable( sal_Int32 column ) +{ + if(!m_mColumns.empty() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + return (*m_mColumnsIter).second.isSearchable(); + return true; +} + +sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isAutoIncrement( sal_Int32 column ) +{ + if(!m_mColumns.empty() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + return (*m_mColumnsIter).second.isAutoIncrement(); + return false; +} + +OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnServiceName( sal_Int32 /*column*/ ) +{ + return OUString(); +} + +OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getTableName( sal_Int32 column ) +{ + if(!m_mColumns.empty() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + return (*m_mColumnsIter).second.getTableName(); + return OUString(); +} + +OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getCatalogName( sal_Int32 /*column*/ ) +{ + return OUString(); +} + +OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnTypeName( sal_Int32 /*column*/ ) +{ + return OUString(); +} + + +sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isCaseSensitive( sal_Int32 column ) +{ + if(!m_mColumns.empty() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + return (*m_mColumnsIter).second.isCaseSensitive(); + return true; +} + + +OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getSchemaName( sal_Int32 /*column*/ ) +{ + return OUString(); +} + + +ObjectTypeEnum OAdoGroup::MapObjectType(sal_Int32 ObjType) +{ + ObjectTypeEnum eNumType= adPermObjTable; + switch(ObjType) + { + case PrivilegeObject::TABLE: + break; + case PrivilegeObject::VIEW: + eNumType = adPermObjView; + break; + case PrivilegeObject::COLUMN: + eNumType = adPermObjColumn; + break; + } + return eNumType; +} + +sal_Int32 OAdoGroup::MapRight(RightsEnum _eNum) +{ + sal_Int32 nRight = 0; + if(_eNum & adRightRead) + nRight |= Privilege::SELECT; + if(_eNum & adRightInsert) + nRight |= Privilege::INSERT; + if(_eNum & adRightUpdate) + nRight |= Privilege::UPDATE; + if(_eNum & adRightDelete) + nRight |= Privilege::DELETE; + if(_eNum & adRightReadDesign) + nRight |= Privilege::READ; + if(_eNum & adRightCreate) + nRight |= Privilege::CREATE; + if(_eNum & adRightWriteDesign) + nRight |= Privilege::ALTER; + if(_eNum & adRightReference) + nRight |= Privilege::REFERENCE; + if(_eNum & adRightDrop) + nRight |= Privilege::DROP; + + return nRight; +} + +RightsEnum OAdoGroup::Map2Right(sal_Int32 _eNum) +{ + sal_Int32 nRight = adRightNone; + if(_eNum & Privilege::SELECT) + nRight |= adRightRead; + + if(_eNum & Privilege::INSERT) + nRight |= adRightInsert; + + if(_eNum & Privilege::UPDATE) + nRight |= adRightUpdate; + + if(_eNum & Privilege::DELETE) + nRight |= adRightDelete; + + if(_eNum & Privilege::READ) + nRight |= adRightReadDesign; + + if(_eNum & Privilege::CREATE) + nRight |= adRightCreate; + + if(_eNum & Privilege::ALTER) + nRight |= adRightWriteDesign; + + if(_eNum & Privilege::REFERENCE) + nRight |= adRightReference; + + if(_eNum & Privilege::DROP) + nRight |= adRightDrop; + + return static_cast<RightsEnum>(nRight); +} + +void WpADOIndex::Create() +{ + pInterface.CoCreateInstance(ADOS::CLSID_ADOINDEX_25, nullptr, CLSCTX_INPROC_SERVER); +} + +void OAdoIndex::fillPropertyValues() +{ + if(m_aIndex.IsValid()) + { + m_Name = m_aIndex.get_Name(); + m_IsUnique = m_aIndex.get_Unique(); + m_IsPrimaryKeyIndex = m_aIndex.get_PrimaryKey(); + m_IsClustered = m_aIndex.get_Clustered(); + } +} + +void WpADOKey::Create() +{ + pInterface.CoCreateInstance(ADOS::CLSID_ADOKEY_25, nullptr, CLSCTX_INPROC_SERVER); +} + +void OAdoKey::fillPropertyValues() +{ + if(m_aKey.IsValid()) + { + m_aProps->m_Type = MapKeyRule(m_aKey.get_Type()); + m_Name = m_aKey.get_Name(); + m_aProps->m_ReferencedTable = m_aKey.get_RelatedTable(); + m_aProps->m_UpdateRule = MapRule(m_aKey.get_UpdateRule()); + m_aProps->m_DeleteRule = MapRule(m_aKey.get_DeleteRule()); + } +} + +sal_Int32 OAdoKey::MapRule(const RuleEnum& _eNum) +{ + sal_Int32 eNum = KeyRule::NO_ACTION; + switch(_eNum) + { + case adRICascade: + eNum = KeyRule::CASCADE; + break; + case adRISetNull: + eNum = KeyRule::SET_NULL; + break; + case adRINone: + eNum = KeyRule::NO_ACTION; + break; + case adRISetDefault: + eNum = KeyRule::SET_DEFAULT; + break; + } + return eNum; +} + +RuleEnum OAdoKey::Map2Rule(sal_Int32 _eNum) +{ + RuleEnum eNum = adRINone; + switch(_eNum) + { + case KeyRule::CASCADE: + eNum = adRICascade; + break; + case KeyRule::SET_NULL: + eNum = adRISetNull; + break; + case KeyRule::NO_ACTION: + eNum = adRINone; + break; + case KeyRule::SET_DEFAULT: + eNum = adRISetDefault; + break; + } + return eNum; +} + +sal_Int32 OAdoKey::MapKeyRule(const KeyTypeEnum& _eNum) +{ + sal_Int32 nKeyType = KeyType::PRIMARY; + switch(_eNum) + { + case adKeyPrimary: + nKeyType = KeyType::PRIMARY; + break; + case adKeyForeign: + nKeyType = KeyType::FOREIGN; + break; + case adKeyUnique: + nKeyType = KeyType::UNIQUE; + break; + } + return nKeyType; +} + +KeyTypeEnum OAdoKey::Map2KeyRule(sal_Int32 _eNum) +{ + KeyTypeEnum eNum( adKeyPrimary ); + switch(_eNum) + { + case KeyType::PRIMARY: + eNum = adKeyPrimary; + break; + case KeyType::FOREIGN: + eNum = adKeyForeign; + break; + case KeyType::UNIQUE: + eNum = adKeyUnique; + break; + default: + OSL_FAIL( "OAdoKey::Map2KeyRule: invalid key type!" ); + } + return eNum; +} + +void WpADOTable::Create() +{ + pInterface.CoCreateInstance(ADOS::CLSID_ADOTABLE_25, nullptr, CLSCTX_INPROC_SERVER); +} + +OUString WpADOCatalog::GetObjectOwner(std::u16string_view _rName, ObjectTypeEnum _eNum) +{ + OLEVariant _rVar; + _rVar.setNoArg(); + sal::systools::BStr aBSTR; + sal::systools::BStr sStr1(_rName); + pInterface->GetObjectOwner(sStr1, _eNum, _rVar, &aBSTR); + return OUString(aBSTR); +} + +void OAdoTable::fillPropertyValues() +{ + if(m_aTable.IsValid()) + { + m_Name = m_aTable.get_Name(); + m_Type = m_aTable.get_Type(); + { + WpADOCatalog aCat(m_aTable.get_ParentCatalog()); + if(aCat.IsValid()) + m_CatalogName = aCat.GetObjectOwner(m_aTable.get_Name(),adPermObjTable); + } + { + WpADOProperties aProps = m_aTable.get_Properties(); + if(aProps.IsValid()) + m_Description + = OTools::getValue(aProps, std::u16string_view(u"Description")).getString(); + } + } +} + +void WpADOUser::Create() +{ + pInterface.CoCreateInstance(ADOS::CLSID_ADOUSER_25, nullptr, CLSCTX_INPROC_SERVER); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/ADatabaseMetaDataResultSet.cxx b/connectivity/source/drivers/ado/ADatabaseMetaDataResultSet.cxx new file mode 100644 index 000000000..bb5bda634 --- /dev/null +++ b/connectivity/source/drivers/ado/ADatabaseMetaDataResultSet.cxx @@ -0,0 +1,1242 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <comphelper/sequence.hxx> +#include <ado/ADatabaseMetaDataResultSet.hxx> +#include <ado/ADatabaseMetaDataResultSetMetaData.hxx> +#include <com/sun/star/sdbc/ColumnSearch.hpp> +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <com/sun/star/sdbc/KeyRule.hpp> +#include <com/sun/star/sdbc/ProcedureResult.hpp> +#include <com/sun/star/sdbc/IndexType.hpp> +#include <comphelper/property.hxx> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/sdbc/ResultSetConcurrency.hpp> +#include <com/sun/star/sdbc/ResultSetType.hpp> +#include <com/sun/star/sdbc/FetchDirection.hpp> +#include <cppuhelper/typeprovider.hxx> +#include <comphelper/seqstream.hxx> +#include <connectivity/dbexception.hxx> +#include <rtl/ref.hxx> + +#include <oledb.h> + +using namespace dbtools; +using namespace connectivity::ado; +using namespace cppu; +using namespace ::comphelper; + +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; + + +ODatabaseMetaDataResultSet::ODatabaseMetaDataResultSet(ADORecordset* _pRecordSet) + :ODatabaseMetaDataResultSet_BASE(m_aMutex) + ,OPropertySetHelper(ODatabaseMetaDataResultSet_BASE::rBHelper) + ,m_pRecordSet(_pRecordSet) + ,m_nRowPos(0) + ,m_bWasNull(false) + ,m_bEOF(false) + ,m_bOnFirstAfterOpen(false) +{ + osl_atomic_increment( &m_refCount ); + m_aColMapping.push_back(-1); + if(_pRecordSet) + { + m_pRecordSet->AddRef(); + VARIANT_BOOL bIsAtBOF; + m_pRecordSet->get_BOF(&bIsAtBOF); + m_bOnFirstAfterOpen = bIsAtBOF != VARIANT_TRUE; + } + else + m_bOnFirstAfterOpen = false; + osl_atomic_decrement( &m_refCount ); + // allocBuffer(); +} + + +ODatabaseMetaDataResultSet::~ODatabaseMetaDataResultSet() +{ + if(m_pRecordSet) + m_pRecordSet->Release(); +} + +void ODatabaseMetaDataResultSet::disposing() +{ + OPropertySetHelper::disposing(); + + ::osl::MutexGuard aGuard(m_aMutex); + if(m_pRecordSet) + m_pRecordSet->Close(); + m_aStatement.clear(); + m_xMetaData.clear(); +} + +Any SAL_CALL ODatabaseMetaDataResultSet::queryInterface( const Type & rType ) +{ + Any aRet = OPropertySetHelper::queryInterface(rType); + return aRet.hasValue() ? aRet : ODatabaseMetaDataResultSet_BASE::queryInterface(rType); +} + +css::uno::Sequence< css::uno::Type > SAL_CALL ODatabaseMetaDataResultSet::getTypes( ) +{ + ::cppu::OTypeCollection aTypes( cppu::UnoType<css::beans::XMultiPropertySet>::get(), + cppu::UnoType<css::beans::XFastPropertySet>::get(), + cppu::UnoType<css::beans::XPropertySet>::get()); + + return ::comphelper::concatSequences(aTypes.getTypes(),ODatabaseMetaDataResultSet_BASE::getTypes()); +} + +void ODatabaseMetaDataResultSet::checkRecordSet() +{ + if(!m_pRecordSet) + throwFunctionSequenceException(*this); +} + + +sal_Int32 SAL_CALL ODatabaseMetaDataResultSet::findColumn( const OUString& columnName ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed ); + + + Reference< XResultSetMetaData > xMeta = getMetaData(); + sal_Int32 nLen = xMeta->getColumnCount(); + sal_Int32 i = 1; + for(;i<=nLen;++i) + { + if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) : + columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i))) + return i; + } + + ::dbtools::throwInvalidColumnException( columnName, *this ); + assert(false); + return 0; // Never reached +} +#define BLOCK_SIZE 256 + +Reference< css::io::XInputStream > SAL_CALL ODatabaseMetaDataResultSet::getBinaryStream( sal_Int32 columnIndex ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + checkRecordSet(); + + + columnIndex = mapColumn(columnIndex); + WpADOField aField = ADOS::getField(m_pRecordSet,columnIndex); + if((aField.GetAttributes() & adFldLong) == adFldLong) + { + //Copy the data only up to the Actual Size of Field. + sal_Int32 nSize = aField.GetActualSize(); + Sequence<sal_Int8> aData(nSize); + sal_Int32 index = 0; + while(index < nSize) + { + m_aValue = aField.GetChunk(BLOCK_SIZE); + if(m_aValue.isNull()) + break; + UCHAR chData; + for(LONG index2 = 0;index2 < BLOCK_SIZE;++index2) + { + HRESULT hr = ::SafeArrayGetElement(m_aValue.parray,&index2,&chData); + if(SUCCEEDED(hr)) + { + //Take BYTE by BYTE and advance Memory Location + aData.getArray()[index++] = chData; + } + else + break; + } + } + return index ? Reference< css::io::XInputStream >(new SequenceInputStream(aData)) : Reference< css::io::XInputStream >(); + } + // else we ask for a bytesequence + aField.get_Value(m_aValue); + if(m_aValue.isNull()) + return nullptr; + return new SequenceInputStream(m_aValue.getByteSequence()); +} + +Reference< css::io::XInputStream > SAL_CALL ODatabaseMetaDataResultSet::getCharacterStream( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getCharacterStream", *this ); + return nullptr; +} + + +sal_Bool SAL_CALL ODatabaseMetaDataResultSet::getBoolean( sal_Int32 columnIndex ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_aValueRange.empty() && columnIndex == 11 && (m_aValueRangeIter = m_aValueRange.find(columnIndex)) != m_aValueRange.end() ) + { + getValue(2); + if ( m_aValue.getInt16() != adCurrency ) + return false; + } + return getValue(columnIndex).getBool(); +} + + +sal_Int8 SAL_CALL ODatabaseMetaDataResultSet::getByte( sal_Int32 columnIndex ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + getValue(columnIndex); + + columnIndex = mapColumn(columnIndex); + + if(m_aValue.isNull()) + return 0; + if ( !m_aValueRange.empty() && (m_aValueRangeIter = m_aValueRange.find(columnIndex)) != m_aValueRange.end()) + return static_cast<sal_Int8>((*m_aValueRangeIter).second[m_aValue.getInt32()]); + else if(m_aStrValueRange.size() && (m_aStrValueRangeIter = m_aStrValueRange.find(columnIndex)) != m_aStrValueRange.end()) + return static_cast<sal_Int8>((*m_aStrValueRangeIter).second[m_aValue.getString()]); + + return m_aValue.getInt8(); +} + + +Sequence< sal_Int8 > SAL_CALL ODatabaseMetaDataResultSet::getBytes( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getByteSequence(); +} + + +css::util::Date SAL_CALL ODatabaseMetaDataResultSet::getDate( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getDate(); +} + + +double SAL_CALL ODatabaseMetaDataResultSet::getDouble( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getDouble(); +} + + +float SAL_CALL ODatabaseMetaDataResultSet::getFloat( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getFloat(); +} + + +sal_Int32 SAL_CALL ODatabaseMetaDataResultSet::getInt( sal_Int32 columnIndex ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + + getValue(columnIndex); + + columnIndex = mapColumn(columnIndex); + if(m_aValue.isNull()) + return 0; + + if(m_aValueRange.size() && (m_aValueRangeIter = m_aValueRange.find(columnIndex)) != m_aValueRange.end()) + return (*m_aValueRangeIter).second[m_aValue.getInt32()]; + else if(m_aStrValueRange.size() && (m_aStrValueRangeIter = m_aStrValueRange.find(columnIndex)) != m_aStrValueRange.end()) + return (*m_aStrValueRangeIter).second[m_aValue.getString()]; + + return m_aValue.getInt32(); +} + + +sal_Int32 SAL_CALL ODatabaseMetaDataResultSet::getRow( ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XResultSet::getRow", *this ); + return 0; +} + + +sal_Int64 SAL_CALL ODatabaseMetaDataResultSet::getLong( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getLong", *this ); + return sal_Int64(0); +} + + +Reference< XResultSetMetaData > SAL_CALL ODatabaseMetaDataResultSet::getMetaData( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + checkRecordSet(); + + + if(!m_xMetaData.is()) + m_xMetaData = new ODatabaseMetaDataResultSetMetaData(m_pRecordSet,this); + + return m_xMetaData; +} + +Reference< XArray > SAL_CALL ODatabaseMetaDataResultSet::getArray( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getRow", *this ); + return nullptr; +} + + +Reference< XClob > SAL_CALL ODatabaseMetaDataResultSet::getClob( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getRow", *this ); + return nullptr; +} + +Reference< XBlob > SAL_CALL ODatabaseMetaDataResultSet::getBlob( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getRow", *this ); + return nullptr; +} + + +Reference< XRef > SAL_CALL ODatabaseMetaDataResultSet::getRef( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getRow", *this ); + return nullptr; +} + + +Any SAL_CALL ODatabaseMetaDataResultSet::getObject( sal_Int32 columnIndex, const Reference< css::container::XNameAccess >& /*typeMap*/ ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + checkRecordSet(); + + + columnIndex = mapColumn(columnIndex); + return Any(); +} + + +sal_Int16 SAL_CALL ODatabaseMetaDataResultSet::getShort( sal_Int32 columnIndex ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + getValue(columnIndex); + + columnIndex = mapColumn(columnIndex); + if(m_aValue.isNull()) + return 0; + + if(m_aValueRange.size() && (m_aValueRangeIter = m_aValueRange.find(columnIndex)) != m_aValueRange.end()) + return static_cast<sal_Int16>((*m_aValueRangeIter).second[m_aValue.getInt32()]); + else if(m_aStrValueRange.size() && (m_aStrValueRangeIter = m_aStrValueRange.find(columnIndex)) != m_aStrValueRange.end()) + return static_cast<sal_Int16>((*m_aStrValueRangeIter).second[m_aValue.getString()]); + + return m_aValue.getInt16(); +} + + +OUString SAL_CALL ODatabaseMetaDataResultSet::getString( sal_Int32 columnIndex ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + getValue(columnIndex); + + + columnIndex = mapColumn(columnIndex); + if(m_aValue.isNull()) + return OUString(); + if(m_aIntValueRange.size() && (m_aIntValueRangeIter = m_aIntValueRange.find(columnIndex)) != m_aIntValueRange.end()) + return (*m_aIntValueRangeIter).second[m_aValue.getInt32()]; + + return m_aValue.getString(); +} + + +css::util::Time SAL_CALL ODatabaseMetaDataResultSet::getTime( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getTime(); +} + + +css::util::DateTime SAL_CALL ODatabaseMetaDataResultSet::getTimestamp( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getDateTime(); +} + + +sal_Bool SAL_CALL ODatabaseMetaDataResultSet::isAfterLast( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + checkRecordSet(); + + + VARIANT_BOOL bIsAtEOF; + m_pRecordSet->get_EOF(&bIsAtEOF); + return bIsAtEOF == VARIANT_TRUE; +} + +sal_Bool SAL_CALL ODatabaseMetaDataResultSet::isFirst( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + checkRecordSet(); + + + return m_nRowPos == 1; +} + +sal_Bool SAL_CALL ODatabaseMetaDataResultSet::isLast( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + checkRecordSet(); + + + return true; +} + +void SAL_CALL ODatabaseMetaDataResultSet::beforeFirst( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + checkRecordSet(); + + + if(first()) + previous(); +} + +void SAL_CALL ODatabaseMetaDataResultSet::afterLast( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + checkRecordSet(); + + + if(last()) + next(); + m_bEOF = true; +} + + +void SAL_CALL ODatabaseMetaDataResultSet::close( ) +{ + { + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + } + dispose(); +} + + +sal_Bool SAL_CALL ODatabaseMetaDataResultSet::first( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + + if(!m_pRecordSet) + return false; + + bool bRet = SUCCEEDED(m_pRecordSet->MoveFirst()); + if ( bRet ) + m_nRowPos = 1; + return bRet; +} + + +sal_Bool SAL_CALL ODatabaseMetaDataResultSet::last( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed ); + + + return m_pRecordSet && SUCCEEDED(m_pRecordSet->MoveLast()); +} + +sal_Bool SAL_CALL ODatabaseMetaDataResultSet::absolute( sal_Int32 row ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + + if(first()) + { + OLEVariant aEmpty; + aEmpty.setNoArg(); + bool bRet = SUCCEEDED(m_pRecordSet->Move(row,aEmpty)); + if(bRet) + m_nRowPos = row; + return bRet; + } + return false; +} + +sal_Bool SAL_CALL ODatabaseMetaDataResultSet::relative( sal_Int32 row ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + + if(!m_pRecordSet) + return false; + + OLEVariant aEmpty; + aEmpty.setNoArg(); + bool bRet = SUCCEEDED(m_pRecordSet->Move(row,aEmpty)); + if(bRet) + m_nRowPos += row; + return bRet; +} + +sal_Bool SAL_CALL ODatabaseMetaDataResultSet::previous( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + + if(!m_pRecordSet) + return false; + + bool bRet = SUCCEEDED(m_pRecordSet->MovePrevious()); + if(bRet) + --m_nRowPos; + return bRet; +} + +Reference< XInterface > SAL_CALL ODatabaseMetaDataResultSet::getStatement( ) +{ + return m_aStatement.get(); +} + + +sal_Bool SAL_CALL ODatabaseMetaDataResultSet::rowDeleted( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + checkRecordSet(); + + + sal_Int32 eRec; + m_pRecordSet->get_Status(&eRec); + return (RecordStatusEnum(eRec) & adRecDeleted) == adRecDeleted; +} + +sal_Bool SAL_CALL ODatabaseMetaDataResultSet::rowInserted( ) +{ ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + checkRecordSet(); + + + sal_Int32 eRec; + m_pRecordSet->get_Status(&eRec); + return (RecordStatusEnum(eRec) & adRecNew) == adRecNew; +} + +sal_Bool SAL_CALL ODatabaseMetaDataResultSet::rowUpdated( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + checkRecordSet(); + + + sal_Int32 eRec; + m_pRecordSet->get_Status(&eRec); + return (RecordStatusEnum(eRec) & adRecModified) == adRecModified; +} + + +sal_Bool SAL_CALL ODatabaseMetaDataResultSet::isBeforeFirst( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + + if(!m_pRecordSet) + return true; + + VARIANT_BOOL bIsAtBOF; + m_pRecordSet->get_BOF(&bIsAtBOF); + return bIsAtBOF == VARIANT_TRUE; +} + + +sal_Bool SAL_CALL ODatabaseMetaDataResultSet::next( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + + if(!m_pRecordSet) + return false; + + if(m_bOnFirstAfterOpen) + { + m_bOnFirstAfterOpen = false; + return true; + } + else + return SUCCEEDED(m_pRecordSet->MoveNext()); +} + + +sal_Bool SAL_CALL ODatabaseMetaDataResultSet::wasNull( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + checkRecordSet(); + + + return m_aValue.isNull(); +} + +void SAL_CALL ODatabaseMetaDataResultSet::refreshRow( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + checkRecordSet(); + + + m_pRecordSet->Resync(adAffectCurrent); +} + + +void SAL_CALL ODatabaseMetaDataResultSet::cancel( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + checkRecordSet(); + + + m_pRecordSet->Cancel(); +} + +void SAL_CALL ODatabaseMetaDataResultSet::clearWarnings( ) +{ +} + +Any SAL_CALL ODatabaseMetaDataResultSet::getWarnings( ) +{ + return Any(); +} + +sal_Int32 ODatabaseMetaDataResultSet::getResultSetConcurrency() +{ + return ResultSetConcurrency::READ_ONLY; +} + +sal_Int32 ODatabaseMetaDataResultSet::getResultSetType() +{ + return ResultSetType::FORWARD_ONLY; +} + +sal_Int32 ODatabaseMetaDataResultSet::getFetchDirection() +{ + return FetchDirection::FORWARD; +} + +sal_Int32 ODatabaseMetaDataResultSet::getFetchSize() const +{ + sal_Int32 nValue=-1; + if(m_pRecordSet) + m_pRecordSet->get_CacheSize(&nValue); + return nValue; +} + +OUString ODatabaseMetaDataResultSet::getCursorName() +{ + return OUString(); +} + + +void ODatabaseMetaDataResultSet::setFetchDirection(sal_Int32 /*_par0*/) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "ResultSet::FetchDirection", *this ); +} + +void ODatabaseMetaDataResultSet::setFetchSize(sal_Int32 _par0) +{ + if(m_pRecordSet) + m_pRecordSet->put_CacheSize(_par0); +} + +::cppu::IPropertyArrayHelper* ODatabaseMetaDataResultSet::createArrayHelper( ) const +{ + + 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_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_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 + } + } + }; +} + +::cppu::IPropertyArrayHelper & ODatabaseMetaDataResultSet::getInfoHelper() +{ + return *getArrayHelper(); +} + +sal_Bool ODatabaseMetaDataResultSet::convertFastPropertyValue( + Any & rConvertedValue, + Any & rOldValue, + sal_Int32 nHandle, + const Any& rValue ) +{ + switch(nHandle) + { + case PROPERTY_ID_CURSORNAME: + case PROPERTY_ID_RESULTSETCONCURRENCY: + case PROPERTY_ID_RESULTSETTYPE: + throw css::lang::IllegalArgumentException(); + case PROPERTY_ID_FETCHDIRECTION: + return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchDirection()); + case PROPERTY_ID_FETCHSIZE: + return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchSize()); + default: + ; + } + return false; +} + +void ODatabaseMetaDataResultSet::setFastPropertyValue_NoBroadcast( + sal_Int32 nHandle, + const Any& /*rValue*/ + ) +{ + switch(nHandle) + { + case PROPERTY_ID_CURSORNAME: + case PROPERTY_ID_RESULTSETCONCURRENCY: + case PROPERTY_ID_RESULTSETTYPE: + case PROPERTY_ID_FETCHDIRECTION: + case PROPERTY_ID_FETCHSIZE: + throw Exception("cannot set prop " + OUString::number(nHandle), nullptr); + default: + OSL_FAIL("setFastPropertyValue_NoBroadcast: Illegal handle value!"); + } +} + +void ODatabaseMetaDataResultSet::getFastPropertyValue( + Any& rValue, + sal_Int32 nHandle + ) const +{ + switch(nHandle) + { + case PROPERTY_ID_CURSORNAME: + rValue <<= getCursorName(); + break; + case PROPERTY_ID_RESULTSETCONCURRENCY: + rValue <<= getResultSetConcurrency(); + break; + case PROPERTY_ID_RESULTSETTYPE: + rValue <<= getResultSetType(); + break; + case PROPERTY_ID_FETCHDIRECTION: + rValue <<= getFetchDirection(); + break; + case PROPERTY_ID_FETCHSIZE: + rValue <<= getFetchSize(); + break; + } +} + +void ODatabaseMetaDataResultSet::setProceduresMap() +{ + for(sal_Int32 i=1;i<4;i++) + m_aColMapping.push_back(i); + m_aColMapping.push_back(5); + m_aColMapping.push_back(7); + m_aColMapping.push_back(8); + m_aColMapping.push_back(6); + m_aColMapping.push_back(4); + + ::std::map<sal_Int32,sal_Int32> aMap + { + {DB_PT_UNKNOWN, ProcedureResult::UNKNOWN}, + {DB_PT_PROCEDURE, ProcedureResult::NONE}, + {DB_PT_FUNCTION, ProcedureResult::RETURN} + }; + m_aValueRange[4] = aMap; + + rtl::Reference<ODatabaseMetaDataResultSetMetaData> pMetaData = new ODatabaseMetaDataResultSetMetaData(m_pRecordSet,this); + pMetaData->setProceduresMap(); + m_xMetaData = pMetaData; +} + +void ODatabaseMetaDataResultSet::setCatalogsMap() +{ + m_aColMapping.push_back(1); + + m_xMetaData = new ODatabaseMetaDataResultSetMetaData(m_pRecordSet,this); +} + +void ODatabaseMetaDataResultSet::setSchemasMap() +{ + m_aColMapping.push_back(2); + + m_xMetaData = new ODatabaseMetaDataResultSetMetaData(m_pRecordSet,this); +} + +void ODatabaseMetaDataResultSet::setColumnPrivilegesMap() +{ + + m_aColMapping.push_back(3); + m_aColMapping.push_back(4); + m_aColMapping.push_back(5); + m_aColMapping.push_back(6); + m_aColMapping.push_back(2); + m_aColMapping.push_back(9); + m_aColMapping.push_back(10); + + rtl::Reference<ODatabaseMetaDataResultSetMetaData> pMetaData = new ODatabaseMetaDataResultSetMetaData(m_pRecordSet,this); + pMetaData->setColumnPrivilegesMap(); + m_xMetaData = pMetaData; +} + +void ODatabaseMetaDataResultSet::setColumnsMap() +{ + + for(sal_Int32 i=1;i<5;++i) + m_aColMapping.push_back(i); + + m_aColMapping.push_back(12); + m_aColMapping.push_back(12); // is used as TYPE_NAME + + m_aColMapping.push_back(14); + m_aColMapping.push_back(6); + m_aColMapping.push_back(17); + m_aColMapping.push_back(18); + + m_aColMapping.push_back(11); + m_aColMapping.push_back(29); + m_aColMapping.push_back(9); + m_aColMapping.push_back(18); + m_aColMapping.push_back(18); + + m_aColMapping.push_back(15); + m_aColMapping.push_back(7); + m_aColMapping.push_back(11); + + ::std::map<sal_Int32,sal_Int32> aMap { + {adEmpty, ADOS::MapADOType2Jdbc(adEmpty)}, + {adTinyInt, ADOS::MapADOType2Jdbc(adTinyInt)}, + {adSmallInt, ADOS::MapADOType2Jdbc(adSmallInt)}, + {adInteger, ADOS::MapADOType2Jdbc(adInteger)}, + {adBigInt, ADOS::MapADOType2Jdbc(adBigInt)}, + {adUnsignedTinyInt, ADOS::MapADOType2Jdbc(adUnsignedTinyInt)}, + {adUnsignedSmallInt, ADOS::MapADOType2Jdbc(adUnsignedSmallInt)}, + {adUnsignedInt, ADOS::MapADOType2Jdbc(adUnsignedInt)}, + {adUnsignedBigInt, ADOS::MapADOType2Jdbc(adUnsignedBigInt)}, + {adSingle, ADOS::MapADOType2Jdbc(adSingle)}, + {adDouble, ADOS::MapADOType2Jdbc(adDouble)}, + {adCurrency, ADOS::MapADOType2Jdbc(adCurrency)}, + {adDecimal, ADOS::MapADOType2Jdbc(adDecimal)}, + {adNumeric, ADOS::MapADOType2Jdbc(adNumeric)}, + {adBoolean, ADOS::MapADOType2Jdbc(adBoolean)}, + {adError, ADOS::MapADOType2Jdbc(adError)}, + {adUserDefined, ADOS::MapADOType2Jdbc(adUserDefined)}, + {adVariant, ADOS::MapADOType2Jdbc(adVariant)}, + {adIDispatch, ADOS::MapADOType2Jdbc(adIDispatch)}, + {adIUnknown, ADOS::MapADOType2Jdbc(adIUnknown)}, + {adGUID, ADOS::MapADOType2Jdbc(adGUID)}, + {adDate, ADOS::MapADOType2Jdbc(adDate)}, + {adDBDate, ADOS::MapADOType2Jdbc(adDBDate)}, + {adDBTime, ADOS::MapADOType2Jdbc(adDBTime)}, + {adDBTimeStamp, ADOS::MapADOType2Jdbc(adDBTimeStamp)}, + {adBSTR, ADOS::MapADOType2Jdbc(adBSTR)}, + {adChar, ADOS::MapADOType2Jdbc(adChar)}, + {adVarChar, ADOS::MapADOType2Jdbc(adVarChar)}, + {adLongVarChar, ADOS::MapADOType2Jdbc(adLongVarChar)}, + {adWChar, ADOS::MapADOType2Jdbc(adWChar)}, + {adVarWChar, ADOS::MapADOType2Jdbc(adVarWChar)}, + {adLongVarWChar, ADOS::MapADOType2Jdbc(adLongVarWChar)}, + {adBinary, ADOS::MapADOType2Jdbc(adBinary)}, + {adVarBinary, ADOS::MapADOType2Jdbc(adVarBinary)}, + {adLongVarBinary, ADOS::MapADOType2Jdbc(adLongVarBinary)}, + {adChapter, ADOS::MapADOType2Jdbc(adChapter)}, + {adFileTime, ADOS::MapADOType2Jdbc(adFileTime)}, + {adPropVariant, ADOS::MapADOType2Jdbc(adPropVariant)}, + {adVarNumeric, ADOS::MapADOType2Jdbc(adVarNumeric)} + }; + m_aValueRange[12] = aMap; + + std::map< sal_Int32,OUString> aMap2 { + {0, "YES"}, + {1, "NO"} + }; + m_aIntValueRange[18] = aMap2; + + rtl::Reference<ODatabaseMetaDataResultSetMetaData> pMetaData = new ODatabaseMetaDataResultSetMetaData(m_pRecordSet,this); + pMetaData->setColumnsMap(); + m_xMetaData = pMetaData; +} + +void ODatabaseMetaDataResultSet::setTablesMap() +{ + + for(sal_Int32 i=1;i<5;i++) + m_aColMapping.push_back(i); + m_aColMapping.push_back(6); + + rtl::Reference<ODatabaseMetaDataResultSetMetaData> pMetaData = new ODatabaseMetaDataResultSetMetaData(m_pRecordSet,this); + pMetaData->setTablesMap(); + m_xMetaData = pMetaData; +} + +void ODatabaseMetaDataResultSet::setProcedureColumnsMap() +{ + + for(sal_Int32 i=1;i<5;i++) + m_aColMapping.push_back(i); + m_aColMapping.push_back(6); + m_aColMapping.push_back(10); + m_aColMapping.push_back(16); + m_aColMapping.push_back(13); + m_aColMapping.push_back(11); + m_aColMapping.push_back(12); + + m_aColMapping.push_back(9); + m_aColMapping.push_back(14); + + ::std::map<sal_Int32,sal_Int32> aMap + { + {DBTYPE_EMPTY, DataType::SQLNULL}, + {DBTYPE_NULL, DataType::SQLNULL}, + {DBTYPE_I2, DataType::SMALLINT}, + {DBTYPE_I4, DataType::INTEGER}, + {DBTYPE_R4, DataType::FLOAT}, + {DBTYPE_R8, DataType::DOUBLE}, + {DBTYPE_CY, DataType::BIGINT}, + {DBTYPE_DATE, DataType::DATE}, + {DBTYPE_BSTR, DataType::VARCHAR}, + {DBTYPE_IDISPATCH, DataType::OBJECT}, + {DBTYPE_ERROR, DataType::OTHER}, + {DBTYPE_BOOL, DataType::BIT}, + {DBTYPE_VARIANT, DataType::STRUCT}, + {DBTYPE_IUNKNOWN, DataType::OTHER}, + {DBTYPE_DECIMAL, DataType::DECIMAL}, + {DBTYPE_UI1, DataType::TINYINT}, + {DBTYPE_ARRAY, DataType::ARRAY}, + {DBTYPE_BYREF, DataType::REF}, + {DBTYPE_I1, DataType::CHAR}, + {DBTYPE_UI2, DataType::SMALLINT}, + {DBTYPE_UI4, DataType::INTEGER}, + + // aMap[The] = ; + // aMap[in] = ; + {DBTYPE_I8, DataType::BIGINT}, + {DBTYPE_UI8, DataType::BIGINT}, + {DBTYPE_GUID, DataType::OTHER}, + {DBTYPE_VECTOR, DataType::OTHER}, + {DBTYPE_FILETIME, DataType::OTHER}, + {DBTYPE_RESERVED, DataType::OTHER}, + + // aMap[The] = ; + {DBTYPE_BYTES, DataType::VARBINARY}, + {DBTYPE_STR, DataType::LONGVARCHAR}, + {DBTYPE_WSTR, DataType::LONGVARCHAR}, + {DBTYPE_NUMERIC, DataType::NUMERIC}, + {DBTYPE_UDT, DataType::OTHER}, + {DBTYPE_DBDATE, DataType::DATE}, + {DBTYPE_DBTIME, DataType::TIME}, + {DBTYPE_DBTIMESTAMP, DataType::TIMESTAMP}, + {DBTYPE_HCHAPTER, DataType::OTHER}, + {DBTYPE_PROPVARIANT, DataType::OTHER}, + {DBTYPE_VARNUMERIC, DataType::NUMERIC} + }; + + m_aValueRange[10] = aMap; + + rtl::Reference<ODatabaseMetaDataResultSetMetaData> pMetaData = new ODatabaseMetaDataResultSetMetaData(m_pRecordSet,this); + pMetaData->setProcedureColumnsMap(); + m_xMetaData = pMetaData; +} + +void ODatabaseMetaDataResultSet::setPrimaryKeysMap() +{ + + sal_Int32 i=1; + for(;i<5;i++) + m_aColMapping.push_back(i); + m_aColMapping.push_back(7); + m_aColMapping.push_back(8); + + rtl::Reference<ODatabaseMetaDataResultSetMetaData> pMetaData = new ODatabaseMetaDataResultSetMetaData(m_pRecordSet,this); + pMetaData->setProcedureColumnsMap(); + m_xMetaData = pMetaData; +} + +void ODatabaseMetaDataResultSet::setIndexInfoMap() +{ + + sal_Int32 i=1; + for(;i<4;i++) + m_aColMapping.push_back(i); + m_aColMapping.push_back(8); + m_aColMapping.push_back(4); + m_aColMapping.push_back(6); + m_aColMapping.push_back(10); + m_aColMapping.push_back(17); + m_aColMapping.push_back(18); + m_aColMapping.push_back(21); + m_aColMapping.push_back(22); + m_aColMapping.push_back(23); + m_aColMapping.push_back(24); + + ::std::map<sal_Int32,sal_Int32> aMap + { + { DBPROPVAL_IT_HASH, IndexType::HASHED }, + { DBPROPVAL_IT_CONTENT, IndexType::OTHER }, + { DBPROPVAL_IT_OTHER, IndexType::OTHER }, + { DBPROPVAL_IT_BTREE, IndexType::OTHER } + }; + + m_aValueRange[10] = aMap; + + ::std::map<sal_Int32,sal_Int32> aMap2 + { + { 0, 1 }, + { 1, 0 } + }; + m_aValueRange[8] = aMap2; + + std::map< sal_Int32,OUString> aMap3 + { + { 0, "" }, + { DB_COLLATION_ASC, "A" }, + { DB_COLLATION_DESC, "D" } + }; + + m_aIntValueRange[21] = aMap3; + + rtl::Reference<ODatabaseMetaDataResultSetMetaData> pMetaData = new ODatabaseMetaDataResultSetMetaData(m_pRecordSet,this); + pMetaData->setIndexInfoMap(); + m_xMetaData = pMetaData; +} + +void ODatabaseMetaDataResultSet::setTablePrivilegesMap() +{ + + sal_Int32 i=3; + for(;i<6;i++) + m_aColMapping.push_back(i); + m_aColMapping.push_back(1); + m_aColMapping.push_back(2); + m_aColMapping.push_back(6); + m_aColMapping.push_back(7); + + std::map< sal_Int32,OUString> aMap + { + { 0, "YES" }, + { 1, "NO" } + }; + m_aIntValueRange[7] = aMap; + + + rtl::Reference<ODatabaseMetaDataResultSetMetaData> pMetaData = new ODatabaseMetaDataResultSetMetaData(m_pRecordSet,this); + pMetaData->setTablePrivilegesMap(); + m_xMetaData = pMetaData; +} + +void ODatabaseMetaDataResultSet::setCrossReferenceMap() +{ + + sal_Int32 i=1; + for(;i<5;i++) + m_aColMapping.push_back(i); + for(i=7;i<11;i++) + m_aColMapping.push_back(i); + + m_aColMapping.push_back(13); + m_aColMapping.push_back(14); + m_aColMapping.push_back(15); + m_aColMapping.push_back(17); + m_aColMapping.push_back(16); + m_aColMapping.push_back(18); + + std::map< OUString,sal_Int32> aMap + { + { "CASCADE", KeyRule::CASCADE }, + { "RESTRICT", KeyRule::RESTRICT }, + { "SET NULL", KeyRule::SET_NULL }, + { "SET DEFAULT", KeyRule::SET_DEFAULT }, + { "NO ACTION", KeyRule::NO_ACTION } + }; + + m_aStrValueRange[14] = aMap; + m_aStrValueRange[15] = aMap; + + rtl::Reference<ODatabaseMetaDataResultSetMetaData> pMetaData = new ODatabaseMetaDataResultSetMetaData(m_pRecordSet,this); + pMetaData->setCrossReferenceMap(); + m_xMetaData = pMetaData; +} + +void ODatabaseMetaDataResultSet::setTypeInfoMap(bool _bJetEngine) +{ + sal_Int32 i=1; + for(;i<19;i++) + m_aColMapping.push_back(i); + + std::map< OUString,sal_Int32> aMap1 { { OUString(), 10 } }; + + m_aStrValueRange[18] = aMap1; + + ::std::map<sal_Int32,sal_Int32> aMap + { + {adEmpty, ADOS::MapADOType2Jdbc(adEmpty)}, + {adTinyInt, ADOS::MapADOType2Jdbc(adTinyInt)}, + {adSmallInt, ADOS::MapADOType2Jdbc(adSmallInt)}, + {adInteger, ADOS::MapADOType2Jdbc(adInteger)}, + {adBigInt, ADOS::MapADOType2Jdbc(adBigInt)}, + {adUnsignedTinyInt, ADOS::MapADOType2Jdbc(adUnsignedTinyInt)}, + {adUnsignedSmallInt, ADOS::MapADOType2Jdbc(adUnsignedSmallInt)}, + {adUnsignedInt, ADOS::MapADOType2Jdbc(adUnsignedInt)}, + {adUnsignedBigInt, ADOS::MapADOType2Jdbc(adUnsignedBigInt)}, + {adSingle, ADOS::MapADOType2Jdbc(adSingle)}, + {adDouble, ADOS::MapADOType2Jdbc(adDouble)}, + {adCurrency, ADOS::MapADOType2Jdbc(adCurrency)}, + {adDecimal, ADOS::MapADOType2Jdbc(adDecimal)}, + {adNumeric, ADOS::MapADOType2Jdbc(adNumeric)}, + {adBoolean, ADOS::MapADOType2Jdbc(adBoolean)}, + {adError, ADOS::MapADOType2Jdbc(adError)}, + {adUserDefined, ADOS::MapADOType2Jdbc(adUserDefined)}, + {adVariant, ADOS::MapADOType2Jdbc(adVariant)}, + {adIDispatch, ADOS::MapADOType2Jdbc(adIDispatch)}, + {adIUnknown, ADOS::MapADOType2Jdbc(adIUnknown)}, + {adGUID, ADOS::MapADOType2Jdbc(adGUID)}, + {adDate, ADOS::MapADOType2Jdbc(_bJetEngine?adDBTimeStamp:adDate)}, + {adDBDate, ADOS::MapADOType2Jdbc(adDBDate)}, + {adDBTime, ADOS::MapADOType2Jdbc(adDBTime)}, + {adDBTimeStamp, ADOS::MapADOType2Jdbc(adDBTimeStamp)}, + {adBSTR, ADOS::MapADOType2Jdbc(adBSTR)}, + {adChar, ADOS::MapADOType2Jdbc(adChar)}, + {adVarChar, ADOS::MapADOType2Jdbc(adVarChar)}, + {adLongVarChar, ADOS::MapADOType2Jdbc(adLongVarChar)}, + {adWChar, ADOS::MapADOType2Jdbc(adWChar)}, + {adVarWChar, ADOS::MapADOType2Jdbc(adVarWChar)}, + {adLongVarWChar, ADOS::MapADOType2Jdbc(adLongVarWChar)}, + {adBinary, ADOS::MapADOType2Jdbc(adBinary)}, + {adVarBinary, ADOS::MapADOType2Jdbc(adVarBinary)}, + {adLongVarBinary, ADOS::MapADOType2Jdbc(adLongVarBinary)}, + {adChapter, ADOS::MapADOType2Jdbc(adChapter)}, + {adFileTime, ADOS::MapADOType2Jdbc(adFileTime)}, + {adPropVariant, ADOS::MapADOType2Jdbc(adPropVariant)}, + {adVarNumeric, ADOS::MapADOType2Jdbc(adVarNumeric)} +// {adArray, ADOS::MapADOType2Jdbc(adArray)} + }; + + m_aValueRange[2] = aMap; + + ::std::map<sal_Int32,sal_Int32> aColumnValueMapping + { + { VARIANT_FALSE, ColumnValue::NO_NULLS }, + { VARIANT_TRUE, ColumnValue::NULLABLE } + }; + m_aValueRange[7] = aColumnValueMapping; + + // now adjust the column mapping + // OJ 24.01.2002 96860 + ::std::map<sal_Int32,sal_Int32> aSearchMapping + { + { DB_UNSEARCHABLE, ColumnSearch::NONE }, + { DB_LIKE_ONLY, ColumnSearch::CHAR }, + { DB_ALL_EXCEPT_LIKE, ColumnSearch::BASIC }, + { DB_SEARCHABLE, ColumnSearch::FULL } + }; + + m_aValueRange[9] = aSearchMapping; + + ::std::map<sal_Int32,sal_Int32> aCurrencyMapping; + m_aValueRange[11] = aCurrencyMapping; + + rtl::Reference<ODatabaseMetaDataResultSetMetaData> pMetaData = new ODatabaseMetaDataResultSetMetaData(m_pRecordSet,this); + pMetaData->setTypeInfoMap(); + m_xMetaData = pMetaData; +} + +void SAL_CALL ODatabaseMetaDataResultSet::acquire() noexcept +{ + ODatabaseMetaDataResultSet_BASE::acquire(); +} + +void SAL_CALL ODatabaseMetaDataResultSet::release() noexcept +{ + ODatabaseMetaDataResultSet_BASE::release(); +} + +css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL ODatabaseMetaDataResultSet::getPropertySetInfo( ) +{ + return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper()); +} + +OLEVariant ODatabaseMetaDataResultSet::getValue(sal_Int32 columnIndex ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + + checkRecordSet(); + + WpADOField aField = ADOS::getField(m_pRecordSet,columnIndex); + aField.get_Value(m_aValue); + return m_aValue; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/ADatabaseMetaDataResultSetMetaData.cxx b/connectivity/source/drivers/ado/ADatabaseMetaDataResultSetMetaData.cxx new file mode 100644 index 000000000..3fa13d06b --- /dev/null +++ b/connectivity/source/drivers/ado/ADatabaseMetaDataResultSetMetaData.cxx @@ -0,0 +1,210 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/ADatabaseMetaDataResultSetMetaData.hxx> +#include <ado/Awrapado.hxx> +#include <connectivity/dbexception.hxx> + +using namespace connectivity; +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; + +ODatabaseMetaDataResultSetMetaData::~ODatabaseMetaDataResultSetMetaData() +{ + if (m_pRecordSet) + m_pRecordSet->Release(); +} + +sal_Int32 SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnDisplaySize(sal_Int32 column) +{ + sal_Int32 nSize = 0; + if (m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + nSize = (*m_mColumnsIter).second.getColumnDisplaySize(); + else if (m_pRecordSet) + { + WpADOField aField = ADOS::getField(m_pRecordSet, m_vMapping[column]); + if (aField.IsValid()) + nSize = aField.GetActualSize(); + } + return nSize; +} + +sal_Int32 SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnType(sal_Int32 column) +{ + sal_Int32 nType = 0; + if (m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + nType = (*m_mColumnsIter).second.getColumnType(); + else if (m_pRecordSet) + { + WpADOField aField = ADOS::getField(m_pRecordSet, m_vMapping[column]); + nType = ADOS::MapADOType2Jdbc(aField.GetADOType()); + } + return nType; +} + +sal_Int32 SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnCount() +{ + if (!m_pRecordSet) + return 0; + if (m_nColCount != -1) + return m_nColCount; + + if (m_vMapping.size()) + return m_mColumns.size(); + + WpOLEAppendCollection<ADOFields, WpADOField> aFields; + m_pRecordSet->get_Fields(&aFields); + m_nColCount = aFields.GetItemCount(); + return m_nColCount; +} + +OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnName(sal_Int32 column) +{ + if (m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + return (*m_mColumnsIter).second.getColumnName(); + if (!m_pRecordSet) + return OUString(); + WpADOField aField = ADOS::getField(m_pRecordSet, m_vMapping[column]); + if (aField.IsValid()) + return aField.GetName(); + + return OUString(); +} + +OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnLabel(sal_Int32 column) +{ + if (m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + return (*m_mColumnsIter).second.getColumnLabel(); + return getColumnName(column); +} + +sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isCurrency(sal_Int32 column) +{ + if (m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + return (*m_mColumnsIter).second.isCurrency(); + if (!m_pRecordSet) + return false; + WpADOField aField = ADOS::getField(m_pRecordSet, m_vMapping[column]); + if (aField.IsValid()) + { + return (aField.GetAttributes() & adFldFixed) == adFldFixed; + } + return false; +} + +sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isSigned(sal_Int32 column) +{ + if (m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + return (*m_mColumnsIter).second.isSigned(); + if (!m_pRecordSet) + return false; + WpADOField aField = ADOS::getField(m_pRecordSet, m_vMapping[column]); + if (aField.IsValid()) + { + return (aField.GetAttributes() & adFldNegativeScale) == adFldNegativeScale; + } + return false; +} + +sal_Int32 SAL_CALL ODatabaseMetaDataResultSetMetaData::getPrecision(sal_Int32 column) +{ + if (m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + return (*m_mColumnsIter).second.getPrecision(); + if (!m_pRecordSet) + return 0; + WpADOField aField = ADOS::getField(m_pRecordSet, m_vMapping[column]); + if (aField.IsValid()) + return aField.GetPrecision(); + return 0; +} + +sal_Int32 SAL_CALL ODatabaseMetaDataResultSetMetaData::getScale(sal_Int32 column) +{ + if (m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + return (*m_mColumnsIter).second.getScale(); + + if (!m_pRecordSet) + return 0; + + WpADOField aField = ADOS::getField(m_pRecordSet, m_vMapping[column]); + if (aField.IsValid()) + return aField.GetNumericScale(); + return 0; +} + +sal_Int32 SAL_CALL ODatabaseMetaDataResultSetMetaData::isNullable(sal_Int32 column) +{ + if (m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + return (*m_mColumnsIter).second.isNullable(); + + if (!m_pRecordSet) + return sal_Int32(false); + + WpADOField aField = ADOS::getField(m_pRecordSet, m_vMapping[column]); + if (aField.IsValid()) + { + return sal_Int32((aField.GetAttributes() & adFldIsNullable) == adFldIsNullable); + } + return sal_Int32(false); +} + +sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isReadOnly(sal_Int32 column) +{ + if (m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + return (*m_mColumnsIter).second.isReadOnly(); + + if (!m_pRecordSet) + return false; + + WpADOField aField = ADOS::getField(m_pRecordSet, m_vMapping[column]); + if (aField.IsValid()) + { + // return (aField.GetStatus() & adFieldReadOnly) == adFieldReadOnly; + } + return false; +} + +sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isDefinitelyWritable(sal_Int32 column) +{ + if (m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + return (*m_mColumnsIter).second.isDefinitelyWritable(); + + if (!m_pRecordSet) + return false; + + WpADOField aField = ADOS::getField(m_pRecordSet, m_vMapping[column]); + if (aField.IsValid()) + { + return (aField.GetAttributes() & adFldUpdatable) == adFldUpdatable; + } + return false; + ; +} + +sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isWritable(sal_Int32 column) +{ + if (m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end()) + return (*m_mColumnsIter).second.isWritable(); + return isDefinitelyWritable(column); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/ADriver.cxx b/connectivity/source/drivers/ado/ADriver.cxx new file mode 100644 index 000000000..6568f7a1e --- /dev/null +++ b/connectivity/source/drivers/ado/ADriver.cxx @@ -0,0 +1,250 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/ADriver.hxx> +#include <ado/AConnection.hxx> +#include <ado/Awrapadox.hxx> +#include <ado/ACatalog.hxx> +#include <ado/Awrapado.hxx> +#include <ado/adoimp.hxx> +#include <com/sun/star/lang/DisposedException.hpp> +#include <comphelper/servicehelper.hxx> +#include <connectivity/dbexception.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <o3tl/safeCoInitUninit.hxx> +#include <rtl/ref.hxx> +#include <strings.hrc> +#include <objbase.h> + +#include <resource/sharedresources.hxx> + +using namespace connectivity; +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::sdbcx; + + +ODriver::ODriver(const css::uno::Reference< css::uno::XComponentContext >& _xORB) + : ODriver_BASE(m_aMutex) + ,m_xContext(_xORB) + ,mnNbCallCoInitializeExForReinit(0) +{ + o3tl::safeCoInitializeEx(COINIT_APARTMENTTHREADED, mnNbCallCoInitializeExForReinit); +} + +ODriver::~ODriver() +{ + o3tl::safeCoUninitializeReinit(COINIT_MULTITHREADED, mnNbCallCoInitializeExForReinit); +} + +void ODriver::disposing() +{ + ::osl::MutexGuard aGuard(m_aMutex); + + + for (auto& rxConnection : m_xConnections) + { + Reference< XComponent > xComp(rxConnection.get(), UNO_QUERY); + if (xComp.is()) + xComp->dispose(); + } + m_xConnections.clear(); + + ODriver_BASE::disposing(); +} +// static ServiceInfo + +OUString ODriver::getImplementationName( ) +{ + return "com.sun.star.comp.sdbc.ado.ODriver"; +} + +Sequence< OUString > ODriver::getSupportedServiceNames( ) +{ + return { "com.sun.star.sdbc.Driver", "com.sun.star.sdbcx.Driver" }; +} + +sal_Bool SAL_CALL ODriver::supportsService( const OUString& _rServiceName ) +{ + return cppu::supportsService(this, _rServiceName); +} + +Reference< XConnection > SAL_CALL ODriver::connect( const OUString& url, const Sequence< PropertyValue >& info ) +{ + if ( ! acceptsURL(url) ) + return nullptr; + + // we need to wrap the connection as the construct call might throw + rtl::Reference<OConnection> pCon(new OConnection(this)); + pCon->construct(url,info); + OConnection* pPtr = pCon.get(); + m_xConnections.push_back(WeakReferenceHelper(*pPtr)); + + return pCon; +} + +sal_Bool SAL_CALL ODriver::acceptsURL( const OUString& url ) +{ + return url.startsWith("sdbc:ado:"); +} + +void ODriver::impl_checkURL_throw(const OUString& _sUrl) +{ + if ( !acceptsURL(_sUrl) ) + { + SharedResources aResources; + const OUString sMessage = aResources.getResourceString(STR_URI_SYNTAX_ERROR); + ::dbtools::throwGenericSQLException(sMessage ,*this); + } // if ( !acceptsURL(_sUrl) ) +} + +Sequence< DriverPropertyInfo > SAL_CALL ODriver::getPropertyInfo( const OUString& url, const Sequence< PropertyValue >& /*info*/ ) +{ + impl_checkURL_throw(url); + if ( acceptsURL(url) ) + { + Sequence< OUString > aBooleanValues{ "false", "true" }; + + return + { + { + "IgnoreDriverPrivileges", + "Ignore the privileges from the database driver.", + false, + "false", + aBooleanValues + }, + { + "EscapeDateTime", + "Escape date time format.", + false, + "true", + aBooleanValues + }, + { + "TypeInfoSettings", + "Defines how the type info of the database metadata should be manipulated.", + false, + {}, + {} + } + }; + } + return Sequence< DriverPropertyInfo >(); +} + +sal_Int32 SAL_CALL ODriver::getMajorVersion( ) +{ + return 1; +} + +sal_Int32 SAL_CALL ODriver::getMinorVersion( ) +{ + return 0; +} + +// XDataDefinitionSupplier +Reference< XTablesSupplier > SAL_CALL ODriver::getDataDefinitionByConnection( const Reference< css::sdbc::XConnection >& connection ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if (ODriver_BASE::rBHelper.bDisposed) + throw DisposedException(); + + OConnection* pConnection = nullptr; + Reference< css::lang::XUnoTunnel> xTunnel(connection,UNO_QUERY); + if (auto pSearchConnection = comphelper::getFromUnoTunnel<OConnection>(xTunnel)) + { + auto foundConnection = std::any_of(m_xConnections.begin(), m_xConnections.end(), + [&pSearchConnection](const css::uno::WeakReferenceHelper& rxConnection) { + return static_cast<OConnection*>(Reference< XConnection >::query(rxConnection.get()).get()) == pSearchConnection; }); + if (foundConnection) + pConnection = pSearchConnection; + } + + Reference< XTablesSupplier > xTab; + if(pConnection) + { + WpADOCatalog aCatalog; + aCatalog.Create(); + if(aCatalog.IsValid()) + { + aCatalog.putref_ActiveConnection(pConnection->getConnection()); + rtl::Reference<OCatalog> pCatalog = new OCatalog(aCatalog,pConnection); + xTab = pCatalog; + pConnection->setCatalog(xTab); + pConnection->setCatalog(pCatalog.get()); + } + } + return xTab; +} + +Reference< XTablesSupplier > SAL_CALL ODriver::getDataDefinitionByURL( const OUString& url, const Sequence< PropertyValue >& info ) +{ + impl_checkURL_throw(url); + return getDataDefinitionByConnection(connect(url,info)); +} + + +void ADOS::ThrowException(ADOConnection* _pAdoCon,const Reference< XInterface >& _xInterface) +{ + sal::systools::COMReference<ADOErrors> pErrors; + _pAdoCon->get_Errors(&pErrors); + if(!pErrors) + return; // no error found + + // read all noted errors and issue them + sal_Int32 nLen; + pErrors->get_Count(&nLen); + if (nLen) + { + SQLException aException; + aException.ErrorCode = 1000; + for (sal_Int32 i = nLen-1; i>=0; --i) + { + WpADOError aErr; + pErrors->get_Item(OLEVariant(i),&aErr); + OSL_ENSURE(aErr,"No error in collection found! BAD!"); + if(aErr) + { + if(i==nLen-1) + aException = SQLException(aErr.GetDescription(),_xInterface,aErr.GetSQLState(),aErr.GetNumber(),Any()); + else + { + SQLException aTemp(aErr.GetDescription(), + _xInterface,aErr.GetSQLState(),aErr.GetNumber(),Any(aException)); + aTemp.NextException <<= aException; + aException = aTemp; + } + } + } + pErrors->Clear(); + throw aException; + } +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +connectivity_ado_ODriver_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new ODriver(context)); +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AGroup.cxx b/connectivity/source/drivers/ado/AGroup.cxx new file mode 100644 index 000000000..a347fb96d --- /dev/null +++ b/connectivity/source/drivers/ado/AGroup.cxx @@ -0,0 +1,142 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <ado/AGroup.hxx> +#include <ado/AUsers.hxx> +#include <comphelper/servicehelper.hxx> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <ado/AConnection.hxx> +#include <TConnection.hxx> + +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::sdbcx; + + +void WpADOGroup::Create() +{ + pInterface.CoCreateInstance(ADOS::CLSID_ADOGROUP_25, nullptr, CLSCTX_INPROC_SERVER); +} + +OAdoGroup::OAdoGroup(OCatalog* _pParent,bool _bCase, ADOGroup* _pGroup) : OGroup_ADO(_bCase),m_pCatalog(_pParent) +{ + construct(); + if(_pGroup) + m_aGroup.set(_pGroup); + else + m_aGroup.Create(); + +} + +OAdoGroup::OAdoGroup(OCatalog* _pParent,bool _bCase, const OUString& Name) : OGroup_ADO(Name,_bCase),m_pCatalog(_pParent) +{ + construct(); + m_aGroup.Create(); + m_aGroup.put_Name(Name); +} + +void OAdoGroup::refreshUsers() +{ + ::std::vector< OUString> aVector; + + WpADOUsers aUsers = m_aGroup.get_Users(); + aUsers.fillElementNames(aVector); + + if(m_pUsers) + m_pUsers->reFill(aVector); + else + m_pUsers.reset(new OUsers(m_pCatalog, m_aMutex, aVector, aUsers, isCaseSensitive())); +} + +Sequence< sal_Int8 > OAdoGroup::getUnoTunnelId() +{ + static const comphelper::UnoIdInit implId; + return implId.getSeq(); +} + +// css::lang::XUnoTunnel + +sal_Int64 OAdoGroup::getSomething( const Sequence< sal_Int8 > & rId ) +{ + return comphelper::getSomethingImpl(rId, this, + comphelper::FallbackToGetSomethingOf<OGroup_ADO>{}); +} + + +void OAdoGroup::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) +{ + if(m_aGroup.IsValid()) + { + + switch(nHandle) + { + case PROPERTY_ID_NAME: + { + OUString aVal; + rValue >>= aVal; + m_aGroup.put_Name(aVal); + } + break; + } + } +} + +void OAdoGroup::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const +{ + if(m_aGroup.IsValid()) + { + switch(nHandle) + { + case PROPERTY_ID_NAME: + rValue <<= m_aGroup.get_Name(); + break; + } + } +} + + +sal_Int32 SAL_CALL OAdoGroup::getPrivileges( const OUString& objName, sal_Int32 objType ) +{ + return MapRight(m_aGroup.GetPermissions(objName,MapObjectType(objType))); +} + +sal_Int32 SAL_CALL OAdoGroup::getGrantablePrivileges( const OUString& objName, sal_Int32 objType ) +{ + RightsEnum eNum = m_aGroup.GetPermissions(objName,MapObjectType(objType)); + if(eNum & adRightWithGrant) + return MapRight(eNum); + return 0; +} + +void SAL_CALL OAdoGroup::grantPrivileges( const OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) +{ + m_aGroup.SetPermissions(objName,MapObjectType(objType),adAccessGrant,Map2Right(objPrivileges)); +} + +void SAL_CALL OAdoGroup::revokePrivileges( const OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) +{ + m_aGroup.SetPermissions(objName,MapObjectType(objType),adAccessDeny,Map2Right(objPrivileges)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AGroups.cxx b/connectivity/source/drivers/ado/AGroups.cxx new file mode 100644 index 000000000..e3fb165b0 --- /dev/null +++ b/connectivity/source/drivers/ado/AGroups.cxx @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/AGroups.hxx> +#include <ado/AGroup.hxx> +#include <ado/ATable.hxx> +#include <ado/AConnection.hxx> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <connectivity/sdbcx/IRefreshable.hxx> +#include <TConnection.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/types.hxx> +#include <connectivity/dbexception.hxx> +#include <strings.hrc> + +using namespace comphelper; +using namespace connectivity; +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::container; + + +sdbcx::ObjectType OGroups::createObject(const OUString& _rName) +{ + return new OAdoGroup(m_pCatalog,isCaseSensitive(),_rName); +} + +void OGroups::impl_refresh() +{ + m_aCollection.Refresh(); +} + +Reference< XPropertySet > OGroups::createDescriptor() +{ + return new OAdoGroup(m_pCatalog,isCaseSensitive()); +} + +// XAppend +sdbcx::ObjectType OGroups::appendObject( const OUString& _rForName, const Reference< XPropertySet >& descriptor ) +{ + OAdoGroup* pGroup = getFromUnoTunnel<OAdoGroup>(descriptor); + if ( pGroup == nullptr ) + m_pCatalog->getConnection()->throwGenericSQLException( STR_INVALID_GROUP_DESCRIPTOR_ERROR,static_cast<XTypeProvider*>(this) ); + + m_aCollection.Append( pGroup->getImpl() ); + return createObject( _rForName ); +} + +// XDrop +void OGroups::dropObject(sal_Int32 /*_nPos*/,const OUString& _sElementName) +{ + m_aCollection.Delete(_sElementName); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AIndex.cxx b/connectivity/source/drivers/ado/AIndex.cxx new file mode 100644 index 000000000..af643a436 --- /dev/null +++ b/connectivity/source/drivers/ado/AIndex.cxx @@ -0,0 +1,121 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/AIndex.hxx> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <ado/AColumns.hxx> +#include <TConnection.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/types.hxx> + +using namespace ::comphelper; + +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; + + +OAdoIndex::OAdoIndex(bool _bCase,OConnection* _pConnection,ADOIndex* _pIndex) + : sdbcx::OIndex(OUString(),OUString(),false,false,false,_bCase) + ,m_pConnection(_pConnection) +{ + construct(); + m_aIndex.set(_pIndex); + fillPropertyValues(); +} + +OAdoIndex::OAdoIndex(bool _bCase,OConnection* _pConnection) + : sdbcx::OIndex(_bCase) + ,m_pConnection(_pConnection) +{ + construct(); + m_aIndex.Create(); +} + + +void OAdoIndex::refreshColumns() +{ + ::std::vector< OUString> aVector; + + WpADOColumns aColumns; + if ( m_aIndex.IsValid() ) + { + aColumns = m_aIndex.get_Columns(); + aColumns.fillElementNames(aVector); + } + + if ( m_pColumns ) + m_pColumns->reFill(aVector); + else + m_pColumns.reset(new OColumns(*this, m_aMutex, aVector, aColumns, isCaseSensitive(), m_pConnection)); +} + + +Sequence< sal_Int8 > OAdoIndex::getUnoTunnelId() +{ + static const comphelper::UnoIdInit implId; + return implId.getSeq(); +} + +// css::lang::XUnoTunnel + +sal_Int64 OAdoIndex::getSomething( const Sequence< sal_Int8 > & rId ) +{ + return comphelper::getSomethingImpl(rId, this, + comphelper::FallbackToGetSomethingOf<sdbcx::OIndex>{}); +} + +void SAL_CALL OAdoIndex::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) +{ + if(m_aIndex.IsValid()) + { + switch(nHandle) + { + case PROPERTY_ID_NAME: + { + OUString aVal; + rValue >>= aVal; + m_aIndex.put_Name(aVal); + } + break; + case PROPERTY_ID_CATALOG: + { + OUString aVal; + rValue >>= aVal; + m_aIndex.put_Name(aVal); + } + break; + case PROPERTY_ID_ISUNIQUE: + m_aIndex.put_Unique(getBOOL(rValue)); + break; + case PROPERTY_ID_ISPRIMARYKEYINDEX: + m_aIndex.put_PrimaryKey(getBOOL(rValue)); + break; + case PROPERTY_ID_ISCLUSTERED: + m_aIndex.put_Clustered(getBOOL(rValue)); + break; + } + } + sdbcx::OIndex::setFastPropertyValue_NoBroadcast(nHandle,rValue); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AIndexes.cxx b/connectivity/source/drivers/ado/AIndexes.cxx new file mode 100644 index 000000000..621ddec60 --- /dev/null +++ b/connectivity/source/drivers/ado/AIndexes.cxx @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/AIndexes.hxx> +#include <ado/AIndex.hxx> +#include <ado/AConnection.hxx> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/IndexType.hpp> +#include <TConnection.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/types.hxx> +#include <connectivity/dbexception.hxx> +#include <strings.hrc> + +using namespace ::comphelper; + + +using namespace connectivity; +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::container; + +sdbcx::ObjectType OIndexes::createObject(const OUString& _rName) +{ + return new OAdoIndex(isCaseSensitive(),m_pConnection,m_aCollection.GetItem(_rName)); +} + +void OIndexes::impl_refresh() +{ + m_aCollection.Refresh(); +} + +Reference< XPropertySet > OIndexes::createDescriptor() +{ + return new OAdoIndex(isCaseSensitive(),m_pConnection); +} + +// XAppend +sdbcx::ObjectType OIndexes::appendObject( const OUString& _rForName, const Reference< XPropertySet >& descriptor ) +{ + OAdoIndex* pIndex = getFromUnoTunnel<OAdoIndex>(descriptor); + if ( pIndex == nullptr ) + m_pConnection->throwGenericSQLException( STR_INVALID_INDEX_DESCRIPTOR_ERROR,static_cast<XTypeProvider*>(this) ); + + ADOIndexes* pIndexes = m_aCollection; + if ( FAILED( pIndexes->Append( OLEVariant( _rForName ), OLEVariant( pIndex->getImpl() ) ) ) ) + { + ADOS::ThrowException(m_pConnection->getConnection(),static_cast<XTypeProvider*>(this)); + m_pConnection->throwGenericSQLException( STR_INVALID_INDEX_DESCRIPTOR_ERROR,static_cast<XTypeProvider*>(this) ); + } + + return new OAdoIndex(isCaseSensitive(),m_pConnection,pIndex->getImpl()); +} + +// XDrop +void OIndexes::dropObject(sal_Int32 /*_nPos*/,const OUString& _sElementName) +{ + m_aCollection.Delete(_sElementName); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AKey.cxx b/connectivity/source/drivers/ado/AKey.cxx new file mode 100644 index 000000000..b74103d83 --- /dev/null +++ b/connectivity/source/drivers/ado/AKey.cxx @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/AKey.hxx> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <comphelper/servicehelper.hxx> +#include <ado/AColumns.hxx> +#include <ado/AConnection.hxx> + +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::sdbcx; + + +OAdoKey::OAdoKey(bool _bCase,OConnection* _pConnection, ADOKey* _pKey) + : OKey_ADO(_bCase) + ,m_pConnection(_pConnection) +{ + construct(); + m_aKey.set(_pKey); + fillPropertyValues(); +} + +OAdoKey::OAdoKey(bool _bCase,OConnection* _pConnection) + : OKey_ADO(_bCase) + ,m_pConnection(_pConnection) +{ + construct(); + m_aKey.Create(); +} + +void OAdoKey::refreshColumns() +{ + ::std::vector< OUString> aVector; + + WpADOColumns aColumns; + if ( m_aKey.IsValid() ) + { + aColumns = m_aKey.get_Columns(); + aColumns.fillElementNames(aVector); + } + + if(m_pColumns) + m_pColumns->reFill(aVector); + else + m_pColumns.reset(new OColumns(*this, m_aMutex, aVector, aColumns, isCaseSensitive(), m_pConnection)); +} + +Sequence< sal_Int8 > OAdoKey::getUnoTunnelId() +{ + static const comphelper::UnoIdInit implId; + return implId.getSeq(); +} + +// css::lang::XUnoTunnel + +sal_Int64 OAdoKey::getSomething( const Sequence< sal_Int8 > & rId ) +{ + return comphelper::getSomethingImpl(rId, this, + comphelper::FallbackToGetSomethingOf<OKey_ADO>{}); +} + +void OAdoKey::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) +{ + if(m_aKey.IsValid()) + { + switch(nHandle) + { + case PROPERTY_ID_NAME: + { + OUString aVal; + rValue >>= aVal; + m_aKey.put_Name(aVal); + ADOS::ThrowException(m_pConnection->getConnection(),*this); + } + break; + case PROPERTY_ID_TYPE: + { + sal_Int32 nVal=0; + rValue >>= nVal; + m_aKey.put_Type(Map2KeyRule(nVal)); + ADOS::ThrowException(m_pConnection->getConnection(),*this); + } + break; + case PROPERTY_ID_REFERENCEDTABLE: + { + OUString aVal; + rValue >>= aVal; + m_aKey.put_RelatedTable(aVal); + ADOS::ThrowException(m_pConnection->getConnection(),*this); + } + break; + case PROPERTY_ID_UPDATERULE: + { + sal_Int32 nVal=0; + rValue >>= nVal; + m_aKey.put_UpdateRule(Map2Rule(nVal)); + ADOS::ThrowException(m_pConnection->getConnection(),*this); + } + break; + case PROPERTY_ID_DELETERULE: + { + sal_Int32 nVal=0; + rValue >>= nVal; + m_aKey.put_DeleteRule(Map2Rule(nVal)); + ADOS::ThrowException(m_pConnection->getConnection(),*this); + } + break; + } + } + OKey_ADO::setFastPropertyValue_NoBroadcast(nHandle,rValue); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AKeys.cxx b/connectivity/source/drivers/ado/AKeys.cxx new file mode 100644 index 000000000..f0d938d39 --- /dev/null +++ b/connectivity/source/drivers/ado/AKeys.cxx @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/AKeys.hxx> +#include <ado/AKey.hxx> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbcx/KeyType.hpp> +#include <com/sun/star/sdbc/KeyRule.hpp> +#include <ado/AConnection.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/types.hxx> +#include <ado/Awrapado.hxx> +#include <connectivity/dbexception.hxx> +#include <strings.hrc> + +using namespace ::comphelper; +using namespace connectivity; +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::sdbcx; +using namespace com::sun::star::container; + +sdbcx::ObjectType OKeys::createObject(const OUString& _rName) +{ + return new OAdoKey(isCaseSensitive(),m_pConnection,m_aCollection.GetItem(_rName)); +} + +void OKeys::impl_refresh() +{ + m_aCollection.Refresh(); +} + +Reference< XPropertySet > OKeys::createDescriptor() +{ + return new OAdoKey(isCaseSensitive(),m_pConnection); +} + +// XAppend +sdbcx::ObjectType OKeys::appendObject( const OUString&, const Reference< XPropertySet >& descriptor ) +{ + OAdoKey* pKey = getFromUnoTunnel<OAdoKey>( descriptor ); + if ( pKey == nullptr) + m_pConnection->throwGenericSQLException( STR_INVALID_KEY_DESCRIPTOR_ERROR,static_cast<XTypeProvider*>(this) ); + + // To pass as column parameter to Key's Append method + OLEVariant vOptional; + vOptional.setNoArg(); + + OAdoKey::Map2KeyRule(getINT32(descriptor->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)))); + + WpADOKey aKey = pKey->getImpl(); + OUString sName = aKey.get_Name(); + if(!sName.getLength()) + aKey.put_Name(u"PrimaryKey"); + + ADOKeys* pKeys = m_aCollection; + if ( FAILED(pKeys->Append(OLEVariant(static_cast<ADOKey*>(aKey)), + adKeyPrimary, // must be every time adKeyPrimary + vOptional)) ) + { + ADOS::ThrowException(m_pConnection->getConnection(),static_cast<XTypeProvider*>(this)); + // just make sure that an SQLExceptionis thrown here + m_pConnection->throwGenericSQLException( STR_INVALID_KEY_DESCRIPTOR_ERROR,static_cast<XTypeProvider*>(this) ); + } + + return new OAdoKey(isCaseSensitive(),m_pConnection,pKey->getImpl()); +} + +// XDrop +void OKeys::dropObject(sal_Int32 /*_nPos*/,const OUString& _sElementName) +{ + if(!m_aCollection.Delete(OLEVariant(_sElementName).getString())) + ADOS::ThrowException(m_pConnection->getConnection(),static_cast<XTypeProvider*>(this)); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/APreparedStatement.cxx b/connectivity/source/drivers/ado/APreparedStatement.cxx new file mode 100644 index 000000000..cf2339fdc --- /dev/null +++ b/connectivity/source/drivers/ado/APreparedStatement.cxx @@ -0,0 +1,455 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <connectivity/sqlparse.hxx> +#include <ado/APreparedStatement.hxx> +#include <com/sun/star/sdbc/DataType.hpp> +#include <ado/AResultSetMetaData.hxx> +#include <ado/AResultSet.hxx> +#include <ado/ADriver.hxx> +#include <com/sun/star/lang/DisposedException.hpp> +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/queryinterface.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/sequence.hxx> +#include <comphelper/types.hxx> +#include <connectivity/dbexception.hxx> +#include <connectivity/dbtools.hxx> +#include <rtl/ref.hxx> +#include <strings.hrc> + +#include <limits> + +#define CHECK_RETURN(x) \ + if(!x) \ + ADOS::ThrowException(m_pConnection->getConnection(),*this); + +#ifdef max +# undef max +#endif + +using namespace connectivity::ado; +using namespace connectivity; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::util; + +IMPLEMENT_SERVICE_INFO(OPreparedStatement,"com.sun.star.sdbcx.APreparedStatement","com.sun.star.sdbc.PreparedStatement"); + +OPreparedStatement::OPreparedStatement( OConnection* _pConnection, const OUString& sql) + : OStatement_Base( _pConnection ) +{ + osl_atomic_increment( &m_refCount ); + + OSQLParser aParser(_pConnection->getDriver()->getContext()); + OUString sErrorMessage; + OUString sNewSql; + std::unique_ptr<OSQLParseNode> pNode = aParser.parseTree(sErrorMessage,sql); + if(pNode) + { // special handling for parameters + // we recursive replace all occurrences of ? in the statement and + // replace them with name like "parame" */ + sal_Int32 nParameterCount = 0; + replaceParameterNodeName(pNode.get(), "parame", nParameterCount); + pNode->parseNodeToStr( sNewSql, _pConnection ); + } + else + sNewSql = sql; + CHECK_RETURN(m_Command.put_CommandText(sNewSql)) + CHECK_RETURN(m_Command.put_Prepared(VARIANT_TRUE)) + m_pParameters = m_Command.get_Parameters(); + m_pParameters->AddRef(); + m_pParameters->Refresh(); + + osl_atomic_decrement( &m_refCount ); +} + +OPreparedStatement::~OPreparedStatement() +{ + if (m_pParameters) + { + OSL_FAIL( "OPreparedStatement::~OPreparedStatement: not disposed!" ); + m_pParameters->Release(); + m_pParameters = nullptr; + } +} + +Any SAL_CALL OPreparedStatement::queryInterface( const Type & rType ) +{ + Any aRet = OStatement_Base::queryInterface(rType); + return aRet.hasValue() ? aRet : ::cppu::queryInterface( rType, + static_cast< XPreparedStatement*>(this), + static_cast< XParameters*>(this), + static_cast< XResultSetMetaDataSupplier*>(this)); +} + +css::uno::Sequence< css::uno::Type > SAL_CALL OPreparedStatement::getTypes( ) +{ + ::cppu::OTypeCollection aTypes( cppu::UnoType<XPreparedStatement>::get(), + cppu::UnoType<XParameters>::get(), + cppu::UnoType<XResultSetMetaDataSupplier>::get()); + + return ::comphelper::concatSequences(aTypes.getTypes(),OStatement_Base::getTypes()); +} + +Reference< XResultSetMetaData > SAL_CALL OPreparedStatement::getMetaData( ) +{ + if(!m_xMetaData.is() && m_RecordSet.IsValid()) + m_xMetaData = new OResultSetMetaData(m_RecordSet); + return m_xMetaData; +} + +void OPreparedStatement::disposing() +{ + m_xMetaData.clear(); + if (m_pParameters) + { + m_pParameters->Release(); + m_pParameters = nullptr; + } + OStatement_Base::disposing(); +} + +void SAL_CALL OPreparedStatement::close( ) +{ + + { + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + } + dispose(); + +} + +sal_Bool SAL_CALL OPreparedStatement::execute( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + clearWarnings (); + + // Call SQLExecute + try { + ADORecordset* pSet=nullptr; + CHECK_RETURN(m_Command.Execute(m_RecordsAffected,m_Parameters,adCmdUnknown,&pSet)) + m_RecordSet.set(pSet); + } + catch (SQLWarning&) + { + //TODO: Save pointer to warning and save with ResultSet + // object once it is created. + } + return m_RecordSet.IsValid(); +} + +sal_Int32 SAL_CALL OPreparedStatement::executeUpdate( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + ADORecordset* pSet=nullptr; + CHECK_RETURN(m_Command.Execute(m_RecordsAffected,m_Parameters,adCmdUnknown,&pSet)) + if ( VT_ERROR == m_RecordsAffected.getType() ) + { + ADOS::ThrowException(m_pConnection->getConnection(),*this); + // to be sure that we get the error really thrown + throw SQLException(); + } + m_RecordSet.set(pSet); + return m_RecordsAffected.getInt32(); +} + +void OPreparedStatement::setParameter(sal_Int32 parameterIndex, const DataTypeEnum& _eType, + sal_Int32 _nSize,const OLEVariant& Val) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + sal_Int32 nCount = 0; + m_pParameters->get_Count(&nCount); + if(nCount < (parameterIndex-1)) + { + OUString sDefaultName = "parame" + OUString::number(parameterIndex); + ADOParameter* pParam = m_Command.CreateParameter(sDefaultName,_eType,adParamInput,_nSize,Val); + if(pParam) + { + m_pParameters->Append(pParam); + } + } + else + { + WpADOParameter aParam; + m_pParameters->get_Item(OLEVariant(sal_Int32(parameterIndex-1)),&aParam); + if(aParam) + { + DataTypeEnum eType = aParam.GetADOType(); + if ( _eType != eType && _eType != adDBTimeStamp ) + { + aParam.put_Type(_eType); + eType = _eType; + aParam.put_Size(_nSize); + } + + if ( adVarBinary == eType && aParam.GetAttributes() == adParamLong ) + { + aParam.AppendChunk(Val); + } + else + CHECK_RETURN(aParam.PutValue(Val)); + } + } + ADOS::ThrowException(m_pConnection->getConnection(),*this); +} + +void SAL_CALL OPreparedStatement::setString( sal_Int32 parameterIndex, const OUString& x ) +{ + setParameter( parameterIndex, adLongVarWChar, std::numeric_limits< sal_Int32 >::max(), x ); +} + +Reference< XConnection > SAL_CALL OPreparedStatement::getConnection( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + return static_cast<Reference< XConnection >>(m_pConnection); +} + +Reference< XResultSet > SAL_CALL OPreparedStatement::executeQuery( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + // first clear the old things + m_xMetaData.clear(); + disposeResultSet(); + if(m_RecordSet.IsValid()) + m_RecordSet.Close(); + m_RecordSet.clear(); + + // then create the new ones + m_RecordSet.Create(); + OLEVariant aCmd; + aCmd.setIDispatch(m_Command); + OLEVariant aCon; + aCon.setNoArg(); + CHECK_RETURN(m_RecordSet.put_CacheSize(m_nFetchSize)) + CHECK_RETURN(m_RecordSet.put_MaxRecords(m_nMaxRows)) + CHECK_RETURN(m_RecordSet.Open(aCmd,aCon,m_eCursorType,m_eLockType,adOpenUnspecified)) + CHECK_RETURN(m_RecordSet.get_CacheSize(m_nFetchSize)) + CHECK_RETURN(m_RecordSet.get_MaxRecords(m_nMaxRows)) + CHECK_RETURN(m_RecordSet.get_CursorType(m_eCursorType)) + CHECK_RETURN(m_RecordSet.get_LockType(m_eLockType)) + + rtl::Reference<OResultSet> pSet = new OResultSet(m_RecordSet,this); + pSet->construct(); + pSet->setMetaData(getMetaData()); + m_xResultSet = WeakReference<XResultSet>(pSet); + + return pSet; +} + +void SAL_CALL OPreparedStatement::setBoolean( sal_Int32 parameterIndex, sal_Bool x ) +{ + setParameter(parameterIndex,adBoolean,sizeof(x),bool(x)); +} + +void SAL_CALL OPreparedStatement::setByte( sal_Int32 parameterIndex, sal_Int8 x ) +{ + setParameter(parameterIndex,adTinyInt,sizeof(x),x); +} + +void SAL_CALL OPreparedStatement::setDate( sal_Int32 parameterIndex, const Date& x ) +{ + setParameter(parameterIndex,adDBDate,sizeof(x),x); +} + +void SAL_CALL OPreparedStatement::setTime( sal_Int32 parameterIndex, const css::util::Time& x ) +{ + setParameter(parameterIndex,adDBTime,sizeof(x),x); +} + +void SAL_CALL OPreparedStatement::setTimestamp( sal_Int32 parameterIndex, const DateTime& x ) +{ + setParameter(parameterIndex,adDBTimeStamp,sizeof(x),x); +} + +void SAL_CALL OPreparedStatement::setDouble( sal_Int32 parameterIndex, double x ) +{ + setParameter(parameterIndex,adDouble,sizeof(x),x); +} + +void SAL_CALL OPreparedStatement::setFloat( sal_Int32 parameterIndex, float x ) +{ + setParameter(parameterIndex,adSingle,sizeof(x),x); +} + +void SAL_CALL OPreparedStatement::setInt( sal_Int32 parameterIndex, sal_Int32 x ) +{ + setParameter(parameterIndex,adInteger,sizeof(x),x); +} + +void SAL_CALL OPreparedStatement::setLong( sal_Int32 parameterIndex, sal_Int64 x ) +{ + setParameter(parameterIndex,adBigInt,sizeof(x),x); +} + +void SAL_CALL OPreparedStatement::setNull( sal_Int32 parameterIndex, sal_Int32 /*sqlType*/ ) +{ + OLEVariant aVal; + aVal.setNull(); + setParameter(parameterIndex,adEmpty,0,aVal); +} + +void SAL_CALL OPreparedStatement::setClob( sal_Int32 /*parameterIndex*/, const Reference< XClob >& /*x*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRowUpdate::setClob", *this ); +} + +void SAL_CALL OPreparedStatement::setBlob( sal_Int32 /*parameterIndex*/, const Reference< XBlob >& /*x*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRowUpdate::setBlob", *this ); +} + +void SAL_CALL OPreparedStatement::setArray( sal_Int32 /*parameterIndex*/, const Reference< XArray >& /*x*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRowUpdate::setArray", *this ); +} + +void SAL_CALL OPreparedStatement::setRef( sal_Int32 /*parameterIndex*/, const Reference< XRef >& /*x*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRowUpdate::setRef", *this ); +} + +void SAL_CALL OPreparedStatement::setObjectWithInfo( sal_Int32 parameterIndex, const Any& x, sal_Int32 sqlType, sal_Int32 scale ) +{ + switch(sqlType) + { + case DataType::DECIMAL: + case DataType::NUMERIC: + setString(parameterIndex,::comphelper::getString(x)); + break; + default: + ::dbtools::setObjectWithInfo(this,parameterIndex,x,sqlType,scale); + break; + } +} + +void SAL_CALL OPreparedStatement::setObjectNull( sal_Int32 parameterIndex, sal_Int32 sqlType, const OUString& /*typeName*/ ) +{ + setNull(parameterIndex,sqlType); +} + +void SAL_CALL OPreparedStatement::setObject( sal_Int32 parameterIndex, const Any& x ) +{ + if(!::dbtools::implSetObject(this,parameterIndex,x)) + { + const OUString sError( m_pConnection->getResources().getResourceStringWithSubstitution( + STR_UNKNOWN_PARA_TYPE, + "$position$", OUString::number(parameterIndex) + ) ); + ::dbtools::throwGenericSQLException(sError,*this); + } +} + +void SAL_CALL OPreparedStatement::setShort( sal_Int32 parameterIndex, sal_Int16 x ) +{ + setParameter(parameterIndex,adSmallInt,sizeof(x),x); +} + +void SAL_CALL OPreparedStatement::setBytes( sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x ) +{ + setParameter(parameterIndex,adVarBinary,sizeof(sal_Int8)*x.getLength(),x); +} + +void SAL_CALL OPreparedStatement::setCharacterStream( sal_Int32 /*parameterIndex*/, const Reference< css::io::XInputStream >& /*x*/, sal_Int32 /*length*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XParameters::setCharacterStream", *this ); +} + +void SAL_CALL OPreparedStatement::setBinaryStream( sal_Int32 parameterIndex, const Reference< css::io::XInputStream >& x, sal_Int32 length ) +{ + if(x.is()) + { + Sequence< sal_Int8 > aData; + x->readBytes(aData,length); + setBytes(parameterIndex,aData); + } +} + +void SAL_CALL OPreparedStatement::clearParameters( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + if(m_pParameters) + { + sal_Int32 nCount = 0; + m_pParameters->get_Count(&nCount); + OLEVariant aVal; + aVal.setEmpty(); + for(sal_Int32 i=0;i<nCount;++i) + { + WpADOParameter aParam; + m_pParameters->get_Item(OLEVariant(i),&aParam); + if(aParam) + { + CHECK_RETURN(aParam.PutValue(aVal)); + } + } + } +} + +void SAL_CALL OPreparedStatement::acquire() noexcept +{ + OStatement_Base::acquire(); +} + +void SAL_CALL OPreparedStatement::release() noexcept +{ + OStatement_Base::release(); +} + +void OPreparedStatement::replaceParameterNodeName(OSQLParseNode const * _pNode, + const OUString& _sDefaultName, + sal_Int32& _rParameterCount) +{ + sal_Int32 nCount = _pNode->count(); + for(sal_Int32 i=0;i < nCount;++i) + { + OSQLParseNode* pChildNode = _pNode->getChild(i); + if(SQL_ISRULE(pChildNode,parameter) && pChildNode->count() == 1) + { + OSQLParseNode* pNewNode = new OSQLParseNode(OUString(":") ,SQLNodeType::Punctuation,0); + delete pChildNode->replace(pChildNode->getChild(0),pNewNode); + OUString sParameterName = _sDefaultName + OUString::number(++_rParameterCount); + pChildNode->append(new OSQLParseNode( sParameterName,SQLNodeType::Name,0)); + } + else + replaceParameterNodeName(pChildNode,_sDefaultName,_rParameterCount); + + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AResultSet.cxx b/connectivity/source/drivers/ado/AResultSet.cxx new file mode 100644 index 000000000..85ca2b081 --- /dev/null +++ b/connectivity/source/drivers/ado/AResultSet.cxx @@ -0,0 +1,1158 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/AResultSet.hxx> +#include <ado/AResultSetMetaData.hxx> +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/KeyRule.hpp> +#include <com/sun/star/sdbc/IndexType.hpp> +#include <com/sun/star/sdbcx/CompareBookmark.hpp> +#include <comphelper/property.hxx> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/sdbc/ResultSetConcurrency.hpp> +#include <com/sun/star/sdbc/ResultSetType.hpp> +#include <com/sun/star/sdbc/FetchDirection.hpp> +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <comphelper/sequence.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <comphelper/seqstream.hxx> +#include <connectivity/dbexception.hxx> +#include <connectivity/dbtools.hxx> +#include <comphelper/types.hxx> + +using namespace ::comphelper; + + +#include <oledb.h> + +#define CHECK_RETURN(x) \ + if(!SUCCEEDED(x)) \ + ADOS::ThrowException(m_pStmt->m_pConnection->getConnection(),*this); + +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; + + +// IMPLEMENT_SERVICE_INFO(OResultSet,"com.sun.star.sdbcx.AResultSet","com.sun.star.sdbc.ResultSet"); +OUString SAL_CALL OResultSet::getImplementationName( ) +{ + return "com.sun.star.sdbcx.ado.ResultSet"; +} + +css::uno::Sequence< OUString > SAL_CALL OResultSet::getSupportedServiceNames( ) +{ + return {"com.sun.star.sdbc.ResultSet","com.sun.star.sdbcx.ResultSet"}; +} + +sal_Bool SAL_CALL OResultSet::supportsService( const OUString& _rServiceName ) +{ + return cppu::supportsService(this, _rServiceName); +} + +OResultSet::OResultSet(ADORecordset* _pRecordSet,OStatement_Base* pStmt) : OResultSet_BASE(m_aMutex) + ,OPropertySetHelper(OResultSet_BASE::rBHelper) + ,m_pRecordSet(_pRecordSet) + ,m_pStmt(pStmt) + ,m_xStatement(*pStmt) + ,m_nRowPos(0) + ,m_bEOF(false) + ,m_bOnFirstAfterOpen(false) +{ +} + +OResultSet::OResultSet(ADORecordset* _pRecordSet) : OResultSet_BASE(m_aMutex) + ,OPropertySetHelper(OResultSet_BASE::rBHelper) + ,m_pRecordSet(_pRecordSet) + ,m_pStmt(nullptr) + ,m_nRowPos(0) + ,m_bEOF(false) + ,m_bOnFirstAfterOpen(false) +{ +} + +void OResultSet::construct() +{ + osl_atomic_increment( &m_refCount ); + if (!m_pRecordSet) + { + OSL_FAIL( "OResultSet::construct: no RecordSet!" ); + Reference< XInterface > xInt( *this ); + osl_atomic_decrement( &m_refCount ); + ::dbtools::throwFunctionSequenceException( xInt ); + } + m_pRecordSet->AddRef(); + VARIANT_BOOL bIsAtBOF; + CHECK_RETURN(m_pRecordSet->get_BOF(&bIsAtBOF)) + m_bOnFirstAfterOpen = bIsAtBOF != VARIANT_TRUE; + osl_atomic_decrement( &m_refCount ); +} + +OResultSet::~OResultSet() +{ + if(m_pRecordSet) + m_pRecordSet->Release(); +} + +void OResultSet::disposing() +{ + OPropertySetHelper::disposing(); + + ::osl::MutexGuard aGuard(m_aMutex); + if(m_pRecordSet) + m_pRecordSet->Close(); + m_xStatement.clear(); + m_xMetaData.clear(); +} + +Any SAL_CALL OResultSet::queryInterface( const Type & rType ) +{ + Any aRet = OPropertySetHelper::queryInterface(rType); + return aRet.hasValue() ? aRet : OResultSet_BASE::queryInterface(rType); +} + +css::uno::Sequence< css::uno::Type > SAL_CALL OResultSet::getTypes( ) +{ + ::cppu::OTypeCollection aTypes( cppu::UnoType<css::beans::XMultiPropertySet>::get(), + cppu::UnoType<css::beans::XFastPropertySet>::get(), + cppu::UnoType<css::beans::XPropertySet>::get()); + + return ::comphelper::concatSequences(aTypes.getTypes(),OResultSet_BASE::getTypes()); +} + + +sal_Int32 SAL_CALL OResultSet::findColumn( const OUString& columnName ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + Reference< XResultSetMetaData > xMeta = getMetaData(); + sal_Int32 nLen = xMeta->getColumnCount(); + sal_Int32 i = 1; + for(;i<=nLen;++i) + { + if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) : + columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i))) + return i; + } + + ::dbtools::throwInvalidColumnException( columnName, *this ); + assert(false); + return 0; // Never reached +} +#define BLOCK_SIZE 256 + +Reference< css::io::XInputStream > SAL_CALL OResultSet::getBinaryStream( sal_Int32 columnIndex ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + WpADOField aField = ADOS::getField(m_pRecordSet,columnIndex); + + if((aField.GetAttributes() & adFldLong) == adFldLong) + { + //Copy the data only up to the Actual Size of Field. + sal_Int32 nSize = aField.GetActualSize(); + Sequence<sal_Int8> aData(nSize); + sal_Int32 index = 0; + while(index < nSize) + { + m_aValue = aField.GetChunk(BLOCK_SIZE); + if(m_aValue.isNull()) + break; + UCHAR chData; + for(LONG index2 = 0;index2 < BLOCK_SIZE;++index2) + { + HRESULT hr = ::SafeArrayGetElement(m_aValue.parray,&index2,&chData); + if(SUCCEEDED(hr)) + { + //Take BYTE by BYTE and advance Memory Location + aData.getArray()[index++] = chData; + } + else + break; + } + } + + return new ::comphelper::SequenceInputStream(aData); + } + // else we ask for a bytesequence + aField.get_Value(m_aValue); + + return m_aValue.isNull() ? nullptr : new ::comphelper::SequenceInputStream(m_aValue.getByteSequence()); +} + +Reference< css::io::XInputStream > SAL_CALL OResultSet::getCharacterStream( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getCharacterStream", *this ); + return nullptr; +} + +OLEVariant OResultSet::getValue(sal_Int32 columnIndex ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + WpADOField aField = ADOS::getField(m_pRecordSet,columnIndex); + aField.get_Value(m_aValue); + return m_aValue; +} + +sal_Bool SAL_CALL OResultSet::getBoolean( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getBool(); +} + + +sal_Int8 SAL_CALL OResultSet::getByte( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getInt8(); +} + + +Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getByteSequence(); +} + + +css::util::Date SAL_CALL OResultSet::getDate( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getDate(); +} + + +double SAL_CALL OResultSet::getDouble( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getDouble(); +} + + +float SAL_CALL OResultSet::getFloat( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getFloat(); +} + + +sal_Int32 SAL_CALL OResultSet::getInt( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getInt32(); +} + + +sal_Int32 SAL_CALL OResultSet::getRow( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + PositionEnum_Param aPos; + m_pRecordSet->get_AbsolutePosition(&aPos); + return (aPos > 0) ? static_cast<sal_Int32>(aPos) : m_nRowPos; + // return the rowcount from driver if the driver doesn't support this return our count +} + + +sal_Int64 SAL_CALL OResultSet::getLong( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getLong", *this ); + return sal_Int64(0); +} + + +Reference< XResultSetMetaData > SAL_CALL OResultSet::getMetaData( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + if(!m_xMetaData.is()) + m_xMetaData = new OResultSetMetaData(m_pRecordSet); + return m_xMetaData; +} + +Reference< XArray > SAL_CALL OResultSet::getArray( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getArray", *this ); + return nullptr; +} + + +Reference< XClob > SAL_CALL OResultSet::getClob( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getClob", *this ); + return nullptr; +} + +Reference< XBlob > SAL_CALL OResultSet::getBlob( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getBlob", *this ); + return nullptr; +} + + +Reference< XRef > SAL_CALL OResultSet::getRef( sal_Int32 /*columnIndex*/ ) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getRef", *this ); + return nullptr; +} + + +Any SAL_CALL OResultSet::getObject( sal_Int32 columnIndex, const Reference< css::container::XNameAccess >& /*typeMap*/ ) +{ + return getValue(columnIndex).makeAny(); +} + + +sal_Int16 SAL_CALL OResultSet::getShort( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getInt16(); +} + + +OUString SAL_CALL OResultSet::getString( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getString(); +} + + +css::util::Time SAL_CALL OResultSet::getTime( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getTime(); +} + + +css::util::DateTime SAL_CALL OResultSet::getTimestamp( sal_Int32 columnIndex ) +{ + return getValue(columnIndex).getDateTime(); +} + + +sal_Bool SAL_CALL OResultSet::isAfterLast( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + VARIANT_BOOL bIsAtEOF; + CHECK_RETURN(m_pRecordSet->get_EOF(&bIsAtEOF)) + return bIsAtEOF == VARIANT_TRUE; +} + +sal_Bool SAL_CALL OResultSet::isFirst( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + return m_nRowPos == 1; +} + +sal_Bool SAL_CALL OResultSet::isLast( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + return true; +} + +void SAL_CALL OResultSet::beforeFirst( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + if(first()) + m_bOnFirstAfterOpen = !previous(); +} + +void SAL_CALL OResultSet::afterLast( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + if(last()) + next(); + m_bEOF = true; +} + + +void SAL_CALL OResultSet::close( ) +{ + { + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + } + dispose(); +} + + +sal_Bool SAL_CALL OResultSet::first( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + if(SUCCEEDED(m_pRecordSet->MoveFirst())) + { + m_nRowPos = 1; + m_bOnFirstAfterOpen = false; + return true; + } + return false; +} + + +sal_Bool SAL_CALL OResultSet::last( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + bool bRet = SUCCEEDED(m_pRecordSet->MoveLast()); + if(bRet) + { + m_pRecordSet->get_RecordCount(&m_nRowPos); + m_bOnFirstAfterOpen = false; + } + return bRet; +} + +sal_Bool SAL_CALL OResultSet::absolute( sal_Int32 row ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + if(!row) // absolute with zero not allowed + ::dbtools::throwFunctionSequenceException(*this); + + bool bCheck = true; + if(row < 0) + { + bCheck = SUCCEEDED(m_pRecordSet->MoveLast()); + if ( bCheck ) + { + while(++row < 0 && bCheck) + bCheck = SUCCEEDED(m_pRecordSet->MovePrevious()); + } + } + else + { + first(); + OLEVariant aEmpty; + aEmpty.setNoArg(); + bCheck = SUCCEEDED(m_pRecordSet->Move(row-1,aEmpty)); // move to row -1 because we stand already on the first + if(bCheck) + m_nRowPos = row; + } + if(bCheck) + m_bOnFirstAfterOpen = false; + return bCheck; +} + +sal_Bool SAL_CALL OResultSet::relative( sal_Int32 row ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + OLEVariant aEmpty; + aEmpty.setNoArg(); + sal_Int32 nNewPos = row; + if ( m_bOnFirstAfterOpen && nNewPos > 0 ) + --nNewPos; + bool bRet = SUCCEEDED(m_pRecordSet->Move(row,aEmpty)); + if(bRet) + { + m_nRowPos += row; + m_bOnFirstAfterOpen = false; + } + return bRet; +} + +sal_Bool SAL_CALL OResultSet::previous( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + bool bRet = SUCCEEDED(m_pRecordSet->MovePrevious()); + if(bRet) + { + --m_nRowPos; + m_bOnFirstAfterOpen = false; + } + return bRet; +} + +Reference< XInterface > SAL_CALL OResultSet::getStatement( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + return m_xStatement; +} + + +sal_Bool SAL_CALL OResultSet::rowDeleted( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + sal_Int32 eRec; + m_pRecordSet->get_Status(&eRec); + bool bRet = (RecordStatusEnum(eRec) & adRecDeleted) == adRecDeleted; + if(bRet) + --m_nRowPos; + return bRet; +} + +sal_Bool SAL_CALL OResultSet::rowInserted( ) +{ ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + sal_Int32 eRec; + m_pRecordSet->get_Status(&eRec); + bool bRet = (RecordStatusEnum(eRec) & adRecNew) == adRecNew; + if(bRet) + ++m_nRowPos; + return bRet; +} + +sal_Bool SAL_CALL OResultSet::rowUpdated( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + sal_Int32 eRec; + m_pRecordSet->get_Status(&eRec); + return (RecordStatusEnum(eRec) & adRecModified) == adRecModified; +} + + +sal_Bool SAL_CALL OResultSet::isBeforeFirst( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + OSL_ENSURE(!m_nRowPos,"OResultSet::isBeforeFirst: Error in setting m_nRowPos!"); + VARIANT_BOOL bIsAtBOF = VARIANT_TRUE; + if(!m_bOnFirstAfterOpen) + { + OSL_ENSURE(!m_nRowPos,"OResultSet::isBeforeFirst: Error in setting m_nRowPos!"); + m_pRecordSet->get_BOF(&bIsAtBOF); + } + return bIsAtBOF == VARIANT_TRUE; +} + + +sal_Bool SAL_CALL OResultSet::next( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + bool bRet = true; + if(m_bOnFirstAfterOpen) + { + m_bOnFirstAfterOpen = false; + ++m_nRowPos; + } + else + { + bRet = SUCCEEDED(m_pRecordSet->MoveNext()); + + if(bRet) + { + VARIANT_BOOL bIsAtEOF; + CHECK_RETURN(m_pRecordSet->get_EOF(&bIsAtEOF)) + bRet = bIsAtEOF != VARIANT_TRUE; + ++m_nRowPos; + } + else + ADOS::ThrowException(m_pStmt->m_pConnection->getConnection(),*this); + } + + return bRet; +} + + +sal_Bool SAL_CALL OResultSet::wasNull( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + return m_aValue.isNull(); +} + + +void SAL_CALL OResultSet::cancel( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + m_pRecordSet->Cancel(); +} + +void SAL_CALL OResultSet::clearWarnings( ) +{ +} + +Any SAL_CALL OResultSet::getWarnings( ) +{ + return Any(); +} + +void SAL_CALL OResultSet::insertRow( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + OLEVariant aEmpty; + aEmpty.setNoArg(); + m_pRecordSet->AddNew(aEmpty,aEmpty); +} + +void SAL_CALL OResultSet::updateRow( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + OLEVariant aEmpty; + aEmpty.setNoArg(); + m_pRecordSet->Update(aEmpty,aEmpty); +} + +void SAL_CALL OResultSet::deleteRow( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + m_pRecordSet->Delete(); + m_pRecordSet->UpdateBatch(adAffectCurrent); +} + + +void SAL_CALL OResultSet::cancelRowUpdates( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + m_pRecordSet->CancelUpdate(); +} + + +void SAL_CALL OResultSet::moveToInsertRow( ) +{ + // ::osl::MutexGuard aGuard( m_aMutex ); + //checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + // if ( getResultSetConcurrency() == ResultSetConcurrency::READ_ONLY ) + // throw SQLException(); +} + + +void SAL_CALL OResultSet::moveToCurrentRow( ) +{ +} + +void OResultSet::updateValue(sal_Int32 columnIndex,const OLEVariant& x) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + WpADOField aField = ADOS::getField(m_pRecordSet,columnIndex); + aField.PutValue(x); +} + +void SAL_CALL OResultSet::updateNull( sal_Int32 columnIndex ) +{ + OLEVariant x; + x.setNull(); + updateValue(columnIndex,x); +} + + +void SAL_CALL OResultSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x ) +{ + updateValue(columnIndex,bool(x)); +} + +void SAL_CALL OResultSet::updateByte( sal_Int32 columnIndex, sal_Int8 x ) +{ + updateValue(columnIndex,x); +} + + +void SAL_CALL OResultSet::updateShort( sal_Int32 columnIndex, sal_Int16 x ) +{ + updateValue(columnIndex,x); +} + +void SAL_CALL OResultSet::updateInt( sal_Int32 columnIndex, sal_Int32 x ) +{ + updateValue(columnIndex,x); +} + +void SAL_CALL OResultSet::updateLong( sal_Int32 columnIndex, sal_Int64 x ) +{ + updateValue(columnIndex,x); +} + +void SAL_CALL OResultSet::updateFloat( sal_Int32 columnIndex, float x ) +{ + updateValue(columnIndex,x); +} + + +void SAL_CALL OResultSet::updateDouble( sal_Int32 columnIndex, double x ) +{ + updateValue(columnIndex,x); +} + +void SAL_CALL OResultSet::updateString( sal_Int32 columnIndex, const OUString& x ) +{ + updateValue(columnIndex,x); +} + +void SAL_CALL OResultSet::updateBytes( sal_Int32 columnIndex, const Sequence< sal_Int8 >& x ) +{ + updateValue(columnIndex,x); +} + +void SAL_CALL OResultSet::updateDate( sal_Int32 columnIndex, const css::util::Date& x ) +{ + updateValue(columnIndex,x); +} + + +void SAL_CALL OResultSet::updateTime( sal_Int32 columnIndex, const css::util::Time& x ) +{ + updateValue(columnIndex,x); +} + + +void SAL_CALL OResultSet::updateTimestamp( sal_Int32 columnIndex, const css::util::DateTime& x ) +{ + updateValue(columnIndex,x); +} + + +void SAL_CALL OResultSet::updateBinaryStream( sal_Int32 columnIndex, const Reference< css::io::XInputStream >& x, sal_Int32 length ) +{ + if(!x.is()) + ::dbtools::throwFunctionSequenceException(*this); + + Sequence<sal_Int8> aSeq; + x->readBytes(aSeq,length); + updateBytes(columnIndex,aSeq); +} + +void SAL_CALL OResultSet::updateCharacterStream( sal_Int32 columnIndex, const Reference< css::io::XInputStream >& x, sal_Int32 length ) +{ + if(!x.is()) + ::dbtools::throwFunctionSequenceException(*this); + + Sequence<sal_Int8> aSeq; + x->readBytes(aSeq,length); + updateBytes(columnIndex,aSeq); +} + +void SAL_CALL OResultSet::refreshRow( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + m_pRecordSet->Resync(adAffectCurrent); +} + +void SAL_CALL OResultSet::updateObject( sal_Int32 columnIndex, const Any& x ) +{ + if (!::dbtools::implUpdateObject(this, columnIndex, x)) + throw SQLException(); +} + + +void SAL_CALL OResultSet::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 /*scale*/ ) +{ + if (!::dbtools::implUpdateObject(this, columnIndex, x)) + throw SQLException(); +} + +// XRowLocate +Any SAL_CALL OResultSet::getBookmark( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + if(m_nRowPos < static_cast<sal_Int32>(m_aBookmarks.size())) // this bookmark was already fetched + return Any(sal_Int32(m_nRowPos-1)); + + OLEVariant aVar; + m_pRecordSet->get_Bookmark(&aVar); + m_aBookmarks.push_back(aVar); + return Any(static_cast<sal_Int32>(m_aBookmarks.size()-1)); + +} + +sal_Bool SAL_CALL OResultSet::moveToBookmark( const Any& bookmark ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + sal_Int32 nPos = 0; + bookmark >>= nPos; + OSL_ENSURE(nPos >= 0 && nPos < static_cast<sal_Int32>(m_aBookmarks.size()),"Invalid Index for vector"); + if(nPos < 0 || nPos >= static_cast<sal_Int32>(m_aBookmarks.size())) + ::dbtools::throwFunctionSequenceException(*this); + + return SUCCEEDED(m_pRecordSet->Move(0,m_aBookmarks[nPos])); +} + +sal_Bool SAL_CALL OResultSet::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + sal_Int32 nPos = 0; + bookmark >>= nPos; + nPos += rows; + OSL_ENSURE(nPos >= 0 && nPos < static_cast<sal_Int32>(m_aBookmarks.size()),"Invalid Index for vector"); + if(nPos < 0 || nPos >= static_cast<sal_Int32>(m_aBookmarks.size())) + ::dbtools::throwFunctionSequenceException(*this); + return SUCCEEDED(m_pRecordSet->Move(rows,m_aBookmarks[nPos])); +} + +sal_Int32 SAL_CALL OResultSet::compareBookmarks( const Any& bookmark1, const Any& bookmark2 ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + sal_Int32 nPos1 = 0; + bookmark1 >>= nPos1; + sal_Int32 nPos2 = 0; + bookmark2 >>= nPos2; + if(nPos1 == nPos2) // they should be equal + return css::sdbcx::CompareBookmark::EQUAL; + + OSL_ENSURE((nPos1 >= 0 && nPos1 < static_cast<sal_Int32>(m_aBookmarks.size())) || (nPos1 >= 0 && nPos2 < static_cast<sal_Int32>(m_aBookmarks.size())),"Invalid Index for vector"); + + CompareEnum eNum; + m_pRecordSet->CompareBookmarks(m_aBookmarks[nPos1],m_aBookmarks[nPos2],&eNum); + return static_cast<sal_Int32>(eNum) - 1; +} + +sal_Bool SAL_CALL OResultSet::hasOrderedBookmarks( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + WpADOProperties aProps; + m_pRecordSet->get_Properties(&aProps); + ADOS::ThrowException(static_cast<OConnection*>(m_pStmt->getConnection().get())->getConnection(),*this); + OSL_ENSURE(aProps.IsValid(),"There are no properties at the connection"); + + WpADOProperty aProp(aProps.GetItem(OUString("Bookmarks Ordered"))); + OLEVariant aVar; + if(aProp.IsValid()) + aVar = aProp.GetValue(); + else + ADOS::ThrowException(static_cast<OConnection*>(m_pStmt->getConnection().get())->getConnection(),*this); + + bool bValue(false); + if(!aVar.isNull() && !aVar.isEmpty()) + bValue = aVar.getBool(); + return bValue; +} + +sal_Int32 SAL_CALL OResultSet::hashBookmark( const Any& bookmark ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + sal_Int32 nPos = 0; + bookmark >>= nPos; + return nPos; +} + +// XDeleteRows +Sequence< sal_Int32 > SAL_CALL OResultSet::deleteRows( const Sequence< Any >& rows ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + OLEVariant aVar; + sal_Int32 nPos = 0; + + // Create SafeArray Bounds and initialize the array + SAFEARRAYBOUND rgsabound[1]; + rgsabound[0].lLbound = 0; + rgsabound[0].cElements = rows.getLength(); + SAFEARRAY *psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound ); + + const Any* pBegin = rows.getConstArray(); + const Any* pEnd = pBegin + rows.getLength(); + for(sal_Int32 i=0;pBegin != pEnd ;++pBegin,++i) + { + *pBegin >>= nPos; + SafeArrayPutElement(psa,&i,&m_aBookmarks[nPos]); + } + + // Initialize and fill the SafeArray + OLEVariant vsa; + vsa.setArray(psa,VT_VARIANT); + + m_pRecordSet->put_Filter(vsa); + m_pRecordSet->Delete(adAffectGroup); + m_pRecordSet->UpdateBatch(adAffectGroup); + + Sequence< sal_Int32 > aSeq(rows.getLength()); + if(first()) + { + sal_Int32* pSeq = aSeq.getArray(); + sal_Int32 i=0; + do + { + OSL_ENSURE(i<aSeq.getLength(),"Index greater than length of sequence"); + m_pRecordSet->get_Status(&pSeq[i]); + if(pSeq[i++] == adRecDeleted) + --m_nRowPos; + } + while(next()); + } + return aSeq; +} + +sal_Int32 OResultSet::getResultSetConcurrency() const +{ + sal_Int32 nValue=ResultSetConcurrency::READ_ONLY; + LockTypeEnum eRet; + if(!SUCCEEDED(m_pRecordSet->get_LockType(&eRet))) + { + switch(eRet) + { + case adLockReadOnly: + nValue = ResultSetConcurrency::READ_ONLY; + break; + default: + nValue = ResultSetConcurrency::UPDATABLE; + break; + } + } + return nValue; +} + +sal_Int32 OResultSet::getResultSetType() const +{ + sal_Int32 nValue=0; + CursorTypeEnum eRet; + if(!SUCCEEDED(m_pRecordSet->get_CursorType(&eRet))) + { + switch(eRet) + { + case adOpenUnspecified: + case adOpenForwardOnly: + nValue = ResultSetType::FORWARD_ONLY; + break; + case adOpenStatic: + case adOpenKeyset: + nValue = ResultSetType::SCROLL_INSENSITIVE; + break; + case adOpenDynamic: + nValue = ResultSetType::SCROLL_SENSITIVE; + break; + } + } + return nValue; +} + +sal_Int32 OResultSet::getFetchDirection() +{ + return FetchDirection::FORWARD; +} + +sal_Int32 OResultSet::getFetchSize() const +{ + sal_Int32 nValue=-1; + m_pRecordSet->get_CacheSize(&nValue); + return nValue; +} + +OUString OResultSet::getCursorName() +{ + return OUString(); +} + + +void OResultSet::setFetchDirection(sal_Int32 /*_par0*/) +{ + ::dbtools::throwFeatureNotImplementedSQLException( "ResultSet::FetchDirection", *this ); +} + +void OResultSet::setFetchSize(sal_Int32 _par0) +{ + m_pRecordSet->put_CacheSize(_par0); +} + +::cppu::IPropertyArrayHelper* OResultSet::createArrayHelper( ) const +{ + return new ::cppu::OPropertyArrayHelper + { + { + { + ::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_ISBOOKMARKABLE), + PROPERTY_ID_ISBOOKMARKABLE, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY + }, + { + ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY), + PROPERTY_ID_RESULTSETCONCURRENCY, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY + }, + { + ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE), + PROPERTY_ID_RESULTSETTYPE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY + } + } + }; +} + +::cppu::IPropertyArrayHelper & OResultSet::getInfoHelper() +{ + return *getArrayHelper(); +} + +sal_Bool OResultSet::convertFastPropertyValue( + Any & rConvertedValue, + Any & rOldValue, + sal_Int32 nHandle, + const Any& rValue ) +{ + switch(nHandle) + { + case PROPERTY_ID_ISBOOKMARKABLE: + case PROPERTY_ID_CURSORNAME: + case PROPERTY_ID_RESULTSETCONCURRENCY: + case PROPERTY_ID_RESULTSETTYPE: + throw css::lang::IllegalArgumentException(); + break; + case PROPERTY_ID_FETCHDIRECTION: + return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchDirection()); + case PROPERTY_ID_FETCHSIZE: + return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchSize()); + default: + ; + } + return false; +} + +void OResultSet::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) +{ + switch(nHandle) + { + case PROPERTY_ID_ISBOOKMARKABLE: + case PROPERTY_ID_CURSORNAME: + case PROPERTY_ID_RESULTSETCONCURRENCY: + case PROPERTY_ID_RESULTSETTYPE: + throw Exception("cannot set prop " + OUString::number(nHandle), nullptr); + break; + case PROPERTY_ID_FETCHDIRECTION: + setFetchDirection(getINT32(rValue)); + break; + case PROPERTY_ID_FETCHSIZE: + setFetchSize(getINT32(rValue)); + break; + default: + ; + } +} + +void OResultSet::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const +{ + switch(nHandle) + { + case PROPERTY_ID_ISBOOKMARKABLE: + { + VARIANT_BOOL bBool; + m_pRecordSet->Supports(adBookmark,&bBool); + rValue <<= (bBool == VARIANT_TRUE); + } + break; + case PROPERTY_ID_CURSORNAME: + rValue <<= getCursorName(); + break; + case PROPERTY_ID_RESULTSETCONCURRENCY: + rValue <<= getResultSetConcurrency(); + break; + case PROPERTY_ID_RESULTSETTYPE: + rValue <<= getResultSetType(); + break; + case PROPERTY_ID_FETCHDIRECTION: + rValue <<= getFetchDirection(); + break; + case PROPERTY_ID_FETCHSIZE: + rValue <<= getFetchSize(); + break; + } +} + +void SAL_CALL OResultSet::acquire() noexcept +{ + OResultSet_BASE::acquire(); +} + +void SAL_CALL OResultSet::release() noexcept +{ + OResultSet_BASE::release(); +} + +css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL OResultSet::getPropertySetInfo( ) +{ + return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper()); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AResultSetMetaData.cxx b/connectivity/source/drivers/ado/AResultSetMetaData.cxx new file mode 100644 index 000000000..d43ee5da9 --- /dev/null +++ b/connectivity/source/drivers/ado/AResultSetMetaData.cxx @@ -0,0 +1,247 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <string_view> + +#include <ado/AResultSetMetaData.hxx> +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <ado/Awrapado.hxx> +#include <connectivity/dbexception.hxx> + +using namespace connectivity; +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; + +OResultSetMetaData::OResultSetMetaData( ADORecordset* _pRecordSet) + : m_pRecordSet(_pRecordSet), + m_nColCount(-1) +{ + if ( m_pRecordSet ) + m_pRecordSet->AddRef(); +} + +OResultSetMetaData::~OResultSetMetaData() +{ + if ( m_pRecordSet ) + m_pRecordSet->Release(); +} + +sal_Int32 SAL_CALL OResultSetMetaData::getColumnDisplaySize( sal_Int32 column ) +{ + WpADOField aField = ADOS::getField(m_pRecordSet,column); + if(aField.IsValid() && aField.GetActualSize() != -1) + return aField.GetActualSize(); + return 0; +} + + +sal_Int32 SAL_CALL OResultSetMetaData::getColumnType( sal_Int32 column ) +{ + WpADOField aField = ADOS::getField(m_pRecordSet,column); + return ADOS::MapADOType2Jdbc(aField.GetADOType()); +} + + +sal_Int32 SAL_CALL OResultSetMetaData::getColumnCount( ) +{ + if(m_nColCount != -1 ) + return m_nColCount; + + if ( !m_pRecordSet ) + return 0; + + WpOLEAppendCollection<ADOFields, WpADOField> pFields; + m_pRecordSet->get_Fields(&pFields); + m_nColCount = pFields.GetItemCount(); + return m_nColCount; +} + + +sal_Bool SAL_CALL OResultSetMetaData::isCaseSensitive( sal_Int32 column ) +{ + bool bRet = false; + WpADOField aField = ADOS::getField(m_pRecordSet,column); + if ( aField.IsValid() ) + { + WpADOProperties aProps( aField.get_Properties() ); + if ( aProps.IsValid() ) + bRet = OTools::getValue(aProps, std::u16string_view(u"ISCASESENSITIVE")).getBool(); + } + return bRet; +} + + +OUString SAL_CALL OResultSetMetaData::getSchemaName( sal_Int32 /*column*/ ) +{ + return OUString(); +} + + +OUString SAL_CALL OResultSetMetaData::getColumnName( sal_Int32 column ) +{ + WpADOField aField = ADOS::getField(m_pRecordSet,column); + if(aField.IsValid()) + return aField.GetName(); + + return OUString(); +} + +OUString SAL_CALL OResultSetMetaData::getTableName( sal_Int32 column ) +{ + OUString sTableName; + + WpADOField aField = ADOS::getField(m_pRecordSet,column); + if ( aField.IsValid() ) + { + WpADOProperties aProps( aField.get_Properties() ); + if ( aProps.IsValid() ) + sTableName + = OTools::getValue(aProps, std::u16string_view(u"BASETABLENAME")).getString(); + } + return sTableName; +} + +OUString SAL_CALL OResultSetMetaData::getCatalogName( sal_Int32 /*column*/ ) +{ + return OUString(); +} + +OUString SAL_CALL OResultSetMetaData::getColumnTypeName( sal_Int32 /*column*/ ) +{ + return OUString(); +} + +OUString SAL_CALL OResultSetMetaData::getColumnLabel( sal_Int32 column ) +{ + return getColumnName(column); +} + +OUString SAL_CALL OResultSetMetaData::getColumnServiceName( sal_Int32 /*column*/ ) +{ + return OUString(); +} + + +sal_Bool SAL_CALL OResultSetMetaData::isCurrency( sal_Int32 column ) +{ + WpADOField aField = ADOS::getField(m_pRecordSet,column); + if(aField.IsValid()) + { + return ((aField.GetAttributes() & adFldFixed) == adFldFixed) && (aField.GetADOType() == adCurrency); + } + return false; +} + + +sal_Bool SAL_CALL OResultSetMetaData::isAutoIncrement( sal_Int32 column ) +{ + bool bRet = false; + WpADOField aField = ADOS::getField(m_pRecordSet,column); + if ( aField.IsValid() ) + { + WpADOProperties aProps( aField.get_Properties() ); + if ( aProps.IsValid() ) + { + bRet = OTools::getValue(aProps, std::u16string_view(u"ISAUTOINCREMENT")).getBool(); + } + } + return bRet; +} + + +sal_Bool SAL_CALL OResultSetMetaData::isSigned( sal_Int32 column ) +{ + WpADOField aField = ADOS::getField(m_pRecordSet,column); + if(aField.IsValid()) + { + DataTypeEnum eType = aField.GetADOType(); + return !(eType == adUnsignedBigInt || eType == adUnsignedInt || eType == adUnsignedSmallInt || eType == adUnsignedTinyInt); + } + return false; +} + +sal_Int32 SAL_CALL OResultSetMetaData::getPrecision( sal_Int32 column ) +{ + WpADOField aField = ADOS::getField(m_pRecordSet,column); + if(aField.IsValid()) + return aField.GetPrecision(); + return 0; +} + +sal_Int32 SAL_CALL OResultSetMetaData::getScale( sal_Int32 column ) +{ + WpADOField aField = ADOS::getField(m_pRecordSet,column); + if(aField.IsValid()) + return aField.GetNumericScale(); + return 0; +} + + +sal_Int32 SAL_CALL OResultSetMetaData::isNullable( sal_Int32 column ) +{ + WpADOField aField = ADOS::getField(m_pRecordSet,column); + if(aField.IsValid()) + { + return sal_Int32((aField.GetAttributes() & adFldIsNullable) == adFldIsNullable); + } + return sal_Int32(false); +} + + +sal_Bool SAL_CALL OResultSetMetaData::isSearchable( sal_Int32 /*column*/ ) +{ + return true; +} + + +sal_Bool SAL_CALL OResultSetMetaData::isReadOnly( sal_Int32 column ) +{ + WpADOField aField = ADOS::getField(m_pRecordSet,column); + if(aField.IsValid()) + { + // return (aField.GetStatus() & adFieldReadOnly) == adFieldReadOnly; + } + return false; +} + + +sal_Bool SAL_CALL OResultSetMetaData::isDefinitelyWritable( sal_Int32 column ) +{ + WpADOField aField = ADOS::getField(m_pRecordSet,column); + if(aField.IsValid()) + { + return (aField.GetAttributes() & adFldUpdatable) == adFldUpdatable; + } + return false; +; +} + +sal_Bool SAL_CALL OResultSetMetaData::isWritable( sal_Int32 column ) +{ + return isDefinitelyWritable(column); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AStatement.cxx b/connectivity/source/drivers/ado/AStatement.cxx new file mode 100644 index 000000000..1c48734d8 --- /dev/null +++ b/connectivity/source/drivers/ado/AStatement.cxx @@ -0,0 +1,868 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/AStatement.hxx> +#include <ado/AConnection.hxx> +#include <ado/AResultSet.hxx> +#include <comphelper/property.hxx> +#include <osl/thread.h> +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/queryinterface.hxx> +#include <comphelper/sequence.hxx> +#include <com/sun/star/sdbc/ResultSetConcurrency.hpp> +#include <com/sun/star/sdbc/ResultSetType.hpp> +#include <com/sun/star/sdbc/FetchDirection.hpp> +#include <connectivity/dbexception.hxx> +#include <comphelper/types.hxx> +#include <rtl/ref.hxx> + +#undef max + +#include <algorithm> +#include <numeric> + +using namespace ::comphelper; + +#define CHECK_RETURN(x) \ + if(!x) \ + ADOS::ThrowException(m_pConnection->getConnection(),*this); + + +using namespace connectivity::ado; + + +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace ::std; + +OStatement_Base::OStatement_Base(OConnection* _pConnection ) : OStatement_BASE(m_aMutex) + ,OPropertySetHelper(OStatement_BASE::rBHelper) + ,m_pConnection(_pConnection) + ,m_nMaxRows(0) + ,m_nFetchSize(1) + ,m_eLockType(adLockReadOnly) + ,m_eCursorType(adOpenForwardOnly) +{ + osl_atomic_increment( &m_refCount ); + + m_Command.Create(); + if(m_Command.IsValid()) + m_Command.putref_ActiveConnection(m_pConnection->getConnection()); + else + ADOS::ThrowException(m_pConnection->getConnection(),*this); + + m_RecordsAffected.setNoArg(); + m_Parameters.setNoArg(); + + m_pConnection->acquire(); + + osl_atomic_decrement( &m_refCount ); +} + +void OStatement_Base::disposeResultSet() +{ + // free the cursor if alive + Reference< XComponent > xComp(m_xResultSet.get(), UNO_QUERY); + if (xComp.is()) + xComp->dispose(); + m_xResultSet.clear(); +} + + +void OStatement_Base::disposing() +{ + ::osl::MutexGuard aGuard(m_aMutex); + + + disposeResultSet(); + + if ( m_Command.IsValid() ) + m_Command.putref_ActiveConnection({}); + m_Command.clear(); + + if ( m_RecordSet.IsValid() ) + m_RecordSet.PutRefDataSource( nullptr ); + m_RecordSet.clear(); + + if (m_pConnection) + m_pConnection->release(); + + OStatement_BASE::disposing(); +} + +void SAL_CALL OStatement_Base::release() noexcept +{ + OStatement_BASE::release(); +} + +Any SAL_CALL OStatement_Base::queryInterface( const Type & rType ) +{ + Any aRet = OStatement_BASE::queryInterface(rType); + return aRet.hasValue() ? aRet : OPropertySetHelper::queryInterface(rType); +} + +css::uno::Sequence< css::uno::Type > SAL_CALL OStatement_Base::getTypes( ) +{ + ::cppu::OTypeCollection aTypes( cppu::UnoType<css::beans::XMultiPropertySet>::get(), + cppu::UnoType<css::beans::XFastPropertySet>::get(), + cppu::UnoType<css::beans::XPropertySet>::get()); + + return ::comphelper::concatSequences(aTypes.getTypes(),OStatement_BASE::getTypes()); +} + + +void SAL_CALL OStatement_Base::cancel( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + CHECK_RETURN(m_Command.Cancel()) +} + + +void SAL_CALL OStatement_Base::close( ) +{ + { + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + } + dispose(); +} + + +void SAL_CALL OStatement::clearBatch( ) +{ + +} + + +void OStatement_Base::reset() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + clearWarnings (); + + if (m_xResultSet.get().is()) + clearMyResultSet(); +} + +// clearMyResultSet +// If a ResultSet was created for this Statement, close it + + +void OStatement_Base::clearMyResultSet () +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + try + { + Reference<XCloseable> xCloseable( + m_xResultSet.get(), css::uno::UNO_QUERY); + if ( xCloseable.is() ) + xCloseable->close(); + } + catch( const DisposedException& ) { } + + m_xResultSet.clear(); +} + +sal_Int32 OStatement_Base::getRowCount () +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + return m_RecordsAffected.getInt32(); +} + +// getPrecision +// Given a SQL type, return the maximum precision for the column. +// Returns -1 if not known + + +sal_Int32 OStatement_Base::getPrecision ( sal_Int32 sqlType) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + sal_Int32 prec = -1; + OTypeInfo aInfo; + aInfo.nType = static_cast<sal_Int16>(sqlType); + if (!m_aTypeInfo.empty()) + { + std::vector<OTypeInfo>::const_iterator aIter = std::find(m_aTypeInfo.begin(),m_aTypeInfo.end(),aInfo); + for(;aIter != m_aTypeInfo.end();++aIter) + { + prec = std::max(prec,(*aIter).nPrecision); + } + } + + return prec; +} + +// setWarning +// Sets the warning + + +void OStatement_Base::setWarning (const SQLWarning &ex) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + m_aLastWarning = ex; +} + +void OStatement_Base::assignRecordSet( ADORecordset* _pRS ) +{ + WpADORecordset aOldRS( m_RecordSet ); + m_RecordSet.set( _pRS ); + + if ( aOldRS.IsValid() ) + aOldRS.PutRefDataSource( nullptr ); + + if ( m_RecordSet.IsValid() ) + m_RecordSet.PutRefDataSource( static_cast<IDispatch*>(m_Command) ); +} + +sal_Bool SAL_CALL OStatement_Base::execute( const OUString& sql ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + // Reset the statement handle and warning + + reset(); + + try + { + ADORecordset* pSet = nullptr; + CHECK_RETURN(m_Command.put_CommandText(sql)) + CHECK_RETURN(m_Command.Execute(m_RecordsAffected,m_Parameters,adCmdText,&pSet)) + + assignRecordSet( pSet ); + } + catch (SQLWarning& ex) + { + + // Save pointer to warning and save with ResultSet + // object once it is created. + + m_aLastWarning = ex; + } + + return m_RecordSet.IsValid(); +} + +Reference< XResultSet > SAL_CALL OStatement_Base::executeQuery( const OUString& sql ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + reset(); + + m_xResultSet = WeakReference<XResultSet>(nullptr); + + WpADORecordset aSet; + aSet.Create(); + CHECK_RETURN(m_Command.put_CommandText(sql)) + OLEVariant aCmd; + aCmd.setIDispatch(m_Command); + OLEVariant aCon; + aCon.setNoArg(); + CHECK_RETURN(aSet.put_CacheSize(m_nFetchSize)) + CHECK_RETURN(aSet.put_MaxRecords(m_nMaxRows)) + CHECK_RETURN(aSet.Open(aCmd,aCon,m_eCursorType,m_eLockType,adOpenUnspecified)) + + + CHECK_RETURN(aSet.get_CacheSize(m_nFetchSize)) + CHECK_RETURN(aSet.get_MaxRecords(m_nMaxRows)) + CHECK_RETURN(aSet.get_CursorType(m_eCursorType)) + CHECK_RETURN(aSet.get_LockType(m_eLockType)) + + rtl::Reference<OResultSet> pSet = new OResultSet(aSet,this); + pSet->construct(); + + m_xResultSet = WeakReference<XResultSet>(pSet); + + return pSet; +} + + +Reference< XConnection > SAL_CALL OStatement_Base::getConnection( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + return static_cast<Reference< XConnection >>(m_pConnection); +} + + +Any SAL_CALL OStatement::queryInterface( const Type & rType ) +{ + Any aRet = ::cppu::queryInterface(rType,static_cast< XBatchExecution*> (this)); + return aRet.hasValue() ? aRet : OStatement_Base::queryInterface(rType); +} + + +void SAL_CALL OStatement::addBatch( const OUString& sql ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + m_aBatchVector.push_back(sql); +} + +Sequence< sal_Int32 > SAL_CALL OStatement::executeBatch( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + reset(); + + OUString aBatchSql = std::accumulate(m_aBatchVector.begin(), m_aBatchVector.end(), OUString(), + [](const OUString& rRes, const OUString& rStr) { return rRes + rStr + ";"; }); + sal_Int32 nLen = m_aBatchVector.size(); + + + if ( m_RecordSet.IsValid() ) + m_RecordSet.PutRefDataSource( nullptr ); + m_RecordSet.clear(); + m_RecordSet.Create(); + + CHECK_RETURN(m_Command.put_CommandText(aBatchSql)) + if ( m_RecordSet.IsValid() ) + m_RecordSet.PutRefDataSource(static_cast<IDispatch*>(m_Command)); + + CHECK_RETURN(m_RecordSet.UpdateBatch(adAffectAll)) + + ADORecordset* pSet=nullptr; + Sequence< sal_Int32 > aRet(nLen); + sal_Int32* pArray = aRet.getArray(); + for(sal_Int32 j=0;j<nLen;++j) + { + pSet = nullptr; + OLEVariant aRecordsAffected; + if(m_RecordSet.NextRecordset(aRecordsAffected,&pSet) && pSet) + { + assignRecordSet( pSet ); + + ADO_LONGPTR nValue; + if(m_RecordSet.get_RecordCount(nValue)) + pArray[j] = nValue; + } + } + return aRet; +} + + +sal_Int32 SAL_CALL OStatement_Base::executeUpdate( const OUString& sql ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + reset(); + + try { + ADORecordset* pSet = nullptr; + CHECK_RETURN(m_Command.put_CommandText(sql)) + CHECK_RETURN(m_Command.Execute(m_RecordsAffected,m_Parameters,long(adCmdText)|long(adExecuteNoRecords),&pSet)) + } + catch (SQLWarning& ex) { + + // Save pointer to warning and save with ResultSet + // object once it is created. + + m_aLastWarning = ex; + } + if(!m_RecordsAffected.isEmpty() && !m_RecordsAffected.isNull() && m_RecordsAffected.getType() != VT_ERROR) + return m_RecordsAffected.getInt32(); + + return 0; +} + + +Reference< XResultSet > SAL_CALL OStatement_Base::getResultSet( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + return m_xResultSet; +} + + +sal_Int32 SAL_CALL OStatement_Base::getUpdateCount( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + ADO_LONGPTR nRet; + if(m_RecordSet.IsValid() && m_RecordSet.get_RecordCount(nRet)) + return nRet; + return -1; +} + + +sal_Bool SAL_CALL OStatement_Base::getMoreResults( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + // clear previous warnings + + clearWarnings (); + + // Call SQLMoreResults + + try + { + ADORecordset* pSet=nullptr; + OLEVariant aRecordsAffected; + if(m_RecordSet.IsValid() && m_RecordSet.NextRecordset(aRecordsAffected,&pSet) && pSet) + assignRecordSet( pSet ); + } + catch (SQLWarning &) + { + + //TODO: Save pointer to warning and save with ResultSet + // object once it is created. + } + return m_RecordSet.IsValid(); +} + + +Any SAL_CALL OStatement_Base::getWarnings( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + return Any(m_aLastWarning); +} + + +void SAL_CALL OStatement_Base::clearWarnings( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + m_aLastWarning = SQLWarning(); +} + + +sal_Int32 OStatement_Base::getQueryTimeOut() const +{ + return m_Command.get_CommandTimeout(); +} + +sal_Int32 OStatement_Base::getMaxRows() const +{ + ADO_LONGPTR nRet=-1; + if(!(m_RecordSet.IsValid() && m_RecordSet.get_MaxRecords(nRet))) + ::dbtools::throwFunctionSequenceException(nullptr); + return nRet; +} + +sal_Int32 OStatement_Base::getResultSetConcurrency() const +{ + sal_Int32 nValue; + + switch(m_eLockType) + { + case adLockReadOnly: + nValue = ResultSetConcurrency::READ_ONLY; + break; + default: + nValue = ResultSetConcurrency::UPDATABLE; + break; + } + + return nValue; +} + +sal_Int32 OStatement_Base::getResultSetType() const +{ + sal_Int32 nValue=0; + switch(m_eCursorType) + { + case adOpenUnspecified: + case adOpenForwardOnly: + nValue = ResultSetType::FORWARD_ONLY; + break; + case adOpenStatic: + case adOpenKeyset: + nValue = ResultSetType::SCROLL_INSENSITIVE; + break; + case adOpenDynamic: + nValue = ResultSetType::SCROLL_SENSITIVE; + break; + } + return nValue; +} + +sal_Int32 OStatement_Base::getFetchDirection() +{ + return FetchDirection::FORWARD; +} + +sal_Int32 OStatement_Base::getFetchSize() const +{ + return m_nFetchSize; +} + +sal_Int32 OStatement_Base::getMaxFieldSize() +{ + return 0; +} + +OUString OStatement_Base::getCursorName() const +{ + return m_Command.GetName(); +} + +void OStatement_Base::setQueryTimeOut(sal_Int32 seconds) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + m_Command.put_CommandTimeout(seconds); +} + +void OStatement_Base::setMaxRows(sal_Int32 _par0) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + m_nMaxRows = _par0; +} + +void OStatement_Base::setResultSetConcurrency(sal_Int32 _par0) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + switch(_par0) + { + case ResultSetConcurrency::READ_ONLY: + m_eLockType = adLockReadOnly; + break; + default: + m_eLockType = adLockOptimistic; + break; + } +} + +void OStatement_Base::setResultSetType(sal_Int32 _par0) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + switch(_par0) + { + case ResultSetType::FORWARD_ONLY: + m_eCursorType = adOpenForwardOnly; + break; + case ResultSetType::SCROLL_INSENSITIVE: + m_eCursorType = adOpenKeyset; + break; + case ResultSetType::SCROLL_SENSITIVE: + m_eCursorType = adOpenDynamic; + break; + } +} + +void OStatement_Base::setFetchDirection(sal_Int32 /*_par0*/) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + ::dbtools::throwFeatureNotImplementedSQLException( "Statement::FetchDirection", *this ); +} + +void OStatement_Base::setFetchSize(sal_Int32 _par0) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + + m_nFetchSize = _par0; +} + +void OStatement_Base::setMaxFieldSize(sal_Int32 /*_par0*/) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + ::dbtools::throwFeatureNotImplementedSQLException( "Statement::MaxFieldSize", *this ); +} + +void OStatement_Base::setCursorName(std::u16string_view _par0) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OStatement_BASE::rBHelper.bDisposed); + + m_Command.put_Name(_par0); +} + + +::cppu::IPropertyArrayHelper* OStatement_Base::createArrayHelper( ) const +{ + 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 + } + } + }; +} + + +::cppu::IPropertyArrayHelper & OStatement_Base::getInfoHelper() +{ + return *getArrayHelper(); +} + +sal_Bool OStatement_Base::convertFastPropertyValue( + Any & rConvertedValue, + Any & rOldValue, + sal_Int32 nHandle, + const Any& rValue ) +{ + bool bModified = false; + + bool bValidAdoRS = m_RecordSet.IsValid(); + // some of the properties below, when set, are remembered in a member, and applied in the next execute + // For these properties, the record set does not need to be valid to allow setting them. + // For all others (where the values are forwarded to the ADO RS directly), the recordset must be valid. + + try + { + switch(nHandle) + { + case PROPERTY_ID_MAXROWS: + bModified = ::comphelper::tryPropertyValue( rConvertedValue, rOldValue, rValue, bValidAdoRS ? getMaxRows() : m_nMaxRows ); + break; + + case PROPERTY_ID_RESULTSETTYPE: + bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getResultSetType()); + break; + case PROPERTY_ID_FETCHSIZE: + bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchSize()); + break; + case PROPERTY_ID_RESULTSETCONCURRENCY: + bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getResultSetConcurrency()); + break; + case PROPERTY_ID_QUERYTIMEOUT: + bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getQueryTimeOut()); + break; + case PROPERTY_ID_MAXFIELDSIZE: + bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getMaxFieldSize()); + break; + case PROPERTY_ID_CURSORNAME: + bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getCursorName()); + break; + case PROPERTY_ID_FETCHDIRECTION: + bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchDirection()); + break; + } + } + catch( const Exception& ) + { + bModified = true; // will ensure that the property is set + OSL_FAIL( "OStatement_Base::convertFastPropertyValue: caught something strange!" ); + } + return bModified; +} + +void OStatement_Base::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) +{ + switch(nHandle) + { + case PROPERTY_ID_QUERYTIMEOUT: + setQueryTimeOut(comphelper::getINT32(rValue)); + break; + case PROPERTY_ID_MAXFIELDSIZE: + setMaxFieldSize(comphelper::getINT32(rValue)); + break; + case PROPERTY_ID_MAXROWS: + setMaxRows(comphelper::getINT32(rValue)); + break; + case PROPERTY_ID_CURSORNAME: + setCursorName(comphelper::getString(rValue)); + break; + case PROPERTY_ID_RESULTSETCONCURRENCY: + setResultSetConcurrency(comphelper::getINT32(rValue)); + break; + case PROPERTY_ID_RESULTSETTYPE: + setResultSetType(comphelper::getINT32(rValue)); + break; + case PROPERTY_ID_FETCHDIRECTION: + setFetchDirection(comphelper::getINT32(rValue)); + break; + case PROPERTY_ID_FETCHSIZE: + setFetchSize(comphelper::getINT32(rValue)); + break; + case PROPERTY_ID_ESCAPEPROCESSING: + // return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bAsLink); + case PROPERTY_ID_USEBOOKMARKS: + // return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bAsLink); + default: + ; + } +} + +void OStatement_Base::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const +{ + switch(nHandle) + { + case PROPERTY_ID_QUERYTIMEOUT: + rValue <<= getQueryTimeOut(); + break; + case PROPERTY_ID_MAXFIELDSIZE: + rValue <<= getMaxFieldSize(); + break; + case PROPERTY_ID_MAXROWS: + rValue <<= getMaxRows(); + break; + case PROPERTY_ID_CURSORNAME: + rValue <<= getCursorName(); + break; + case PROPERTY_ID_RESULTSETCONCURRENCY: + rValue <<= getResultSetConcurrency(); + break; + case PROPERTY_ID_RESULTSETTYPE: + rValue <<= getResultSetType(); + break; + case PROPERTY_ID_FETCHDIRECTION: + rValue <<= getFetchDirection(); + break; + case PROPERTY_ID_FETCHSIZE: + rValue <<= getFetchSize(); + break; + case PROPERTY_ID_ESCAPEPROCESSING: + rValue <<= true; + break; + case PROPERTY_ID_USEBOOKMARKS: + default: + ; + } +} + +OStatement::~OStatement() +{ +} +IMPLEMENT_SERVICE_INFO(OStatement,"com.sun.star.sdbcx.AStatement","com.sun.star.sdbc.Statement"); + +void SAL_CALL OStatement_Base::acquire() noexcept +{ + OStatement_BASE::acquire(); +} + +void SAL_CALL OStatement::acquire() noexcept +{ + OStatement_Base::acquire(); +} + +void SAL_CALL OStatement::release() noexcept +{ + OStatement_Base::release(); +} + +css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL OStatement_Base::getPropertySetInfo( ) +{ + return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/ATable.cxx b/connectivity/source/drivers/ado/ATable.cxx new file mode 100644 index 000000000..f048f3ec0 --- /dev/null +++ b/connectivity/source/drivers/ado/ATable.cxx @@ -0,0 +1,230 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <string_view> + +#include <ado/ATable.hxx> +#include <ado/AIndexes.hxx> +#include <ado/AColumns.hxx> +#include <ado/AColumn.hxx> +#include <ado/AKeys.hxx> +#include <ado/AConnection.hxx> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbcx/KeyType.hpp> +#include <com/sun/star/sdbc/KeyRule.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <ado/Awrapado.hxx> +#include <TConnection.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/types.hxx> + +using namespace ::comphelper; + +using namespace connectivity; +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::container; + + +OAdoTable::OAdoTable(sdbcx::OCollection* _pTables,bool _bCase,OCatalog* _pCatalog,_ADOTable* _pTable) + : OTable_TYPEDEF(_pTables,_bCase) + ,m_pCatalog(_pCatalog) +{ + construct(); + m_aTable.set(_pTable); + // m_aTable.putref_ParentCatalog(_pCatalog->getCatalog()); + fillPropertyValues(); + +} + +OAdoTable::OAdoTable(sdbcx::OCollection* _pTables,bool _bCase,OCatalog* _pCatalog) + : OTable_TYPEDEF(_pTables,_bCase) + ,m_pCatalog(_pCatalog) +{ + construct(); + m_aTable.Create(); + m_aTable.putref_ParentCatalog(_pCatalog->getCatalog()); + +} + +void SAL_CALL OAdoTable::disposing() +{ + OTable_TYPEDEF::disposing(); + m_aTable.clear(); +} + +void OAdoTable::refreshColumns() +{ + ::std::vector< OUString> aVector; + + WpADOColumns aColumns; + if ( m_aTable.IsValid() ) + { + aColumns = m_aTable.get_Columns(); + aColumns.fillElementNames(aVector); + } + + if(m_xColumns) + m_xColumns->reFill(aVector); + else + m_xColumns.reset(new OColumns(*this,m_aMutex,aVector,aColumns,isCaseSensitive(),m_pCatalog->getConnection())); +} + +void OAdoTable::refreshKeys() +{ + ::std::vector< OUString> aVector; + + WpADOKeys aKeys; + if(m_aTable.IsValid()) + { + aKeys = m_aTable.get_Keys(); + aKeys.fillElementNames(aVector); + } + + if(m_xKeys) + m_xKeys->reFill(aVector); + else + m_xKeys.reset(new OKeys(*this,m_aMutex,aVector,aKeys,isCaseSensitive(),m_pCatalog->getConnection())); +} + +void OAdoTable::refreshIndexes() +{ + ::std::vector< OUString> aVector; + + WpADOIndexes aIndexes; + if(m_aTable.IsValid()) + { + aIndexes = m_aTable.get_Indexes(); + aIndexes.fillElementNames(aVector); + } + + if(m_xIndexes) + m_xIndexes->reFill(aVector); + else + m_xIndexes.reset(new OIndexes(*this,m_aMutex,aVector,aIndexes,isCaseSensitive(),m_pCatalog->getConnection())); +} + +Sequence< sal_Int8 > OAdoTable::getUnoTunnelId() +{ + static const comphelper::UnoIdInit implId; + return implId.getSeq(); +} + +// css::lang::XUnoTunnel + +sal_Int64 OAdoTable::getSomething( const Sequence< sal_Int8 > & rId ) +{ + return comphelper::getSomethingImpl(rId, this, + comphelper::FallbackToGetSomethingOf<OTable_TYPEDEF>{}); +} + +// XRename +void SAL_CALL OAdoTable::rename( const OUString& newName ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OTableDescriptor_BASE_TYPEDEF::rBHelper.bDisposed); + + m_aTable.put_Name(newName); + ADOS::ThrowException(m_pCatalog->getConnection()->getConnection(),*this); + + OTable_TYPEDEF::rename(newName); +} + +Reference< XDatabaseMetaData> OAdoTable::getMetaData() const +{ + return m_pCatalog->getConnection()->getMetaData(); +} + +// XAlterTable +void SAL_CALL OAdoTable::alterColumnByName( const OUString& colName, const Reference< XPropertySet >& descriptor ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OTableDescriptor_BASE_TYPEDEF::rBHelper.bDisposed); + + bool bError = true; + OAdoColumn* pColumn = comphelper::getFromUnoTunnel<OAdoColumn>(descriptor); + if(pColumn != nullptr) + { + WpADOColumns aColumns = m_aTable.get_Columns(); + bError = !aColumns.Delete(colName); + bError = bError || !aColumns.Append(pColumn->getColumnImpl()); + } + if(bError) + ADOS::ThrowException(m_pCatalog->getConnection()->getConnection(),*this); + + m_xColumns->refresh(); + refreshColumns(); +} + +void SAL_CALL OAdoTable::alterColumnByIndex( sal_Int32 index, const Reference< XPropertySet >& descriptor ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OTableDescriptor_BASE_TYPEDEF::rBHelper.bDisposed); + + Reference< XPropertySet > xOld; + m_xColumns->getByIndex(index) >>= xOld; + if(xOld.is()) + alterColumnByName(getString(xOld->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME))),descriptor); +} + +void OAdoTable::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) +{ + if(m_aTable.IsValid()) + { + switch(nHandle) + { + case PROPERTY_ID_NAME: + m_aTable.put_Name(getString(rValue)); + break; + + case PROPERTY_ID_TYPE: + OTools::putValue( m_aTable.get_Properties(), + OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE), + getString(rValue)); + break; + + case PROPERTY_ID_DESCRIPTION: + OTools::putValue( m_aTable.get_Properties(), + std::u16string_view(u"Description"), + getString(rValue)); + break; + + case PROPERTY_ID_SCHEMANAME: + break; + + default: + throw Exception("unknown prop " + OUString::number(nHandle), nullptr); + } + } + OTable_TYPEDEF::setFastPropertyValue_NoBroadcast(nHandle,rValue); +} + +OUString SAL_CALL OAdoTable::getName() +{ + return m_aTable.get_Name(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/ATables.cxx b/connectivity/source/drivers/ado/ATables.cxx new file mode 100644 index 000000000..234a41fa5 --- /dev/null +++ b/connectivity/source/drivers/ado/ATables.cxx @@ -0,0 +1,103 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/ATables.hxx> +#include <ado/ATable.hxx> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <com/sun/star/sdbc/KeyRule.hpp> +#include <com/sun/star/sdbcx/KeyType.hpp> +#include <ado/ACatalog.hxx> +#include <ado/AConnection.hxx> +#include <ado/Awrapado.hxx> +#include <TConnection.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/types.hxx> +#include <cppuhelper/interfacecontainer.h> +#include <connectivity/dbexception.hxx> +#include <strings.hrc> + +using namespace ::cppu; +using namespace connectivity; +using namespace comphelper; +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::container; + +sdbcx::ObjectType OTables::createObject(const OUString& _rName) +{ + OSL_ENSURE(m_aCollection.IsValid(),"Collection isn't valid"); + return new OAdoTable(this,isCaseSensitive(),m_pCatalog,m_aCollection.GetItem(_rName)); +} + +void OTables::impl_refresh( ) +{ + OSL_ENSURE(m_aCollection.IsValid(),"Collection isn't valid"); + m_aCollection.Refresh(); + m_pCatalog->refreshTables(); +} + +Reference< XPropertySet > OTables::createDescriptor() +{ + return new OAdoTable(this,isCaseSensitive(),m_pCatalog); +} + +// XAppend +sdbcx::ObjectType OTables::appendObject( const OUString&, const Reference< XPropertySet >& descriptor ) +{ + OAdoTable* pTable = getFromUnoTunnel<OAdoTable>( descriptor ); + if ( pTable == nullptr ) + m_pCatalog->getConnection()->throwGenericSQLException( STR_INVALID_TABLE_DESCRIPTOR_ERROR,static_cast<XTypeProvider*>(this) ); + + OSL_ENSURE(m_aCollection.IsValid(),"Collection isn't valid"); + if(!m_aCollection.Append(pTable->getImpl())) + ADOS::ThrowException(m_pCatalog->getConnection()->getConnection(),static_cast<XTypeProvider*>(this)); + m_aCollection.Refresh(); + + return new OAdoTable(this,isCaseSensitive(),m_pCatalog,pTable->getImpl()); +} + +// XDrop +void OTables::dropObject(sal_Int32 /*_nPos*/,const OUString& _sElementName) +{ + OSL_ENSURE(m_aCollection.IsValid(),"Collection isn't valid"); + if ( !m_aCollection.Delete(_sElementName) ) + ADOS::ThrowException(m_pCatalog->getConnection()->getConnection(),static_cast<XTypeProvider*>(this)); +} + +void OTables::appendNew(const OUString& _rsNewTable) +{ + OSL_ENSURE(m_aCollection.IsValid(),"Collection isn't valid"); + m_aCollection.Refresh(); + + insertElement(_rsNewTable,nullptr); + + // notify our container listeners + ContainerEvent aEvent(static_cast<XContainer*>(this), Any(_rsNewTable), Any(), Any()); + OInterfaceIteratorHelper3 aListenerLoop(m_aContainerListeners); + while (aListenerLoop.hasMoreElements()) + aListenerLoop.next()->elementInserted(aEvent); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AUser.cxx b/connectivity/source/drivers/ado/AUser.cxx new file mode 100644 index 000000000..42f7240f8 --- /dev/null +++ b/connectivity/source/drivers/ado/AUser.cxx @@ -0,0 +1,190 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/AUser.hxx> +#include <ado/ACatalog.hxx> +#include <ado/AGroups.hxx> +#include <comphelper/servicehelper.hxx> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <ado/AConnection.hxx> +#include <ado/Awrapado.hxx> + +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; + + +OAdoUser::OAdoUser(OCatalog* _pParent,bool _bCase, ADOUser* _pUser) + : OUser_TYPEDEF(_bCase) + ,m_pCatalog(_pParent) +{ + construct(); + + if(_pUser) + m_aUser.set(_pUser); + else + m_aUser.Create(); +} + +OAdoUser::OAdoUser(OCatalog* _pParent,bool _bCase, const OUString& Name) + : OUser_TYPEDEF(Name,_bCase) + , m_pCatalog(_pParent) +{ + construct(); + m_aUser.Create(); + m_aUser.put_Name(Name); +} + +void OAdoUser::refreshGroups() +{ + ::std::vector< OUString> aVector; + WpADOGroups aGroups(m_aUser.get_Groups()); + aGroups.fillElementNames(aVector); + if(m_pGroups) + m_pGroups->reFill(aVector); + else + m_pGroups.reset(new OGroups(m_pCatalog, m_aMutex, aVector, aGroups, isCaseSensitive())); +} + +Sequence< sal_Int8 > OAdoUser::getUnoTunnelId() +{ + static const comphelper::UnoIdInit implId; + return implId.getSeq(); +} + +// css::lang::XUnoTunnel + +sal_Int64 OAdoUser::getSomething( const Sequence< sal_Int8 > & rId ) +{ + return comphelper::getSomethingImpl(rId, this, + comphelper::FallbackToGetSomethingOf<OUser_TYPEDEF>{}); +} + + +void OAdoUser::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) +{ + if(m_aUser.IsValid()) + { + + switch(nHandle) + { + case PROPERTY_ID_NAME: + { + OUString aVal; + rValue >>= aVal; + m_aUser.put_Name(aVal); + } + break; + } + } +} + +void OAdoUser::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const +{ + if(m_aUser.IsValid()) + { + switch(nHandle) + { + case PROPERTY_ID_NAME: + rValue <<= m_aUser.get_Name(); + break; + } + } +} + +OUserExtend::OUserExtend(OCatalog* _pParent,bool _bCase, ADOUser* _pUser) + : OAdoUser(_pParent,_bCase,_pUser) +{ +} + +OUserExtend::OUserExtend(OCatalog* _pParent,bool _bCase, const OUString& Name) + : OAdoUser(_pParent,_bCase,Name) +{ +} + + +void OUserExtend::construct() +{ + OUser_TYPEDEF::construct(); + registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD), PROPERTY_ID_PASSWORD,0,&m_Password,::cppu::UnoType<OUString>::get()); +} + +cppu::IPropertyArrayHelper* OUserExtend::createArrayHelper() const +{ + Sequence< css::beans::Property > aProps; + describeProperties(aProps); + return new cppu::OPropertyArrayHelper(aProps); +} + +cppu::IPropertyArrayHelper & OUserExtend::getInfoHelper() +{ + return *OUserExtend_PROP::getArrayHelper(); +} + +sal_Int32 SAL_CALL OAdoUser::getPrivileges( const OUString& objName, sal_Int32 objType ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OUser_BASE_TYPEDEF::rBHelper.bDisposed); + + return ADOS::mapAdoRights2Sdbc(m_aUser.GetPermissions(objName, ADOS::mapObjectType2Ado(objType))); +} + +sal_Int32 SAL_CALL OAdoUser::getGrantablePrivileges( const OUString& objName, sal_Int32 objType ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OUser_BASE_TYPEDEF::rBHelper.bDisposed); + + sal_Int32 nRights = 0; + RightsEnum eRights = m_aUser.GetPermissions(objName, ADOS::mapObjectType2Ado(objType)); + if((eRights & adRightWithGrant) == adRightWithGrant) + nRights = ADOS::mapAdoRights2Sdbc(eRights); + ADOS::ThrowException(m_pCatalog->getConnection()->getConnection(),*this); + return nRights; +} + +void SAL_CALL OAdoUser::grantPrivileges( const OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OUser_BASE_TYPEDEF::rBHelper.bDisposed); + m_aUser.SetPermissions(objName,ADOS::mapObjectType2Ado(objType),adAccessGrant,RightsEnum(ADOS::mapRights2Ado(objPrivileges))); + ADOS::ThrowException(m_pCatalog->getConnection()->getConnection(),*this); +} + +void SAL_CALL OAdoUser::revokePrivileges( const OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OUser_BASE_TYPEDEF::rBHelper.bDisposed); + m_aUser.SetPermissions(objName,ADOS::mapObjectType2Ado(objType),adAccessRevoke,RightsEnum(ADOS::mapRights2Ado(objPrivileges))); + ADOS::ThrowException(m_pCatalog->getConnection()->getConnection(),*this); +} + +// XUser +void SAL_CALL OAdoUser::changePassword( const OUString& objPassword, const OUString& newPassword ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OUser_BASE_TYPEDEF::rBHelper.bDisposed); + m_aUser.ChangePassword(objPassword,newPassword); + ADOS::ThrowException(m_pCatalog->getConnection()->getConnection(),*this); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AUsers.cxx b/connectivity/source/drivers/ado/AUsers.cxx new file mode 100644 index 000000000..407433091 --- /dev/null +++ b/connectivity/source/drivers/ado/AUsers.cxx @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/AUsers.hxx> +#include <ado/AUser.hxx> +#include <ado/ATable.hxx> +#include <ado/AConnection.hxx> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <connectivity/sdbcx/IRefreshable.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/types.hxx> +#include <connectivity/dbexception.hxx> +#include <systools/win32/oleauto.hxx> +#include <strings.hrc> + +using namespace comphelper; +using namespace connectivity; +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::container; + +sdbcx::ObjectType OUsers::createObject(const OUString& _rName) +{ + return new OAdoUser(m_pCatalog,isCaseSensitive(),_rName); +} + +void OUsers::impl_refresh() +{ + m_aCollection.Refresh(); +} + +Reference< XPropertySet > OUsers::createDescriptor() +{ + return new OUserExtend(m_pCatalog,isCaseSensitive()); +} + +// XAppend +sdbcx::ObjectType OUsers::appendObject( const OUString& _rForName, const Reference< XPropertySet >& descriptor ) +{ + OUserExtend* pUser = getFromUnoTunnel<OUserExtend>( descriptor ); + if ( pUser == nullptr ) + m_pCatalog->getConnection()->throwGenericSQLException( STR_INVALID_USER_DESCRIPTOR_ERROR,static_cast<XTypeProvider*>(this) ); + + ADOUsers* pUsers = m_aCollection; + pUsers->Append(OLEVariant(pUser->getImpl()), sal::systools::BStr(pUser->getPassword())); + + return createObject( _rForName ); +} + +// XDrop +void OUsers::dropObject(sal_Int32 /*_nPos*/,const OUString& _sElementName) +{ + m_aCollection.Delete(_sElementName); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AView.cxx b/connectivity/source/drivers/ado/AView.cxx new file mode 100644 index 000000000..3b88116bc --- /dev/null +++ b/connectivity/source/drivers/ado/AView.cxx @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/AView.hxx> +#include <com/sun/star/lang/DisposedException.hpp> +#include <ado/adoimp.hxx> +#include <ado/Awrapado.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/types.hxx> +#include <systools/win32/oleauto.hxx> + +#include <TConnection.hxx> + + +using namespace comphelper; +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; + +// IMPLEMENT_SERVICE_INFO(OAdoView,"com.sun.star.sdbcx.AView","com.sun.star.sdbcx.View"); + +OAdoView::OAdoView(bool _bCase,ADOView* _pView) : OView_ADO(_bCase,nullptr) +,m_aView(_pView) +{ +} + +Sequence< sal_Int8 > OAdoView::getUnoTunnelId() +{ + static const comphelper::UnoIdInit implId; + return implId.getSeq(); +} + +// css::lang::XUnoTunnel + +sal_Int64 OAdoView::getSomething( const Sequence< sal_Int8 > & rId ) +{ + return comphelper::getSomethingImpl(rId, this, + comphelper::FallbackToGetSomethingOf<OView_ADO>{}); +} + + +void OAdoView::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const +{ + if(m_aView.IsValid()) + { + switch(nHandle) + { + case PROPERTY_ID_NAME: + rValue <<= m_aView.get_Name(); + break; + case PROPERTY_ID_CATALOGNAME: + break; + case PROPERTY_ID_SCHEMANAME: + // rValue <<= m_aView.get_Type(); + break; + case PROPERTY_ID_COMMAND: + { + OLEVariant aVar; + m_aView.get_Command(aVar); + if(!aVar.isNull() && !aVar.isEmpty()) + { + ADOCommand* pCom = static_cast<ADOCommand*>(aVar.getIDispatch()); + sal::systools::BStr aBSTR; + pCom->get_CommandText(&aBSTR); + rValue <<= OUString(aBSTR); + } + } + break; + } + } + else + OView_ADO::getFastPropertyValue(rValue,nHandle); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/AViews.cxx b/connectivity/source/drivers/ado/AViews.cxx new file mode 100644 index 000000000..38f9ae4d7 --- /dev/null +++ b/connectivity/source/drivers/ado/AViews.cxx @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/AViews.hxx> +#include <ado/AView.hxx> +#include <ado/ATables.hxx> +#include <ado/ACatalog.hxx> +#include <ado/AConnection.hxx> +#include <ado/Awrapado.hxx> +#include <TConnection.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/types.hxx> +#include <connectivity/dbexception.hxx> +#include <rtl/ref.hxx> +#include <systools/win32/oleauto.hxx> + +#include <strings.hrc> + +using namespace ::comphelper; + +using namespace connectivity; +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::container; + +sdbcx::ObjectType OViews::createObject(const OUString& _rName) +{ + rtl::Reference<OAdoView> pView = new OAdoView(isCaseSensitive(),m_aCollection.GetItem(_rName)); + pView->setNew(false); + return pView; +} + +void OViews::impl_refresh( ) +{ + m_aCollection.Refresh(); +} + +Reference< XPropertySet > OViews::createDescriptor() +{ + return new OAdoView(isCaseSensitive()); +} + + +// XAppend +sdbcx::ObjectType OViews::appendObject( const OUString& _rForName, const Reference< XPropertySet >& descriptor ) +{ + OAdoView* pView = getFromUnoTunnel<OAdoView>( descriptor ); + if ( pView == nullptr ) + m_pCatalog->getConnection()->throwGenericSQLException( STR_INVALID_VIEW_DESCRIPTOR_ERROR,static_cast<XTypeProvider*>(this) ); + + WpADOCommand aCommand; + aCommand.Create(); + if ( !aCommand.IsValid() ) + m_pCatalog->getConnection()->throwGenericSQLException( STR_VIEW_NO_COMMAND_ERROR,static_cast<XTypeProvider*>(this) ); + + OUString sName( _rForName ); + aCommand.put_Name(sName); + aCommand.put_CommandText(getString(descriptor->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_COMMAND)))); + ADOViews* pViews = m_aCollection; + if (FAILED(pViews->Append(sal::systools::BStr(sName), aCommand))) + ADOS::ThrowException(m_pCatalog->getConnection()->getConnection(),static_cast<XTypeProvider*>(this)); + + OTables* pTables = static_cast<OTables*>(static_cast<OCatalog&>(m_rParent).getPrivateTables()); + if ( pTables ) + pTables->appendNew(sName); + + return createObject( _rForName ); +} + +// XDrop +void OViews::dropObject(sal_Int32 /*_nPos*/,const OUString& _sElementName) +{ + if(!m_aCollection.Delete(_sElementName)) + ADOS::ThrowException(m_pCatalog->getConnection()->getConnection(),static_cast<XTypeProvider*>(this)); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/Aolevariant.cxx b/connectivity/source/drivers/ado/Aolevariant.cxx new file mode 100644 index 000000000..c082c1987 --- /dev/null +++ b/connectivity/source/drivers/ado/Aolevariant.cxx @@ -0,0 +1,687 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ado/Aolevariant.hxx> +#include <connectivity/dbconversion.hxx> +#include <osl/diagnose.h> +#include <o3tl/char16_t2wchar_t.hxx> +#include <com/sun/star/sdbc/SQLException.hpp> +#include <com/sun/star/util/Time.hpp> +#include <com/sun/star/util/Date.hpp> +#include <com/sun/star/util/DateTime.hpp> +#include <resource/sharedresources.hxx> +#include <strings.hrc> +#include <com/sun/star/bridge/oleautomation/Date.hpp> +#include <com/sun/star/bridge/oleautomation/Currency.hpp> +#include <com/sun/star/bridge/oleautomation/SCode.hpp> +#include <com/sun/star/bridge/oleautomation/Decimal.hpp> + +using namespace com::sun::star::beans; +using namespace com::sun::star::uno; +using namespace com::sun::star::bridge::oleautomation; +using namespace connectivity::ado; + +OLEVariant::OLEVariant() +{ + VariantInit(this); +} +OLEVariant::OLEVariant(const VARIANT& varSrc) +{ + ::VariantInit(this); + HRESULT eRet = ::VariantCopy(this, &varSrc); + OSL_ENSURE(eRet == S_OK,"Error while copying an ado variant!"); +} +OLEVariant::OLEVariant(const OLEVariant& varSrc) +{ + ::VariantInit(this); + HRESULT eRet = ::VariantCopy(this, static_cast<const VARIANT*>(&varSrc)); + OSL_ENSURE(eRet == S_OK,"Error while copying an ado variant!"); +} + +OLEVariant::OLEVariant(bool x) { VariantInit(this); vt = VT_BOOL; boolVal = (x ? VARIANT_TRUE : VARIANT_FALSE);} +OLEVariant::OLEVariant(sal_Int8 n) { VariantInit(this); vt = VT_I1; bVal = n;} +OLEVariant::OLEVariant(sal_Int16 n) { VariantInit(this); vt = VT_I2; intVal = n;} +OLEVariant::OLEVariant(sal_Int32 n) { VariantInit(this); vt = VT_I4; lVal = n;} +OLEVariant::OLEVariant(sal_Int64 x) { VariantInit(this); vt = VT_I4; lVal = static_cast<LONG>(x);} + +OLEVariant::OLEVariant(std::u16string_view us) +{ + ::VariantInit(this); + vt = VT_BSTR; + bstrVal = SysAllocStringLen(o3tl::toW(us.data()), us.length()); +} +OLEVariant::~OLEVariant() +{ + HRESULT eRet = ::VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); +} // clears all the memory that was allocated before + +OLEVariant::OLEVariant(const css::util::Date& x ) +{ + VariantInit(this); + vt = VT_DATE; + dblVal = ::dbtools::DBTypeConversion::toDouble(x,css::util::Date(30,12,1899)); +} +OLEVariant::OLEVariant(const css::util::Time& x ) +{ + VariantInit(this); + vt = VT_DATE; + dblVal = ::dbtools::DBTypeConversion::toDouble(x); +} +OLEVariant::OLEVariant(const css::util::DateTime& x ) +{ + VariantInit(this); + vt = VT_DATE; + dblVal = ::dbtools::DBTypeConversion::toDouble(x,css::util::Date(30,12,1899)); +} +OLEVariant::OLEVariant(float x) +{ + VariantInit(this); + vt = VT_R4; + fltVal = x; +} +OLEVariant::OLEVariant(const double &x) +{ + VariantInit(this); + vt = VT_R8; + dblVal = x; +} + + +OLEVariant::OLEVariant(IDispatch* pDispInterface) +{ + VariantInit(this); + setIDispatch( pDispInterface ); +} + +OLEVariant::OLEVariant(const css::uno::Sequence< sal_Int8 >& x) +{ + VariantInit(this); + + vt = VT_ARRAY|VT_UI1; + + parray = SafeArrayCreateVector(VT_UI1, 0, x.getLength()); + const sal_Int8* pBegin = x.getConstArray(); + const sal_Int8* pEnd = pBegin + x.getLength(); + + for(sal_Int32 i=0;pBegin != pEnd;++i,++pBegin) + { + sal_Int32 nData = *pBegin; + HRESULT rs = SafeArrayPutElement(parray,&i,&nData); + OSL_ENSURE(S_OK == rs,"Error while copy byte data"); + } +} + +OLEVariant& OLEVariant::operator=(const OLEVariant& varSrc) +{ + HRESULT eRet = ::VariantCopy(this, static_cast<const VARIANT*>(&varSrc)); + OSL_ENSURE(eRet == S_OK,"Error while copying an ado variant!"); + return *this; +} +// Assign a const VARIANT& (::VariantCopy handles everything) + +OLEVariant& OLEVariant::operator=(const tagVARIANT& varSrc) +{ + HRESULT eRet = ::VariantCopy(this, &varSrc); + OSL_ENSURE(eRet == S_OK,"Error while copying an ado variant!"); + + return *this; +} + +// Assign a const VARIANT* (::VariantCopy handles everything) + +OLEVariant& OLEVariant::operator=(const VARIANT* pSrc) +{ + HRESULT eRet = ::VariantCopy(this, pSrc); + OSL_ENSURE(eRet == S_OK,"Error while copying an ado variant!"); + + return *this; +} + +void OLEVariant::setByte(sal_uInt8 n) +{ + HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + vt = VT_UI1; + bVal = n; +} +void OLEVariant::setInt16(sal_Int16 n) +{ + HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + vt = VT_I2; + iVal = n; +} +void OLEVariant::setInt32(sal_Int32 n) +{ + HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + vt = VT_I4; + lVal = n; +} +void OLEVariant::setFloat(float f) +{ HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + vt = VT_R4; + fltVal = f; +} +void OLEVariant::setDouble(double d) +{ + HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + vt = VT_R8; + dblVal = d; +} +void OLEVariant::setDate(DATE d) +{ HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + vt = VT_DATE; + date = d; +} +void OLEVariant::setChar(unsigned char a) +{ + HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + vt = VT_UI1; + bVal = a; +} +void OLEVariant::setCurrency(double aCur) +{ + HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + vt = VT_CY; + set(aCur*10000); +} +void OLEVariant::setBool(bool b) +{ + HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + vt = VT_BOOL; + boolVal = b ? VARIANT_TRUE : VARIANT_FALSE; +} +void OLEVariant::setString(std::u16string_view us) +{ + HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + vt = VT_BSTR; + bstrVal = SysAllocStringLen(o3tl::toW(us.data()), us.length()); +} +void OLEVariant::setNoArg() +{ + HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + vt = VT_ERROR; + scode = DISP_E_PARAMNOTFOUND; +} + +void OLEVariant::setNull() +{ + HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + vt = VT_NULL; +} +void OLEVariant::setEmpty() +{ + HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + vt = VT_EMPTY; +} + +void OLEVariant::setUI1SAFEARRAYPtr(SAFEARRAY* pSafeAr) +{ + HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + vt = VT_ARRAY|VT_UI1; parray = pSafeAr; +} + +void OLEVariant::setArray(SAFEARRAY* pSafeArray, VARTYPE vtType) +{ + HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + vt = static_cast<VARTYPE>(VT_ARRAY|vtType); + parray = pSafeArray; +} + +void OLEVariant::setIDispatch(IDispatch* pDispInterface) +{ + HRESULT eRet = VariantClear(this); + OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!"); + + vt = VT_DISPATCH; + pdispVal = pDispInterface; + + if ( pDispInterface ) + pDispInterface->AddRef(); +} + + +bool OLEVariant::isNull() const { return (vt == VT_NULL); } +bool OLEVariant::isEmpty() const { return (vt == VT_EMPTY); } + +VARTYPE OLEVariant::getType() const { return vt; } + +css::util::Date OLEVariant::getDate() const +{ + return isNull() ? css::util::Date(30,12,1899) : ::dbtools::DBTypeConversion::toDate(getDateAsDouble(),css::util::Date(30,12,1899)); +} +css::util::Time OLEVariant::getTime() const +{ + return isNull() ? css::util::Time() : ::dbtools::DBTypeConversion::toTime(getDateAsDouble()); +} +css::util::DateTime OLEVariant::getDateTime() const +{ + return isNull() ? css::util::DateTime() : ::dbtools::DBTypeConversion::toDateTime(getDateAsDouble(),css::util::Date(30,12,1899)); +} + +VARIANT_BOOL OLEVariant::VariantBool(bool bEinBoolean) +{ + return (bEinBoolean ? VARIANT_TRUE : VARIANT_FALSE); +} + +void OLEVariant::CHS() +{ + cyVal.Lo ^= sal_uInt32(-1); + cyVal.Hi ^= -1; + cyVal.Lo++; + if( !cyVal.Lo ) + cyVal.Hi++; +} + +void OLEVariant::set(double n) +{ + if( n >= 0 ) + { + cyVal.Hi = static_cast<sal_Int32>(n / 4294967296.0); + cyVal.Lo = static_cast<sal_uInt32>(n - (static_cast<double>(cyVal.Hi) * 4294967296.0)); + } + else { + cyVal.Hi = static_cast<sal_Int32>(-n / 4294967296.0); + cyVal.Lo = static_cast<sal_uInt32>(-n - (static_cast<double>(cyVal.Hi) * 4294967296.0)); + CHS(); + } +} + +OUString OLEVariant::getString() const +{ + if (V_VT(this) == VT_BSTR) + return OUString(o3tl::toU(V_BSTR(this))); + + if(isNull()) + return OUString(); + + OLEVariant varDest; + + varDest.ChangeType(VT_BSTR, this); + + return OUString(o3tl::toU(V_BSTR(&varDest))); +} + + +void OLEVariant::ChangeType(VARTYPE vartype, const OLEVariant* pSrc) +{ + + // If pDest is NULL, convert type in place + + if (pSrc == nullptr) + pSrc = this; + + if ( ( this != pSrc ) + || ( vartype != V_VT( this ) ) + ) + { + if ( FAILED( ::VariantChangeType( static_cast< VARIANT* >( this ), + static_cast< const VARIANT* >( pSrc ), + 0, + vartype ) ) ) + { + ::connectivity::SharedResources aResources; + const OUString sError( aResources.getResourceString(STR_TYPE_NOT_CONVERT)); + throw css::sdbc::SQLException( + sError, + nullptr, + "S1000", + 1000, + css::uno::Any() + ); + } + } +} + + +css::uno::Sequence< sal_Int8 > OLEVariant::getByteSequence() const +{ + css::uno::Sequence< sal_Int8 > aRet; + if(V_VT(this) == VT_BSTR) + { + aRet = css::uno::Sequence<sal_Int8>(reinterpret_cast<sal_Int8*>(V_BSTR(this)), + ::SysStringByteLen(V_BSTR(this))); + } + else if(!isNull()) + { + SAFEARRAY* pArray = getUI1SAFEARRAYPtr(); + + if(pArray) + { + HRESULT hresult1,hresult2; + LONG lBound,uBound; + // Verify that the SafeArray is the proper shape. + hresult1 = ::SafeArrayGetLBound(pArray, 1, &lBound); + hresult2 = ::SafeArrayGetUBound(pArray, 1, &uBound); + if ( SUCCEEDED(hresult1) && SUCCEEDED(hresult2) ) + { + LONG nCount = uBound-lBound+1; + aRet.realloc(nCount); + sal_Int8* pData = aRet.getArray(); + for(; SUCCEEDED(hresult1) && lBound <= uBound ;++lBound) + { + sal_Int32 nData = 0; + hresult1 = ::SafeArrayGetElement(pArray,&lBound,&nData); + if ( SUCCEEDED(hresult1) ) + { + *pData = static_cast<sal_Int8>(nData); + ++pData; + } + } + } + } + } + + return aRet; +} + +bool OLEVariant::getBool() const +{ + if (V_VT(this) == VT_BOOL) + return V_BOOL(this) == VARIANT_TRUE; + if(isNull()) + return false; + + OLEVariant varDest; + + varDest.ChangeType(VT_BOOL, this); + + return V_BOOL(&varDest) == VARIANT_TRUE; +} + +IUnknown* OLEVariant::getIUnknown() const +{ + if (V_VT(this) == VT_UNKNOWN) + { + return V_UNKNOWN(this); + } + if(isNull()) + return nullptr; + + OLEVariant varDest; + + varDest.ChangeType(VT_UNKNOWN, this); + + V_UNKNOWN(&varDest)->AddRef(); + return V_UNKNOWN(&varDest); +} + +IDispatch* OLEVariant::getIDispatch() const +{ + if (V_VT(this) == VT_DISPATCH) + { + return V_DISPATCH(this); + } + + if(isNull()) + return nullptr; + + OLEVariant varDest; + + varDest.ChangeType(VT_DISPATCH, this); + + V_DISPATCH(&varDest)->AddRef(); + return V_DISPATCH(&varDest); +} + +sal_uInt8 OLEVariant::getByte() const +{ + if (V_VT(this) == VT_UI1) + return V_UI1(this); + + if(isNull()) + return sal_Int8(0); + OLEVariant varDest; + + varDest.ChangeType(VT_UI1, this); + + return V_UI1(&varDest); +} + +sal_Int16 OLEVariant::getInt16() const +{ + if (V_VT(this) == VT_I2) + return V_I2(this); + + if(isNull()) + return sal_Int16(0); + OLEVariant varDest; + + varDest.ChangeType(VT_I2, this); + + return V_I2(&varDest); +} + +sal_Int8 OLEVariant::getInt8() const +{ + if (V_VT(this) == VT_I1) + return V_I1(this); + + if(isNull()) + return sal_Int8(0); + + OLEVariant varDest; + + varDest.ChangeType(VT_I1, this); + + return V_I1(&varDest); +} + +sal_Int32 OLEVariant::getInt32() const +{ + if (V_VT(this) == VT_I4) + return V_I4(this); + + if(isNull()) + return sal_Int32(0); + + OLEVariant varDest; + + varDest.ChangeType(VT_I4, this); + + return V_I4(&varDest); +} + +sal_uInt32 OLEVariant::getUInt32() const +{ + if (V_VT(this) == VT_UI4) + return V_UI4(this); + + if(isNull()) + return sal_uInt32(0); + + OLEVariant varDest; + + varDest.ChangeType(VT_UI4, this); + + return V_UI4(&varDest); +} + +float OLEVariant::getFloat() const +{ + if (V_VT(this) == VT_R4) + return V_R4(this); + + if(isNull()) + return float(0); + OLEVariant varDest; + + varDest.ChangeType(VT_R4, this); + + return V_R4(&varDest); +} + +double OLEVariant::getDouble() const +{ + if (V_VT(this) == VT_R8) + return V_R8(this); + + if(isNull()) + return double(0); + OLEVariant varDest; + + varDest.ChangeType(VT_R8, this); + + return V_R8(&varDest); +} + +double OLEVariant::getDateAsDouble() const +{ + if (V_VT(this) == VT_DATE) + return V_DATE(this); + + if(isNull()) + return double(0); + OLEVariant varDest; + + varDest.ChangeType(VT_DATE, this); + + return V_DATE(&varDest); +} + +CY OLEVariant::getCurrency() const +{ + if (V_VT(this) == VT_CY) + return V_CY(this); + + if(isNull()) + { + CY aVar; + aVar.int64 = sal_Int64(0); + return aVar; + } + OLEVariant varDest; + + varDest.ChangeType(VT_CY, this); + + return V_CY(&varDest); +} + +SAFEARRAY* OLEVariant::getUI1SAFEARRAYPtr() const +{ + if (V_VT(this) == (VT_ARRAY|VT_UI1)) + return V_ARRAY(this); + + if(isNull()) + return nullptr; + OLEVariant varDest; + + varDest.ChangeType((VT_ARRAY|VT_UI1), this); + + return V_ARRAY(&varDest); +} + +css::uno::Any OLEVariant::makeAny() const +{ + css::uno::Any aValue; + switch (V_VT(this)) + { + case VT_EMPTY: + case VT_NULL: + aValue.setValue(nullptr, Type()); + break; + case VT_I2: + aValue.setValue( & iVal, cppu::UnoType<sal_Int16>::get()); + break; + case VT_I4: + aValue.setValue( & lVal, cppu::UnoType<sal_Int32>::get()); + break; + case VT_R4: + aValue.setValue( & fltVal, cppu::UnoType<float>::get()); + break; + case VT_R8: + aValue.setValue(& dblVal, cppu::UnoType<double>::get()); + break; + case VT_CY: + { + Currency cy(cyVal.int64); + aValue <<= cy; + break; + } + case VT_DATE: + { + aValue <<= getDate(); + break; + } + case VT_BSTR: + { + OUString b(o3tl::toU(bstrVal)); + aValue.setValue( &b, cppu::UnoType<decltype(b)>::get()); + break; + } + case VT_BOOL: + { + aValue <<= (boolVal == VARIANT_TRUE); + break; + } + case VT_I1: + aValue.setValue( & cVal, cppu::UnoType<sal_Int8>::get()); + break; + case VT_UI1: // there is no unsigned char in UNO + aValue <<= sal_Int8(bVal); + break; + case VT_UI2: + aValue.setValue( & uiVal, cppu::UnoType<cppu::UnoUnsignedShortType>::get()); + break; + case VT_UI4: + aValue.setValue( & ulVal, cppu::UnoType<sal_uInt32>::get()); + break; + case VT_INT: + aValue.setValue( & intVal, cppu::UnoType<sal_Int32>::get()); + break; + case VT_UINT: + aValue.setValue( & uintVal, cppu::UnoType<sal_uInt32>::get()); + break; + case VT_VOID: + aValue.setValue( nullptr, Type()); + break; + case VT_DECIMAL: + { + Decimal dec; + dec.Scale = decVal.scale; + dec.Sign = decVal.sign; + dec.LowValue = decVal.Lo32; + dec.MiddleValue = decVal.Mid32; + dec.HighValue = decVal.Hi32; + aValue <<= dec; + break; + } + + default: + break; + } + return aValue; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/Awrapado.cxx b/connectivity/source/drivers/ado/Awrapado.cxx new file mode 100644 index 000000000..c25c0d6e0 --- /dev/null +++ b/connectivity/source/drivers/ado/Awrapado.cxx @@ -0,0 +1,2008 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/macros.h> +#include <ado/Awrapado.hxx> +#include <ado/Awrapadox.hxx> +#include <comphelper/types.hxx> +#include <rtl/ustrbuf.hxx> +#include <sal/log.hxx> +#include <systools/win32/oleauto.hxx> + +using namespace connectivity::ado; + +void WpADOCatalog::Create() +{ + pInterface.CoCreateInstance(ADOS::CLSID_ADOCATALOG_25, nullptr, CLSCTX_INPROC_SERVER); +} + + +WpADOProperties WpADOConnection::get_Properties() const +{ + WpADOProperties pProps; + pInterface->get_Properties(&pProps); + return pProps; +} + +OUString WpADOConnection::GetConnectionString() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_ConnectionString(&aBSTR); + return OUString(aBSTR); +} + +bool WpADOConnection::PutConnectionString(std::u16string_view aCon) const +{ + assert(pInterface); + sal::systools::BStr bstr(aCon); + bool bErg = SUCCEEDED(pInterface->put_ConnectionString(bstr)); + + return bErg; +} + +sal_Int32 WpADOConnection::GetCommandTimeout() const +{ + assert(pInterface); + sal_Int32 nRet=0; + pInterface->get_CommandTimeout(&nRet); + return nRet; +} + +void WpADOConnection::PutCommandTimeout(sal_Int32 nRet) +{ + assert(pInterface); + pInterface->put_CommandTimeout(nRet); +} + +sal_Int32 WpADOConnection::GetConnectionTimeout() const +{ + assert(pInterface); + sal_Int32 nRet=0; + pInterface->get_ConnectionTimeout(&nRet); + return nRet; +} + +void WpADOConnection::PutConnectionTimeout(sal_Int32 nRet) +{ + assert(pInterface); + pInterface->put_ConnectionTimeout(nRet); +} + +bool WpADOConnection::Close() +{ + assert(pInterface); + return (SUCCEEDED(pInterface->Close())); +} + +bool WpADOConnection::Execute(std::u16string_view CommandText,OLEVariant& RecordsAffected,long Options, WpADORecordset** ppiRset) +{ + assert(pInterface); + sal::systools::BStr sStr1(CommandText); + bool bErg = SUCCEEDED(pInterface->Execute(sStr1,&RecordsAffected,Options,reinterpret_cast<ADORecordset**>(ppiRset))); + return bErg; +} + +bool WpADOConnection::BeginTrans() +{ + assert(pInterface); + sal_Int32 nIso=0; + return SUCCEEDED(pInterface->BeginTrans(&nIso)); +} + +bool WpADOConnection::CommitTrans( ) +{ + assert(pInterface); + return SUCCEEDED(pInterface->CommitTrans()); +} + +bool WpADOConnection::RollbackTrans( ) +{ + assert(pInterface); + return SUCCEEDED(pInterface->RollbackTrans()); +} + +bool WpADOConnection::Open(std::u16string_view ConnectionString, std::u16string_view UserID,std::u16string_view Password,long Options) +{ + assert(pInterface); + sal::systools::BStr sStr1(ConnectionString); + sal::systools::BStr sStr2(UserID); + sal::systools::BStr sStr3(Password); + bool bErg = SUCCEEDED(pInterface->Open(sStr1, sStr2, sStr3, Options)); + return bErg; +} + +bool WpADOConnection::GetErrors(ADOErrors** pErrors) +{ + assert(pInterface); + return SUCCEEDED(pInterface->get_Errors(pErrors)); +} + +OUString WpADOConnection::GetDefaultDatabase() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; pInterface->get_DefaultDatabase(&aBSTR); + return OUString(aBSTR); +} + +bool WpADOConnection::PutDefaultDatabase(std::u16string_view _bstr) +{ + assert(pInterface); + sal::systools::BStr bstr(_bstr); + bool bErg = SUCCEEDED(pInterface->put_DefaultDatabase(bstr)); + + return bErg; +} + +IsolationLevelEnum WpADOConnection::get_IsolationLevel() const +{ + assert(pInterface); + IsolationLevelEnum eNum=adXactUnspecified; + pInterface->get_IsolationLevel(&eNum); + return eNum; +} + +bool WpADOConnection::put_IsolationLevel(const IsolationLevelEnum& eNum) +{ + assert(pInterface); + return SUCCEEDED(pInterface->put_IsolationLevel(eNum)); +} + +sal_Int32 WpADOConnection::get_Attributes() const +{ + assert(pInterface); + sal_Int32 nRet=0; + pInterface->get_Attributes(&nRet); + return nRet; +} + +bool WpADOConnection::put_Attributes(sal_Int32 nRet) +{ + assert(pInterface); + return SUCCEEDED(pInterface->put_Attributes(nRet)); +} + +CursorLocationEnum WpADOConnection::get_CursorLocation() const +{ + assert(pInterface); + CursorLocationEnum eNum=adUseNone; + pInterface->get_CursorLocation(&eNum); + return eNum; +} + +bool WpADOConnection::put_CursorLocation(const CursorLocationEnum &eNum) +{ + assert(pInterface); + return SUCCEEDED(pInterface->put_CursorLocation(eNum)); +} + +ConnectModeEnum WpADOConnection::get_Mode() const +{ + assert(pInterface); + ConnectModeEnum eNum=adModeUnknown; + pInterface->get_Mode(&eNum); + return eNum; +} + +bool WpADOConnection::put_Mode(const ConnectModeEnum &eNum) +{ + assert(pInterface); + return SUCCEEDED(pInterface->put_Mode(eNum)); +} + +OUString WpADOConnection::get_Provider() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; pInterface->get_Provider(&aBSTR); + return OUString(aBSTR); +} + +bool WpADOConnection::put_Provider(std::u16string_view _bstr) +{ + assert(pInterface); + sal::systools::BStr bstr(_bstr); + return SUCCEEDED(pInterface->put_Provider(bstr)); +} + +sal_Int32 WpADOConnection::get_State() const +{ + assert(pInterface); + sal_Int32 nRet=0; + pInterface->get_State(&nRet); + return nRet; +} + +bool WpADOConnection::OpenSchema(SchemaEnum eNum,OLEVariant const & Restrictions,OLEVariant const & SchemaID,ADORecordset**pprset) +{ + assert(pInterface); + return SUCCEEDED(pInterface->OpenSchema(eNum,Restrictions,SchemaID,pprset)); +} + +OUString WpADOConnection::get_Version() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_Version(&aBSTR); + return OUString(aBSTR); +} + +bool WpADOCommand::putref_ActiveConnection(const WpADOConnection& rCon) +{ + assert(pInterface); + return SUCCEEDED(pInterface->putref_ActiveConnection(rCon)); +} + +void WpADOCommand::put_ActiveConnection(/* [in] */ const OLEVariant& vConn) +{ + assert(pInterface); + pInterface->put_ActiveConnection(vConn); +} + +void WpADOCommand::Create() +{ + sal::systools::COMReference<IClassFactory2> pInterface2; + if (!FAILED(pInterface2.CoGetClassObject(ADOS::CLSID_ADOCOMMAND_21, CLSCTX_INPROC_SERVER))) + { + sal::systools::COMReference<ADOCommand> pCommand; + + HRESULT hr = pInterface2->CreateInstanceLic(nullptr, + nullptr, + ADOS::IID_ADOCOMMAND_21, + ADOS::GetKeyStr(), + reinterpret_cast<void**>(&pCommand)); + + if( !FAILED( hr ) ) + pInterface = std::move(pCommand); + } +} + +sal_Int32 WpADOCommand::get_State() const +{ + assert(pInterface); + sal_Int32 nRet=0; + pInterface->get_State(&nRet); + return nRet; +} + +OUString WpADOCommand::get_CommandText() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_CommandText(&aBSTR); + return OUString(aBSTR); +} + +bool WpADOCommand::put_CommandText(std::u16string_view aCon) +{ + assert(pInterface); + sal::systools::BStr bstr(aCon); + bool bErg = SUCCEEDED(pInterface->put_CommandText(bstr)); + + return bErg; +} + +sal_Int32 WpADOCommand::get_CommandTimeout() const +{ + assert(pInterface); + sal_Int32 nRet=0; + pInterface->get_CommandTimeout(&nRet); + return nRet; +} + +void WpADOCommand::put_CommandTimeout(sal_Int32 nRet) +{ + assert(pInterface); + pInterface->put_CommandTimeout(nRet); +} + +bool WpADOCommand::get_Prepared() const +{ + assert(pInterface); + VARIANT_BOOL bPrepared = VARIANT_FALSE; + pInterface->get_Prepared(&bPrepared); + return bPrepared == VARIANT_TRUE; +} + +bool WpADOCommand::put_Prepared(VARIANT_BOOL bPrepared) const +{ + assert(pInterface); + return SUCCEEDED(pInterface->put_Prepared(bPrepared)); +} + +bool WpADOCommand::Execute(OLEVariant& RecordsAffected,OLEVariant& Params,long Options, ADORecordset** ppiRset) +{ + assert(pInterface); + return SUCCEEDED(pInterface->Execute(&RecordsAffected,&Params,Options,ppiRset)); +} + +ADOParameter* WpADOCommand::CreateParameter(std::u16string_view _bstr,DataTypeEnum Type,ParameterDirectionEnum Direction,long nSize,const OLEVariant &Value) +{ + assert(pInterface); + ADOParameter* pPara = nullptr; + sal::systools::BStr bstr(_bstr); + bool bErg = SUCCEEDED(pInterface->CreateParameter(bstr, Type, Direction, nSize, Value, &pPara)); + + return bErg ? pPara : nullptr; +} + +ADOParameters* WpADOCommand::get_Parameters() const +{ + assert(pInterface); + ADOParameters* pPara=nullptr; + pInterface->get_Parameters(&pPara); + return pPara; +} + +bool WpADOCommand::put_CommandType( /* [in] */ CommandTypeEnum lCmdType) +{ + assert(pInterface); + return SUCCEEDED(pInterface->put_CommandType(lCmdType)); +} + +CommandTypeEnum WpADOCommand::get_CommandType() const +{ + assert(pInterface); + CommandTypeEnum eNum=adCmdUnspecified; + pInterface->get_CommandType(&eNum); + return eNum; +} + +// returns the name of the field +OUString WpADOCommand::GetName() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_Name(&aBSTR); + return OUString(aBSTR); +} + +bool WpADOCommand::put_Name(std::u16string_view Name) +{ + assert(pInterface); + sal::systools::BStr bstr(Name); + bool bErg = SUCCEEDED(pInterface->put_Name(bstr)); + + return bErg; +} +bool WpADOCommand::Cancel() +{ + assert(pInterface); + return SUCCEEDED(pInterface->Cancel()); +} + +OUString WpADOError::GetDescription() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_Description(&aBSTR); + return OUString(aBSTR); +} + +OUString WpADOError::GetSource() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_Source(&aBSTR); + return OUString(aBSTR); +} + +sal_Int32 WpADOError::GetNumber() const +{ + assert(pInterface); + sal_Int32 nErrNr=0; + pInterface->get_Number(&nErrNr); + return nErrNr; +} + +OUString WpADOError::GetSQLState() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_SQLState(&aBSTR); + return OUString(aBSTR); +} + +sal_Int32 WpADOError::GetNativeError() const +{ + assert(pInterface); + sal_Int32 nErrNr=0; + pInterface->get_NativeError(&nErrNr); + return nErrNr; +} + +WpADOProperties WpADOField::get_Properties() +{ + assert(pInterface); + WpADOProperties pProps; + pInterface->get_Properties(&pProps); + return pProps; +} + +sal_Int32 WpADOField::GetActualSize() const +{ + assert(pInterface); + ADO_LONGPTR nActualSize=0; + pInterface->get_ActualSize(&nActualSize); + return nActualSize; +} + +sal_Int32 WpADOField::GetAttributes() const +{ + assert(pInterface); + sal_Int32 eADOSFieldAttributes=0; + pInterface->get_Attributes(&eADOSFieldAttributes); + return eADOSFieldAttributes; +} + +sal_Int32 WpADOField::GetStatus() const +{ + assert(pInterface); + // pInterface->get_Status(&eADOSFieldAttributes); + return 0; +} + +sal_Int32 WpADOField::GetDefinedSize() const +{ + assert(pInterface); + ADO_LONGPTR nDefinedSize=0; + pInterface->get_DefinedSize(&nDefinedSize); + return nDefinedSize; +} + +// returns the name of the field +OUString WpADOField::GetName() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_Name(&aBSTR); + return OUString(aBSTR); +} + +DataTypeEnum WpADOField::GetADOType() const +{ + assert(pInterface); + DataTypeEnum eType=adEmpty; + pInterface->get_Type(&eType); + return eType; +} + +void WpADOField::get_Value(OLEVariant& aValVar) const +{ + assert(pInterface); + aValVar.setEmpty(); + pInterface->get_Value(&aValVar); +} + +OLEVariant WpADOField::get_Value() const +{ + assert(pInterface); + OLEVariant aValVar; + pInterface->get_Value(&aValVar); + return aValVar; +} + +bool WpADOField::PutValue(const OLEVariant& aVariant) +{ + assert(pInterface); + return (SUCCEEDED(pInterface->put_Value(aVariant))); +} + +sal_Int32 WpADOField::GetPrecision() const +{ + assert(pInterface); + sal_uInt8 eType=0; + pInterface->get_Precision(&eType); + return eType; +} + +sal_Int32 WpADOField::GetNumericScale() const +{ + assert(pInterface); + sal_uInt8 eType=0; + pInterface->get_NumericScale(&eType); + return eType; +} + +bool WpADOField::AppendChunk(const OLEVariant& Variant) +{ + assert(pInterface); + return (SUCCEEDED(pInterface->AppendChunk(Variant))); +} + +OLEVariant WpADOField::GetChunk(long Length) const +{ + assert(pInterface); + OLEVariant aValVar; + pInterface->GetChunk(Length,&aValVar); + return aValVar; +} + +void WpADOField::GetChunk(long Length,OLEVariant &aValVar) const +{ + assert(pInterface); + pInterface->GetChunk(Length,&aValVar); +} + +OLEVariant WpADOField::GetOriginalValue() const +{ + assert(pInterface); + OLEVariant aValVar; + pInterface->get_OriginalValue(&aValVar); + return aValVar; +} + +void WpADOField::GetOriginalValue(OLEVariant &aValVar) const +{ + assert(pInterface); + pInterface->get_OriginalValue(&aValVar); +} + +OLEVariant WpADOField::GetUnderlyingValue() const +{ + assert(pInterface); + OLEVariant aValVar; + pInterface->get_UnderlyingValue(&aValVar); + return aValVar; +} + +void WpADOField::GetUnderlyingValue(OLEVariant &aValVar) const +{ + assert(pInterface); + pInterface->get_UnderlyingValue(&aValVar); +} + +bool WpADOField::PutPrecision(sal_Int8 _prec) +{ + assert(pInterface); + return (SUCCEEDED(pInterface->put_Precision(_prec))); +} + +bool WpADOField::PutNumericScale(sal_Int8 _prec) +{ + assert(pInterface); + return (SUCCEEDED(pInterface->put_NumericScale(_prec))); +} + +void WpADOField::PutADOType(DataTypeEnum eType) +{ + assert(pInterface); + pInterface->put_Type(eType); +} + +bool WpADOField::PutDefinedSize(sal_Int32 _nDefSize) +{ + assert(pInterface); + return (SUCCEEDED(pInterface->put_DefinedSize(_nDefSize))); +} + +bool WpADOField::PutAttributes(sal_Int32 _nDefSize) +{ + assert(pInterface); + return (SUCCEEDED(pInterface->put_Attributes(_nDefSize))); +} + +OLEVariant WpADOProperty::GetValue() const +{ + OLEVariant aValVar; + if(pInterface) + pInterface->get_Value(&aValVar); + return aValVar; +} + +void WpADOProperty::GetValue(OLEVariant &aValVar) const +{ + assert(pInterface); + if(pInterface) + pInterface->get_Value(&aValVar); +} + +bool WpADOProperty::PutValue(const OLEVariant &aValVar) +{ + assert(pInterface); + return (SUCCEEDED(pInterface->put_Value(aValVar))); +} + +OUString WpADOProperty::GetName() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_Name(&aBSTR); + return OUString(aBSTR); +} + +DataTypeEnum WpADOProperty::GetADOType() const +{ + assert(pInterface); + DataTypeEnum eType=adEmpty; + pInterface->get_Type(&eType); + return eType; +} + +sal_Int32 WpADOProperty::GetAttributes() const +{ + assert(pInterface); + sal_Int32 eADOSFieldAttributes=0; + pInterface->get_Attributes(&eADOSFieldAttributes); + return eADOSFieldAttributes; +} + +bool WpADOProperty::PutAttributes(sal_Int32 _nDefSize) +{ + assert(pInterface); + return (SUCCEEDED(pInterface->put_Attributes(_nDefSize))); +} + void WpADORecordset::Create() +{ + sal::systools::COMReference<IClassFactory2> pInterface2; + if (!FAILED(pInterface2.CoGetClassObject(ADOS::CLSID_ADORECORDSET_21, CLSCTX_INPROC_SERVER))) + { + sal::systools::COMReference<ADORecordset> pRec; + HRESULT hr = pInterface2->CreateInstanceLic(nullptr, + nullptr, + ADOS::IID_ADORECORDSET_21, + ADOS::GetKeyStr(), + reinterpret_cast<void**>(&pRec)); + + if( !FAILED( hr ) ) + pInterface = std::move(pRec); + } +} + +bool WpADORecordset::Open( + /* [optional][in] */ VARIANT Source, + /* [optional][in] */ VARIANT ActiveConnection, + /* [defaultvalue][in] */ CursorTypeEnum CursorType, + /* [defaultvalue][in] */ LockTypeEnum LockType, + /* [defaultvalue][in] */ sal_Int32 Options) +{ + assert(pInterface); + return (SUCCEEDED(pInterface->Open(Source,ActiveConnection,CursorType,LockType,Options))); +} + + +LockTypeEnum WpADORecordset::GetLockType() +{ + assert(pInterface); + LockTypeEnum eType=adLockUnspecified; + pInterface->get_LockType(&eType); + return eType; +} + +void WpADORecordset::Close() +{ + assert(pInterface); + pInterface->Close(); +} + +bool WpADORecordset::Cancel() const +{ + assert(pInterface); + return (SUCCEEDED(pInterface->Cancel())); +} + +sal_Int32 WpADORecordset::get_State() +{ + assert(pInterface); + sal_Int32 nState = 0; + pInterface->get_State(&nState); + return nState; +} + +bool WpADORecordset::Supports( /* [in] */ CursorOptionEnum CursorOptions) +{ + assert(pInterface); + VARIANT_BOOL bSupports=VARIANT_FALSE; + pInterface->Supports(CursorOptions,&bSupports); + return bSupports == VARIANT_TRUE; +} + +PositionEnum_Param WpADORecordset::get_AbsolutePosition() +{ + assert(pInterface); + PositionEnum_Param aTemp=adPosUnknown; + pInterface->get_AbsolutePosition(&aTemp); + return aTemp; +} + +void WpADORecordset::GetDataSource(IUnknown** _pInterface) const +{ + assert(pInterface); + pInterface->get_DataSource(_pInterface); +} + +void WpADORecordset::PutRefDataSource(IUnknown* _pInterface) +{ + assert(pInterface); + pInterface->putref_DataSource(_pInterface); +} + +void WpADORecordset::GetBookmark(VARIANT& var) +{ + assert(pInterface); + pInterface->get_Bookmark(&var); +} + +OLEVariant WpADORecordset::GetBookmark() +{ + assert(pInterface); + OLEVariant var; + pInterface->get_Bookmark(&var); + return var; +} + +CompareEnum WpADORecordset::CompareBookmarks(const OLEVariant& left,const OLEVariant& right) +{ + assert(pInterface); + CompareEnum eNum=adCompareNotComparable; + pInterface->CompareBookmarks(left,right,&eNum); + return eNum; +} + +bool WpADORecordset::SetBookmark(const OLEVariant &pSafeAr) +{ + assert(pInterface); + return SUCCEEDED(pInterface->put_Bookmark(pSafeAr)); +} + + +WpADOFields WpADORecordset::GetFields() const +{ + assert(pInterface); + WpADOFields pFields; + pInterface->get_Fields(&pFields); + return pFields; +} + + +bool WpADORecordset::Move(sal_Int32 nRows, VARIANT aBmk) {return pInterface && SUCCEEDED(pInterface->Move(nRows, aBmk));} +bool WpADORecordset::MoveNext() {return pInterface && SUCCEEDED(pInterface->MoveNext());} +bool WpADORecordset::MovePrevious() {return pInterface && SUCCEEDED(pInterface->MovePrevious());} +bool WpADORecordset::MoveFirst() {return pInterface && SUCCEEDED(pInterface->MoveFirst());} +bool WpADORecordset::MoveLast() {return pInterface && SUCCEEDED(pInterface->MoveLast());} + +bool WpADORecordset::IsAtBOF() const +{ + assert(pInterface); + VARIANT_BOOL bIsAtBOF=VARIANT_FALSE; + pInterface->get_BOF(&bIsAtBOF); + return bIsAtBOF == VARIANT_TRUE; +} + +bool WpADORecordset::IsAtEOF() const +{ + assert(pInterface); + VARIANT_BOOL bIsAtEOF=VARIANT_FALSE; + pInterface->get_EOF(&bIsAtEOF); + return bIsAtEOF == VARIANT_TRUE; +} + +bool WpADORecordset::Delete(AffectEnum eNum) +{ + assert(pInterface); + return SUCCEEDED(pInterface->Delete(eNum)); +} + +bool WpADORecordset::AddNew(const OLEVariant &FieldList,const OLEVariant &Values) +{ + assert(pInterface); + return SUCCEEDED(pInterface->AddNew(FieldList,Values)); +} + +bool WpADORecordset::Update(const OLEVariant &FieldList,const OLEVariant &Values) +{ + assert(pInterface); + return SUCCEEDED(pInterface->Update(FieldList,Values)); +} + +bool WpADORecordset::CancelUpdate() +{ + assert(pInterface); + return SUCCEEDED(pInterface->CancelUpdate()); +} + +WpADOProperties WpADORecordset::get_Properties() const +{ + assert(pInterface); + WpADOProperties pProps; + pInterface->get_Properties(&pProps); + return pProps; +} + +bool WpADORecordset::NextRecordset(OLEVariant& RecordsAffected,ADORecordset** ppiRset) +{ + assert(pInterface); + return SUCCEEDED(pInterface->NextRecordset(&RecordsAffected,ppiRset)); +} + +bool WpADORecordset::get_RecordCount(ADO_LONGPTR &_nRet) const +{ + assert(pInterface); + return SUCCEEDED(pInterface->get_RecordCount(&_nRet)); +} + +bool WpADORecordset::get_MaxRecords(ADO_LONGPTR &_nRet) const +{ + assert(pInterface); + return SUCCEEDED(pInterface->get_MaxRecords(&_nRet)); +} + +bool WpADORecordset::put_MaxRecords(ADO_LONGPTR _nRet) +{ + assert(pInterface); + return SUCCEEDED(pInterface->put_MaxRecords(_nRet)); +} + +bool WpADORecordset::get_CursorType(CursorTypeEnum &_nRet) const +{ + assert(pInterface); + return SUCCEEDED(pInterface->get_CursorType(&_nRet)); +} + +bool WpADORecordset::put_CursorType(CursorTypeEnum _nRet) +{ + assert(pInterface); + return SUCCEEDED(pInterface->put_CursorType(_nRet)); +} + +bool WpADORecordset::get_LockType(LockTypeEnum &_nRet) const +{ + assert(pInterface); + return SUCCEEDED(pInterface->get_LockType(&_nRet)); +} + +bool WpADORecordset::put_LockType(LockTypeEnum _nRet) +{ + assert(pInterface); + return SUCCEEDED(pInterface->put_LockType(_nRet)); +} + +bool WpADORecordset::get_CacheSize(sal_Int32 &_nRet) const +{ + assert(pInterface); + return SUCCEEDED(pInterface->get_CacheSize(&_nRet)); +} + +bool WpADORecordset::put_CacheSize(sal_Int32 _nRet) +{ + assert(pInterface); + return SUCCEEDED(pInterface->put_CacheSize(_nRet)); +} + +bool WpADORecordset::UpdateBatch(AffectEnum AffectRecords) +{ + assert(pInterface); + return SUCCEEDED(pInterface->UpdateBatch(AffectRecords)); +} + +OUString WpADOParameter::GetName() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_Name(&aBSTR); + return OUString(aBSTR); +} + +DataTypeEnum WpADOParameter::GetADOType() const +{ + assert(pInterface); + DataTypeEnum eType=adEmpty; + pInterface->get_Type(&eType); + return eType; +} + +void WpADOParameter::put_Type(const DataTypeEnum& _eType) +{ + assert(pInterface); + pInterface->put_Type(_eType); +} + +sal_Int32 WpADOParameter::GetAttributes() const +{ + assert(pInterface); + sal_Int32 eADOSFieldAttributes=0; + pInterface->get_Attributes(&eADOSFieldAttributes); + return eADOSFieldAttributes; +} + +sal_Int32 WpADOParameter::GetPrecision() const +{ + assert(pInterface); + sal_uInt8 eType=0; + pInterface->get_Precision(&eType); + return eType; +} + +sal_Int32 WpADOParameter::GetNumericScale() const +{ + assert(pInterface); + sal_uInt8 eType=0; + pInterface->get_NumericScale(&eType); + return eType; +} + +ParameterDirectionEnum WpADOParameter::get_Direction() const +{ + assert(pInterface); + ParameterDirectionEnum alParmDirection=adParamUnknown; + pInterface->get_Direction(&alParmDirection); + return alParmDirection; +} + +void WpADOParameter::GetValue(OLEVariant& aValVar) const +{ + assert(pInterface); + pInterface->get_Value(&aValVar); +} + +OLEVariant WpADOParameter::GetValue() const +{ + assert(pInterface); + OLEVariant aValVar; + pInterface->get_Value(&aValVar); + return aValVar; +} + +bool WpADOParameter::PutValue(const OLEVariant& aVariant) +{ + assert(pInterface); + return (SUCCEEDED(pInterface->put_Value(aVariant))); +} +bool WpADOParameter::AppendChunk(const OLEVariant& aVariant) +{ + assert(pInterface); + return (SUCCEEDED(pInterface->AppendChunk(aVariant))); +} +bool WpADOParameter::put_Size(sal_Int32 _nSize) +{ + assert(pInterface); + return (SUCCEEDED(pInterface->put_Size(_nSize))); +} + +OUString WpADOColumn::get_Name() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_Name(&aBSTR); + return OUString(aBSTR); +} + +OUString WpADOColumn::get_RelatedColumn() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_RelatedColumn(&aBSTR); + return OUString(aBSTR); +} + +void WpADOColumn::put_Name(std::u16string_view _rName) +{ + assert(pInterface); + sal::systools::BStr bstr(_rName); + pInterface->put_Name(bstr); +} +void WpADOColumn::put_RelatedColumn(std::u16string_view _rName) +{ + assert(pInterface); + sal::systools::BStr bstr(_rName); + pInterface->put_RelatedColumn(bstr); +} + +DataTypeEnum WpADOColumn::get_Type() const +{ + assert(pInterface); + DataTypeEnum eNum = adVarChar; + pInterface->get_Type(&eNum); + return eNum; +} + +void WpADOColumn::put_Type(const DataTypeEnum& _eNum) +{ + assert(pInterface); + pInterface->put_Type(_eNum); +} + +sal_Int32 WpADOColumn::get_Precision() const +{ + assert(pInterface); + sal_Int32 nPrec=0; + pInterface->get_Precision(&nPrec); + return nPrec; +} + +void WpADOColumn::put_Precision(sal_Int32 _nPre) +{ + assert(pInterface); + pInterface->put_Precision(_nPre); +} + +sal_Int32 WpADOColumn::get_DefinedSize() const +{ + assert(pInterface); + sal_Int32 nPrec=0; + pInterface->get_DefinedSize(&nPrec); + return nPrec; +} +sal_uInt8 WpADOColumn::get_NumericScale() const +{ + assert(pInterface); + sal_uInt8 nPrec=0; + pInterface->get_NumericScale(&nPrec); + return nPrec; +} + +void WpADOColumn::put_NumericScale(sal_Int8 _nScale) +{ + assert(pInterface); + pInterface->put_NumericScale(_nScale); +} + +SortOrderEnum WpADOColumn::get_SortOrder() const +{ + assert(pInterface); + SortOrderEnum nPrec=adSortAscending; + pInterface->get_SortOrder(&nPrec); + return nPrec; +} + +void WpADOColumn::put_SortOrder(SortOrderEnum _nScale) +{ + assert(pInterface); + pInterface->put_SortOrder(_nScale); +} + +ColumnAttributesEnum WpADOColumn::get_Attributes() const +{ + assert(pInterface); + ColumnAttributesEnum eNum=adColNullable; + pInterface->get_Attributes(&eNum); + return eNum; +} + +bool WpADOColumn::put_Attributes(const ColumnAttributesEnum& _eNum) +{ + assert(pInterface); + return SUCCEEDED(pInterface->put_Attributes(_eNum)); +} + +WpADOProperties WpADOColumn::get_Properties() const +{ + assert(pInterface); + WpADOProperties pProps; + pInterface->get_Properties(&pProps); + return pProps; +} + +OUString WpADOKey::get_Name() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_Name(&aBSTR); + return OUString(aBSTR); +} + +void WpADOKey::put_Name(std::u16string_view _rName) +{ + assert(pInterface); + sal::systools::BStr bstr(_rName); + pInterface->put_Name(bstr); +} + +KeyTypeEnum WpADOKey::get_Type() const +{ + assert(pInterface); + KeyTypeEnum eNum=adKeyPrimary; + pInterface->get_Type(&eNum); + return eNum; +} + +void WpADOKey::put_Type(const KeyTypeEnum& _eNum) +{ + assert(pInterface); + pInterface->put_Type(_eNum); +} + +OUString WpADOKey::get_RelatedTable() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_RelatedTable(&aBSTR); + return OUString(aBSTR); +} + +void WpADOKey::put_RelatedTable(std::u16string_view _rName) +{ + assert(pInterface); + sal::systools::BStr bstr(_rName); + pInterface->put_RelatedTable(bstr); +} + +RuleEnum WpADOKey::get_DeleteRule() const +{ + assert(pInterface); + RuleEnum eNum = adRINone; + pInterface->get_DeleteRule(&eNum); + return eNum; +} + +void WpADOKey::put_DeleteRule(const RuleEnum& _eNum) +{ + assert(pInterface); + pInterface->put_DeleteRule(_eNum); +} + +RuleEnum WpADOKey::get_UpdateRule() const +{ + assert(pInterface); + RuleEnum eNum = adRINone; + pInterface->get_UpdateRule(&eNum); + return eNum; +} + +void WpADOKey::put_UpdateRule(const RuleEnum& _eNum) +{ + assert(pInterface); + pInterface->put_UpdateRule(_eNum); +} + +WpADOColumns WpADOKey::get_Columns() const +{ + assert(pInterface); + WpADOColumns pCols; + pInterface->get_Columns(&pCols); + return pCols; +} + +OUString WpADOIndex::get_Name() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_Name(&aBSTR); + return OUString(aBSTR); +} + +void WpADOIndex::put_Name(std::u16string_view _rName) +{ + assert(pInterface); + sal::systools::BStr bstr(_rName); + pInterface->put_Name(bstr); +} + +bool WpADOIndex::get_Clustered() const +{ + assert(pInterface); + VARIANT_BOOL eNum = VARIANT_FALSE; + pInterface->get_Clustered(&eNum); + return eNum == VARIANT_TRUE; +} + +void WpADOIndex::put_Clustered(bool _b) +{ + assert(pInterface); + pInterface->put_Clustered(_b ? VARIANT_TRUE : VARIANT_FALSE); +} + +bool WpADOIndex::get_Unique() const +{ + assert(pInterface); + VARIANT_BOOL eNum = VARIANT_FALSE; + pInterface->get_Unique(&eNum); + return eNum == VARIANT_TRUE; +} + +void WpADOIndex::put_Unique(bool _b) +{ + assert(pInterface); + pInterface->put_Unique(_b ? VARIANT_TRUE : VARIANT_FALSE); +} + +bool WpADOIndex::get_PrimaryKey() const +{ + assert(pInterface); + VARIANT_BOOL eNum = VARIANT_FALSE; + pInterface->get_PrimaryKey(&eNum); + return eNum == VARIANT_TRUE; +} + +void WpADOIndex::put_PrimaryKey(bool _b) +{ + assert(pInterface); + pInterface->put_PrimaryKey(_b ? VARIANT_TRUE : VARIANT_FALSE); +} + +WpADOColumns WpADOIndex::get_Columns() const +{ + assert(pInterface); + WpADOColumns pCols; + pInterface->get_Columns(&pCols); + return pCols; +} + +void WpADOCatalog::putref_ActiveConnection(IDispatch* pCon) +{ + assert(pInterface); + pInterface->putref_ActiveConnection(pCon); +} + +WpADOTables WpADOCatalog::get_Tables() +{ + assert(pInterface); + WpADOTables pRet; + pInterface->get_Tables(&pRet); + return pRet; +} + +WpADOViews WpADOCatalog::get_Views() +{ + assert(pInterface); + WpADOViews pRet; + pInterface->get_Views(&pRet); + return pRet; +} + +WpADOGroups WpADOCatalog::get_Groups() +{ + assert(pInterface); + WpADOGroups pRet; + pInterface->get_Groups(&pRet); + return pRet; +} + +WpADOUsers WpADOCatalog::get_Users() +{ + assert(pInterface); + WpADOUsers pRet; + pInterface->get_Users(&pRet); + return pRet; +} + +ADOProcedures* WpADOCatalog::get_Procedures() +{ + assert(pInterface); + ADOProcedures* pRet = nullptr; + pInterface->get_Procedures(&pRet); + return pRet; +} + +OUString WpADOTable::get_Name() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_Name(&aBSTR); + return OUString(aBSTR); +} + +void WpADOTable::put_Name(std::u16string_view _rName) +{ + assert(pInterface); + sal::systools::BStr bstr(_rName); + pInterface->put_Name(bstr); +} + +OUString WpADOTable::get_Type() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_Type(&aBSTR); + return OUString(aBSTR); +} + +WpADOColumns WpADOTable::get_Columns() const +{ + assert(pInterface); + WpADOColumns pCols; + pInterface->get_Columns(&pCols); + return pCols; +} + +WpADOIndexes WpADOTable::get_Indexes() const +{ + assert(pInterface); + WpADOIndexes pRet; + pInterface->get_Indexes(&pRet); + return pRet; +} + +WpADOKeys WpADOTable::get_Keys() const +{ + assert(pInterface); + WpADOKeys pRet; + pInterface->get_Keys(&pRet); + return pRet; +} + +WpADOCatalog WpADOTable::get_ParentCatalog() const +{ + assert(pInterface); + WpADOCatalog pCat; + pInterface->get_ParentCatalog(&pCat); + return pCat; +} + +WpADOProperties WpADOTable::get_Properties() const +{ + assert(pInterface); + WpADOProperties pProps; + pInterface->get_Properties(&pProps); + return pProps; +} + +OUString WpADOView::get_Name() const +{ + assert(pInterface); + sal::systools::BStr aBSTR; + pInterface->get_Name(&aBSTR); + return OUString(aBSTR); +} + +void WpADOView::get_Command(OLEVariant& _rVar) const +{ + assert(pInterface); + pInterface->get_Command(&_rVar); +} + +void WpADOView::put_Command(OLEVariant const & _rVar) +{ + assert(pInterface); + pInterface->put_Command(_rVar); +} + +OUString WpADOGroup::get_Name() const +{ + sal::systools::BStr aBSTR; + pInterface->get_Name(&aBSTR); + return OUString(aBSTR); +} + +void WpADOGroup::put_Name(std::u16string_view _rName) +{ + sal::systools::BStr bstr(_rName); + pInterface->put_Name(bstr); +} + +RightsEnum WpADOGroup::GetPermissions( + /* [in] */ const OLEVariant& Name, + /* [in] */ ObjectTypeEnum ObjectType) +{ + RightsEnum Rights=adRightNone; + OLEVariant ObjectTypeId; + ObjectTypeId.setNoArg(); + pInterface->GetPermissions(Name,ObjectType,ObjectTypeId,&Rights); + return Rights; +} + +bool WpADOGroup::SetPermissions( + /* [in] */ const OLEVariant& Name, + /* [in] */ ObjectTypeEnum ObjectType, + /* [in] */ ActionEnum Action, + /* [in] */ RightsEnum Rights) +{ + OLEVariant ObjectTypeId; + ObjectTypeId.setNoArg(); + return SUCCEEDED(pInterface->SetPermissions(Name,ObjectType,Action,Rights,adInheritNone,ObjectTypeId)); +} + +WpADOUsers WpADOGroup::get_Users( ) +{ + WpADOUsers pRet; + pInterface->get_Users( &pRet); + return pRet; +} + +OUString WpADOUser::get_Name() const +{ + sal::systools::BStr aBSTR; + pInterface->get_Name(&aBSTR); + return OUString(aBSTR); +} + +void WpADOUser::put_Name(std::u16string_view _rName) +{ + sal::systools::BStr bstr(_rName); + pInterface->put_Name(bstr); +} + +bool WpADOUser::ChangePassword(std::u16string_view _rPwd,std::u16string_view _rNewPwd) +{ + sal::systools::BStr sStr1(_rPwd); + sal::systools::BStr sStr2(_rNewPwd); + bool bErg = SUCCEEDED(pInterface->ChangePassword(sStr1, sStr2)); + return bErg; +} + +WpADOGroups WpADOUser::get_Groups() +{ + WpADOGroups pRet; + pInterface->get_Groups(&pRet); + return pRet; +} + +RightsEnum WpADOUser::GetPermissions( + /* [in] */ const OLEVariant& Name, + /* [in] */ ObjectTypeEnum ObjectType) +{ + RightsEnum Rights=adRightNone; + OLEVariant ObjectTypeId; + ObjectTypeId.setNoArg(); + pInterface->GetPermissions(Name,ObjectType,ObjectTypeId,&Rights); + return Rights; +} + +bool WpADOUser::SetPermissions( + /* [in] */ const OLEVariant& Name, + /* [in] */ ObjectTypeEnum ObjectType, + /* [in] */ ActionEnum Action, + /* [in] */ RightsEnum Rights) +{ + OLEVariant ObjectTypeId; + ObjectTypeId.setNoArg(); + return SUCCEEDED(pInterface->SetPermissions(Name,ObjectType,Action,Rights,adInheritNone,ObjectTypeId)); +} + +ADORecordset* WpADOConnection::getExportedKeys( const css::uno::Any& catalog, const OUString& schema, std::u16string_view table ) +{ + // Create elements used in the array + SAFEARRAYBOUND rgsabound[1]; + SAFEARRAY *psa = nullptr; + OLEVariant varCriteria[6]; + + // Create SafeArray Bounds and initialize the array + rgsabound[0].lLbound = 0; + rgsabound[0].cElements = std::size(varCriteria); + psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound ); + + sal_Int32 nPos=0; + if(catalog.hasValue()) + varCriteria[nPos].setString(::comphelper::getString(catalog)); + + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_CATALOG + if(schema.getLength() && schema.toChar() != '%') + varCriteria[nPos].setString(schema); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_SCHEMA + + varCriteria[nPos].setString(table); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_NAME + + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_CATALOG + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_SCHEMA + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_NAME + + OLEVariant vtEmpty; + vtEmpty.setNoArg(); + + // Initialize and fill the SafeArray + OLEVariant vsa; + vsa.setArray(psa,VT_VARIANT); + + ADORecordset *pRecordset = nullptr; + OpenSchema(adSchemaForeignKeys,vsa,vtEmpty,&pRecordset); + return pRecordset; +} + +ADORecordset* WpADOConnection::getImportedKeys( const css::uno::Any& catalog, const OUString& schema, std::u16string_view table ) +{ + // Create elements used in the array + SAFEARRAYBOUND rgsabound[1]; + SAFEARRAY *psa = nullptr; + OLEVariant varCriteria[6]; + + // Create SafeArray Bounds and initialize the array + rgsabound[0].lLbound = 0; + rgsabound[0].cElements = std::size(varCriteria); + psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound ); + + sal_Int32 nPos=0; + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_CATALOG + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_SCHEMA + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_NAME + + if(catalog.hasValue()) + varCriteria[nPos].setString(::comphelper::getString(catalog)); + + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_CATALOG + if(schema.getLength() && schema.toChar() != '%') + varCriteria[nPos].setString(schema); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_SCHEMA + + varCriteria[nPos].setString(table); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_NAME + + OLEVariant vtEmpty; + vtEmpty.setNoArg(); + + // Initialize and fill the SafeArray + OLEVariant vsa; + vsa.setArray(psa,VT_VARIANT); + + ADORecordset *pRecordset = nullptr; + OpenSchema(adSchemaForeignKeys,vsa,vtEmpty,&pRecordset); + + return pRecordset; + +} + +ADORecordset* WpADOConnection::getPrimaryKeys( const css::uno::Any& catalog, const OUString& schema, std::u16string_view table ) +{ + // Create elements used in the array + SAFEARRAYBOUND rgsabound[1]; + SAFEARRAY *psa = nullptr; + OLEVariant varCriteria[3]; + + // Create SafeArray Bounds and initialize the array + rgsabound[0].lLbound = 0; + rgsabound[0].cElements = std::size(varCriteria); + psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound ); + + sal_Int32 nPos=0; + if(catalog.hasValue()) + varCriteria[nPos].setString(::comphelper::getString(catalog)); + + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_CATALOG + if(schema.getLength() && schema.toChar() != '%') + varCriteria[nPos].setString(schema); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_SCHEMA + + varCriteria[nPos].setString(table); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_NAME + + + OLEVariant vtEmpty; + vtEmpty.setNoArg(); + + // Initialize and fill the SafeArray + OLEVariant vsa; + vsa.setArray(psa,VT_VARIANT); + + ADORecordset *pRecordset = nullptr; + OpenSchema(adSchemaPrimaryKeys,vsa,vtEmpty,&pRecordset); + + return pRecordset; +} + +ADORecordset* WpADOConnection::getIndexInfo( + const css::uno::Any& catalog, const OUString& schema, std::u16string_view table, + bool /*unique*/, bool /*approximate*/ ) +{ + // Create elements used in the array + SAFEARRAYBOUND rgsabound[1]; + SAFEARRAY *psa = nullptr; + OLEVariant varCriteria[5]; + + // Create SafeArray Bounds and initialize the array + rgsabound[0].lLbound = 0; + rgsabound[0].cElements = std::size(varCriteria); + psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound ); + + sal_Int32 nPos=0; + if(catalog.hasValue()) + varCriteria[nPos].setString(::comphelper::getString(catalog)); + + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_CATALOG + if(schema.getLength() && schema.toChar() != '%') + varCriteria[nPos].setString(schema); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_SCHEMA + + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// INDEX_NAME + + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TYPE + + varCriteria[nPos].setString(table); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_NAME + + OLEVariant vtEmpty; + vtEmpty.setNoArg(); + + // Initialize and fill the SafeArray + OLEVariant vsa; + vsa.setArray(psa,VT_VARIANT); + + ADORecordset *pRecordset = nullptr; + OpenSchema(adSchemaIndexes,vsa,vtEmpty,&pRecordset); + + return pRecordset; +} + +ADORecordset* WpADOConnection::getTablePrivileges( const css::uno::Any& catalog, + const OUString& schemaPattern, + const OUString& tableNamePattern ) +{ + SAFEARRAYBOUND rgsabound[1]; + SAFEARRAY *psa = nullptr; + OLEVariant varCriteria[5]; + + // Create SafeArray Bounds and initialize the array + rgsabound[0].lLbound = 0; + rgsabound[0].cElements = std::size(varCriteria); + psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound ); + + sal_Int32 nPos=0; + if(catalog.hasValue()) + varCriteria[nPos].setString(::comphelper::getString(catalog)); + + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_CATALOG + if(schemaPattern.getLength() && schemaPattern.toChar() != '%') + varCriteria[nPos].setString(schemaPattern); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_SCHEMA + + if(tableNamePattern.toChar() != '%') + varCriteria[nPos].setString(tableNamePattern); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_NAME + + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// GRANTOR + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// GRANTEE + + OLEVariant vtEmpty; + vtEmpty.setNoArg(); + + // Initialize and fill the SafeArray + OLEVariant vsa; + vsa.setArray(psa,VT_VARIANT); + + ADORecordset *pRecordset = nullptr; + OpenSchema(adSchemaTablePrivileges,vsa,vtEmpty,&pRecordset); + + return pRecordset; +} + +ADORecordset* WpADOConnection::getCrossReference( const css::uno::Any& primaryCatalog, + const OUString& primarySchema, + std::u16string_view primaryTable, + const css::uno::Any& foreignCatalog, + const OUString& foreignSchema, + std::u16string_view foreignTable) +{ + // Create elements used in the array + SAFEARRAYBOUND rgsabound[1]; + SAFEARRAY *psa = nullptr; + OLEVariant varCriteria[6]; + + // Create SafeArray Bounds and initialize the array + rgsabound[0].lLbound = 0; + rgsabound[0].cElements = std::size(varCriteria); + psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound ); + + sal_Int32 nPos=0; + if(primaryCatalog.hasValue()) + varCriteria[nPos].setString(::comphelper::getString(primaryCatalog)); + + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_CATALOG + if(primarySchema.getLength() && primarySchema.toChar() != '%') + varCriteria[nPos].setString(primarySchema); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_SCHEMA + + varCriteria[nPos].setString(primaryTable); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_NAME + + if(foreignCatalog.hasValue()) + varCriteria[nPos].setString(::comphelper::getString(foreignCatalog)); + + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_CATALOG + if(foreignSchema.getLength() && foreignSchema.toChar() != '%') + varCriteria[nPos].setString(foreignSchema); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_SCHEMA + + varCriteria[nPos].setString(foreignTable); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_NAME + + OLEVariant vtEmpty; + vtEmpty.setNoArg(); + + // Initialize and fill the SafeArray + OLEVariant vsa; + vsa.setArray(psa,VT_VARIANT); + + ADORecordset *pRecordset = nullptr; + OpenSchema(adSchemaForeignKeys,vsa,vtEmpty,&pRecordset); + + return pRecordset; +} + +ADORecordset* WpADOConnection::getProcedures( const css::uno::Any& catalog, + const OUString& schemaPattern, + const OUString& procedureNamePattern ) +{ + SAFEARRAYBOUND rgsabound[1]; + SAFEARRAY *psa = nullptr; + OLEVariant varCriteria[3]; + + // Create SafeArray Bounds and initialize the array + rgsabound[0].lLbound = 0; + rgsabound[0].cElements = std::size(varCriteria); + psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound ); + + sal_Int32 nPos=0; + if(catalog.hasValue()) + varCriteria[nPos].setString(::comphelper::getString(catalog)); + + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_CATALOG + if(schemaPattern.getLength() && schemaPattern.toChar() != '%') + varCriteria[nPos].setString(schemaPattern); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_SCHEMA + + if(procedureNamePattern.toChar() != '%') + varCriteria[nPos].setString(procedureNamePattern); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_NAME + + OLEVariant vtEmpty; + vtEmpty.setNoArg(); + + // Initialize and fill the SafeArray + OLEVariant vsa; + vsa.setArray(psa,VT_VARIANT); + + ADORecordset *pRecordset = nullptr; + OpenSchema(adSchemaProcedures,vsa,vtEmpty,&pRecordset); + + return pRecordset; +} + +ADORecordset* WpADOConnection::getProcedureColumns( const css::uno::Any& catalog, + const OUString& schemaPattern, + const OUString& procedureNamePattern, + const OUString& columnNamePattern ) +{ + // Create elements used in the array + SAFEARRAYBOUND rgsabound[1]; + SAFEARRAY *psa = nullptr; + OLEVariant varCriteria[4]; + + // Create SafeArray Bounds and initialize the array + rgsabound[0].lLbound = 0; + rgsabound[0].cElements = std::size(varCriteria); + psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound ); + + sal_Int32 nPos=0; + if(catalog.hasValue()) + varCriteria[nPos].setString(::comphelper::getString(catalog)); + + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_CATALOG + if(schemaPattern.getLength() && schemaPattern.toChar() != '%') + varCriteria[nPos].setString(schemaPattern); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_SCHEMA + + if(procedureNamePattern.toChar() != '%') + varCriteria[nPos].setString(procedureNamePattern); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_NAME + + if(columnNamePattern.toChar() != '%') + varCriteria[nPos].setString(columnNamePattern); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// COLUMN_NAME + + OLEVariant vtEmpty; + vtEmpty.setNoArg(); + + // Initialize and fill the SafeArray + OLEVariant vsa; + vsa.setArray(psa,VT_VARIANT); + + ADORecordset *pRecordset = nullptr; + OpenSchema(adSchemaProcedureParameters,vsa,vtEmpty,&pRecordset); + + return pRecordset; +} + +ADORecordset* WpADOConnection::getTables( const css::uno::Any& catalog, + const OUString& schemaPattern, + const OUString& tableNamePattern, + const css::uno::Sequence< OUString >& types ) +{ + // Create elements used in the array + HRESULT hr = S_OK; + OLEVariant varCriteria[4]; + + sal_Int32 nPos=0; + OUString sCatalog; + if ( catalog.hasValue() && (catalog >>= sCatalog) ) + varCriteria[nPos].setString(sCatalog); + + ++nPos; + if(schemaPattern.getLength() && schemaPattern.toChar() != '%') + varCriteria[nPos].setString(schemaPattern); + + ++nPos; + if(tableNamePattern.toChar() != '%') + varCriteria[nPos].setString(tableNamePattern); + + ++nPos; + OUStringBuffer aTypes; + const OUString* pIter = types.getConstArray(); + const OUString* pEnd = pIter + types.getLength(); + for( ; pIter != pEnd ; ++pIter) + { + if ( aTypes.getLength() ) + aTypes.append(","); + aTypes.append(*pIter); + } + + OUString sTypeNames = aTypes.makeStringAndClear(); + if ( sTypeNames.getLength() ) + varCriteria[nPos].setString(sTypeNames); + + // Create SafeArray Bounds and initialize the array + const sal_Int32 nCrit = std::size(varCriteria); + SAFEARRAYBOUND rgsabound[1]; + rgsabound[0].lLbound = 0; + rgsabound[0].cElements = nCrit; + SAFEARRAY *psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound ); + + // Set the values for each element of the array + for( LONG i = 0 ; i < nCrit && SUCCEEDED( hr );i++) + { + hr = SafeArrayPutElement(psa, &i,&varCriteria[i]); + } + + OLEVariant vtEmpty; + vtEmpty.setNoArg(); + + // Initialize and fill the SafeArray + OLEVariant vsa; + vsa.setArray(psa,VT_VARIANT); + + ADORecordset *pRecordset = nullptr; + OpenSchema(adSchemaTables,vsa,vtEmpty,&pRecordset); + + return pRecordset; +} + +ADORecordset* WpADOConnection::getColumns( const css::uno::Any& catalog, + const OUString& schemaPattern, + const OUString& tableNamePattern, + std::u16string_view columnNamePattern ) +{ + // Create elements used in the array + SAFEARRAYBOUND rgsabound[1]; + SAFEARRAY *psa = nullptr; + OLEVariant varCriteria[4]; + + // Create SafeArray Bounds and initialize the array + rgsabound[0].lLbound = 0; + rgsabound[0].cElements = std::size(varCriteria); + psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound ); + + sal_Int32 nPos=0; + if(catalog.hasValue()) + varCriteria[nPos].setString(::comphelper::getString(catalog)); + + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_CATALOG + if(schemaPattern.getLength() && schemaPattern.toChar() != '%') + varCriteria[nPos].setString(schemaPattern); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_SCHEMA + + if(tableNamePattern.toChar() != '%') + varCriteria[nPos].setString(tableNamePattern); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_NAME + + varCriteria[nPos].setString(columnNamePattern); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// COLUMN_NAME + + OLEVariant vtEmpty; + vtEmpty.setNoArg(); + + // Initialize and fill the SafeArray + OLEVariant vsa; + vsa.setArray(psa,VT_VARIANT); + + ADORecordset *pRecordset = nullptr; + OpenSchema(adSchemaColumns,vsa,vtEmpty,&pRecordset); + + return pRecordset; +} + +ADORecordset* WpADOConnection::getColumnPrivileges( const css::uno::Any& catalog, + const OUString& schema, + std::u16string_view table, + std::u16string_view columnNamePattern ) +{ + // Create elements used in the array + SAFEARRAYBOUND rgsabound[1]; + SAFEARRAY *psa = nullptr; + OLEVariant varCriteria[4]; + + // Create SafeArray Bounds and initialize the array + rgsabound[0].lLbound = 0; + rgsabound[0].cElements = std::size(varCriteria); + psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound ); + + sal_Int32 nPos=0; + if(catalog.hasValue()) + varCriteria[nPos].setString(::comphelper::getString(catalog)); + + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_CATALOG + if(schema.getLength() && schema.toChar() != '%') + varCriteria[nPos].setString(schema); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_SCHEMA + + varCriteria[nPos].setString(table); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// TABLE_NAME + + varCriteria[nPos].setString(columnNamePattern); + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++;// COLUMN_NAME + + OLEVariant vtEmpty; + vtEmpty.setNoArg(); + + // Initialize and fill the SafeArray + OLEVariant vsa; + vsa.setArray(psa,VT_VARIANT); + + ADORecordset *pRecordset = nullptr; + OpenSchema(adSchemaColumnPrivileges,vsa,vtEmpty,&pRecordset); + + return pRecordset; +} + +ADORecordset* WpADOConnection::getTypeInfo(DataTypeEnum /*_eType*/) +{ + // Create elements used in the array + OLEVariant varCriteria[2]; + const int nCrit = std::size(varCriteria); + // Create SafeArray Bounds and initialize the array + SAFEARRAYBOUND rgsabound[1]; + rgsabound[0].lLbound = 0; + rgsabound[0].cElements = nCrit; + SAFEARRAY *psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound ); + + sal_Int32 nPos = 0; + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++; + SafeArrayPutElement(psa,&nPos,&varCriteria[nPos]);nPos++; + + // Initialize and fill the SafeArray + OLEVariant vsa; + vsa.setArray(psa,VT_VARIANT); + + OLEVariant aEmpty; + aEmpty.setNoArg(); + + ADORecordset *pRec=nullptr; + OpenSchema(adSchemaProviderTypes,vsa,aEmpty,&pRec); + + return pRec; +} + +void WpADOColumn::put_ParentCatalog(/* [in] */ _ADOCatalog __RPC_FAR *ppvObject) +{ + assert(pInterface); + bool bRet = SUCCEEDED(pInterface->put_ParentCatalog(ppvObject)); + SAL_WARN_IF(!bRet, "connectivity.ado", "Could not set ParentCatalog!"); +} + +void WpADOTable::putref_ParentCatalog(/* [in] */ _ADOCatalog __RPC_FAR *ppvObject) +{ + assert(pInterface); + bool bRet = SUCCEEDED(pInterface->putref_ParentCatalog(ppvObject)); + SAL_WARN_IF(!bRet, "connectivity.ado", "Could not set ParentCatalog!"); +} + +void OTools::putValue(const WpADOProperties& _rProps,const OLEVariant &_aPosition,const OLEVariant &_aValVar) +{ + SAL_WARN_IF(!_rProps.IsValid(), "connectivity.ado", "Properties are not valid!"); + WpADOProperty aProp(_rProps.GetItem(_aPosition)); + if ( aProp.IsValid() ) + { + bool bRet = aProp.PutValue(_aValVar); + SAL_WARN_IF(!bRet, "connectivity.ado", "Could not put value!"); + } +} + +OLEVariant OTools::getValue(const WpADOProperties& _rProps,const OLEVariant &_aPosition) +{ + WpADOProperty aProp(_rProps.GetItem(_aPosition)); + return aProp.GetValue(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/ado/ado.component b/connectivity/source/drivers/ado/ado.component new file mode 100644 index 000000000..7c97fb2d8 --- /dev/null +++ b/connectivity/source/drivers/ado/ado.component @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + --> + +<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@:affine" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.comp.sdbc.ado.ODriver" + constructor="connectivity_ado_ODriver_get_implementation"> + <service name="com.sun.star.sdbc.Driver"/> + <service name="com.sun.star.sdbcx.Driver"/> + </implementation> +</component> diff --git a/connectivity/source/drivers/ado/adoimp.cxx b/connectivity/source/drivers/ado/adoimp.cxx new file mode 100644 index 000000000..0f0d02268 --- /dev/null +++ b/connectivity/source/drivers/ado/adoimp.cxx @@ -0,0 +1,325 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <com/sun/star/sdbcx/Privilege.hpp> +#include <com/sun/star/sdbcx/PrivilegeObject.hpp> +#include <connectivity/dbexception.hxx> +#include <ado/Awrapado.hxx> +#include <ado/adoimp.hxx> +#include <osl/diagnose.h> +#include <systools/win32/oleauto.hxx> +#include <com/sun/star/sdbc/DataType.hpp> + + +using namespace connectivity::ado; +using namespace com::sun::star::uno; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::sdbcx; + + +#define MYADOID(l) {l, 0,0x10,{0x80,0,0,0xAA,0,0x6D,0x2E,0xA4}}; + +const CLSID ADOS::CLSID_ADOCONNECTION_21 = MYADOID(0x00000514); +const IID ADOS::IID_ADOCONNECTION_21 = MYADOID(0x00000550); + +const CLSID ADOS::CLSID_ADOCOMMAND_21 = MYADOID(0x00000507); +const IID ADOS::IID_ADOCOMMAND_21 = MYADOID(0x0000054E); + +const CLSID ADOS::CLSID_ADORECORDSET_21 = MYADOID(0x00000535); +const IID ADOS::IID_ADORECORDSET_21 = MYADOID(0x0000054F); + +const CLSID ADOS::CLSID_ADOCATALOG_25 = MYADOID(0x00000602); +const IID ADOS::IID_ADOCATALOG_25 = MYADOID(0x00000603); + +const CLSID ADOS::CLSID_ADOINDEX_25 = MYADOID(0x0000061E); +const IID ADOS::IID_ADOINDEX_25 = MYADOID(0x0000061F); + +const CLSID ADOS::CLSID_ADOTABLE_25 = MYADOID(0x00000609); +const IID ADOS::IID_ADOTABLE_25 = MYADOID(0x00000610); + +const CLSID ADOS::CLSID_ADOKEY_25 = MYADOID(0x00000621); +const IID ADOS::IID_ADOKEY_25 = MYADOID(0x00000622); + +const CLSID ADOS::CLSID_ADOCOLUMN_25 = MYADOID(0x0000061B); +const IID ADOS::IID_ADOCOLUMN_25 = MYADOID(0x0000061C); + +const CLSID ADOS::CLSID_ADOGROUP_25 = MYADOID(0x00000615); +const IID ADOS::IID_ADOGROUP_25 = MYADOID(0x00000616); + +const CLSID ADOS::CLSID_ADOUSER_25 = MYADOID(0x00000618); +const IID ADOS::IID_ADOUSER_25 = MYADOID(0x00000619); + +const CLSID ADOS::CLSID_ADOVIEW_25 = MYADOID(0x00000612); +const IID ADOS::IID_ADOVIEW_25 = MYADOID(0x00000613); + +sal::systools::BStr& ADOS::GetKeyStr() +{ + static sal::systools::BStr sKeyStr(u"gxwaezucfyqpwjgqbcmtsncuhwsnyhiohwxz"); + return sKeyStr; +} + + +sal_Int32 ADOS::MapADOType2Jdbc(DataTypeEnum eType) +{ + sal_Int32 nType = DataType::VARCHAR; + switch (eType) + { + case adUnsignedSmallInt: + case adSmallInt: nType = DataType::SMALLINT; break; + case adUnsignedInt: + case adInteger: nType = DataType::INTEGER; break; + case adUnsignedBigInt: + case adBigInt: nType = DataType::BIGINT; break; + case adSingle: nType = DataType::FLOAT; break; + case adDouble: nType = DataType::DOUBLE; break; + case adCurrency: nType = DataType::DOUBLE; break; + case adVarNumeric: + case adNumeric: nType = DataType::NUMERIC; break; + case adDecimal: nType = DataType::DECIMAL; break; + case adDBDate: nType = DataType::DATE; break; + case adDBTime: nType = DataType::TIME; break; + case adDate: + case adDBTimeStamp: nType = DataType::TIMESTAMP; break; + case adBoolean: nType = DataType::BOOLEAN; break; +// case adArray: nType = DataType::ARRAY; break; + case adBinary: nType = DataType::BINARY; break; + case adGUID: nType = DataType::OBJECT; break; + case adBSTR: + case adVarWChar: + case adWChar: + case adVarChar: nType = DataType::VARCHAR; break; + case adLongVarWChar: + case adLongVarChar: nType = DataType::LONGVARCHAR; break; + case adVarBinary: nType = DataType::VARBINARY; break; + case adLongVarBinary: nType = DataType::LONGVARBINARY;break; + case adChar: nType = DataType::CHAR; break; + case adUnsignedTinyInt: + case adTinyInt: nType = DataType::TINYINT; break; + case adEmpty: nType = DataType::SQLNULL; break; + case adUserDefined: + case adPropVariant: + case adFileTime: + case adChapter: + case adIDispatch: + case adIUnknown: + case adError: + case adVariant: + nType = DataType::OTHER; break; + default: + OSL_FAIL("MapADOType2Jdbc: Unknown Type!"); + ; + } + return nType; +} + +DataTypeEnum ADOS::MapJdbc2ADOType(sal_Int32 _nType,sal_Int32 _nJetEngine) +{ + switch (_nType) + { + case DataType::SMALLINT: return adSmallInt; break; + case DataType::INTEGER: return adInteger; break; + case DataType::BIGINT: return adBigInt; break; + case DataType::FLOAT: return adSingle; break; + case DataType::DOUBLE: return adDouble; break; + case DataType::NUMERIC: return adNumeric; break; + case DataType::DECIMAL: return adDecimal; break; + case DataType::DATE: return isJetEngine(_nJetEngine) ? adDate : adDBDate; break; + case DataType::TIME: return adDBTime; break; + case DataType::TIMESTAMP: return isJetEngine(_nJetEngine) ? adDate : adDBTimeStamp; break; + case DataType::BOOLEAN: + case DataType::BIT: return adBoolean; break; + case DataType::BINARY: return adBinary; break; + case DataType::VARCHAR: return adVarWChar; break; + case DataType::CLOB: + case DataType::LONGVARCHAR: return adLongVarWChar; break; + case DataType::VARBINARY: return adVarBinary; break; + case DataType::BLOB: + case DataType::LONGVARBINARY: return adLongVarBinary; break; + case DataType::CHAR: return adWChar; break; + case DataType::TINYINT: return isJetEngine(_nJetEngine) ? adUnsignedTinyInt : adTinyInt;break; + case DataType::OBJECT: return adGUID; break; + default: + OSL_FAIL("MapJdbc2ADOType: Unknown Type!"); + ; + } + return adEmpty; +} + +const int JET_ENGINETYPE_UNKNOWN = 0; +const int JET_ENGINETYPE_JET10 = 1; +const int JET_ENGINETYPE_JET11 = 2; +const int JET_ENGINETYPE_JET20 = 3; +const int JET_ENGINETYPE_JET3X = 4; +const int JET_ENGINETYPE_JET4X = 5; +const int JET_ENGINETYPE_DBASE3 = 10; +const int JET_ENGINETYPE_DBASE4 = 11; +const int JET_ENGINETYPE_DBASE5 = 12; +const int JET_ENGINETYPE_EXCEL30 = 20; +const int JET_ENGINETYPE_EXCEL40 = 21; +const int JET_ENGINETYPE_EXCEL50 = 22; +const int JET_ENGINETYPE_EXCEL80 = 23; +const int JET_ENGINETYPE_EXCEL90 = 24; +const int JET_ENGINETYPE_EXCHANGE4 = 30; +const int JET_ENGINETYPE_LOTUSWK1 = 40; +const int JET_ENGINETYPE_LOTUSWK3 = 41; +const int JET_ENGINETYPE_LOTUSWK4 = 42; +const int JET_ENGINETYPE_PARADOX3X = 50; +const int JET_ENGINETYPE_PARADOX4X = 51; +const int JET_ENGINETYPE_PARADOX5X = 52; +const int JET_ENGINETYPE_PARADOX7X = 53; +const int JET_ENGINETYPE_TEXT1X = 60; +const int JET_ENGINETYPE_HTML1X = 70; + +bool ADOS::isJetEngine(sal_Int32 _nEngineType) +{ + bool bRet = false; + switch(_nEngineType) + { + case JET_ENGINETYPE_UNKNOWN: + case JET_ENGINETYPE_JET10: + case JET_ENGINETYPE_JET11: + case JET_ENGINETYPE_JET20: + case JET_ENGINETYPE_JET3X: + case JET_ENGINETYPE_JET4X: + case JET_ENGINETYPE_DBASE3: + case JET_ENGINETYPE_DBASE4: + case JET_ENGINETYPE_DBASE5: + case JET_ENGINETYPE_EXCEL30: + case JET_ENGINETYPE_EXCEL40: + case JET_ENGINETYPE_EXCEL50: + case JET_ENGINETYPE_EXCEL80: + case JET_ENGINETYPE_EXCEL90: + case JET_ENGINETYPE_EXCHANGE4: + case JET_ENGINETYPE_LOTUSWK1: + case JET_ENGINETYPE_LOTUSWK3: + case JET_ENGINETYPE_LOTUSWK4: + case JET_ENGINETYPE_PARADOX3X: + case JET_ENGINETYPE_PARADOX4X: + case JET_ENGINETYPE_PARADOX5X: + case JET_ENGINETYPE_PARADOX7X: + case JET_ENGINETYPE_TEXT1X: + case JET_ENGINETYPE_HTML1X: + bRet = true; + break; + } + return bRet; +} + +ObjectTypeEnum ADOS::mapObjectType2Ado(sal_Int32 objType) +{ + ObjectTypeEnum eType = adPermObjTable; + switch(objType) + { + case PrivilegeObject::TABLE: + eType = adPermObjTable; + break; + case PrivilegeObject::VIEW: + eType = adPermObjView; + break; + case PrivilegeObject::COLUMN: + eType = adPermObjColumn; + break; + } + return eType; +} + +sal_Int32 ADOS::mapAdoType2Object(ObjectTypeEnum objType) +{ + sal_Int32 nType = PrivilegeObject::TABLE; + switch(objType) + { + case adPermObjTable: + nType = PrivilegeObject::TABLE; + break; + case adPermObjView: + nType = PrivilegeObject::VIEW; + break; + case adPermObjColumn: + nType = PrivilegeObject::COLUMN; + break; + default: + OSL_FAIL( "ADOS::mapAdoType2Object: privilege type cannot be translated!" ); + break; + } + return nType; +} +#ifdef DELETE +#undef DELETE +#endif + +sal_Int32 ADOS::mapAdoRights2Sdbc(RightsEnum eRights) +{ + sal_Int32 nRights = 0; + if((eRights & adRightInsert) == adRightInsert) + nRights |= Privilege::INSERT; + if((eRights & adRightDelete) == adRightDelete) + nRights |= css::sdbcx::Privilege::DELETE; + if((eRights & adRightUpdate) == adRightUpdate) + nRights |= Privilege::UPDATE; + if((eRights & adRightWriteDesign) == adRightWriteDesign) + nRights |= Privilege::ALTER; + if((eRights & adRightRead) == adRightRead) + nRights |= Privilege::SELECT; + if((eRights & adRightReference) == adRightReference) + nRights |= Privilege::REFERENCE; + if((eRights & adRightDrop) == adRightDrop) + nRights |= Privilege::DROP; + + return nRights; +} + +sal_Int32 ADOS::mapRights2Ado(sal_Int32 nRights) +{ + sal_Int32 eRights = adRightNone; + + if((nRights & Privilege::INSERT) == Privilege::INSERT) + eRights |= adRightInsert; + if((nRights & Privilege::DELETE) == Privilege::DELETE) + eRights |= adRightDelete; + if((nRights & Privilege::UPDATE) == Privilege::UPDATE) + eRights |= adRightUpdate; + if((nRights & Privilege::ALTER) == Privilege::ALTER) + eRights |= adRightWriteDesign; + if((nRights & Privilege::SELECT) == Privilege::SELECT) + eRights |= adRightRead; + if((nRights & Privilege::REFERENCE) == Privilege::REFERENCE) + eRights |= adRightReference; + if((nRights & Privilege::DROP) == Privilege::DROP) + eRights |= adRightDrop; + + return eRights; +} + +WpADOField ADOS::getField(ADORecordset* _pRecordSet,sal_Int32 _nColumnIndex) +{ + if ( !_pRecordSet ) + return WpADOField(); + + WpOLEAppendCollection<ADOFields, WpADOField> aFields; + _pRecordSet->get_Fields(&aFields); + if(_nColumnIndex <= 0 || _nColumnIndex > aFields.GetItemCount()) + ::dbtools::throwInvalidIndexException(nullptr); + WpADOField aField(aFields.GetItem(_nColumnIndex-1)); + if(!aField.IsValid()) + ::dbtools::throwInvalidIndexException(nullptr); + return aField; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |