Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/dbaccess/source/ui/misc/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 53 kB image not shown  

Quelle  UITools.cxx   Sprache: C

 
/* -*- 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 <UITools.hxx>
#include <sfx2/docfilt.hxx>
#include <core_resource.hxx>
#include <dlgsave.hxx>
#include <defaultobjectnamecheck.hxx>
#include <strings.hxx>
#include <comphelper/extract.hxx>
#include <com/sun/star/sdb/DatabaseContext.hpp>
#include <com/sun/star/sdb/XSingleSelectQueryAnalyzer.hpp>
#include <com/sun/star/sdb/XCompletedConnection.hpp>
#include <com/sun/star/sdbc/XDataSource.hpp>
#include <com/sun/star/sdb/SQLContext.hpp>
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#include <com/sun/star/sdbcx/XViewsSupplier.hpp>
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
#include <com/sun/star/sdbcx/XAppend.hpp>
#include <com/sun/star/sdbc/XRow.hpp>
#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
#include <com/sun/star/sdbc/ColumnValue.hpp>
#include <com/sun/star/task/InteractionHandler.hpp>
#include <com/sun/star/ucb/XContent.hpp>
#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/ucb/InteractiveIOException.hpp>
#include <com/sun/star/sdb/XDocumentDataSource.hpp>
#include <com/sun/star/ucb/IOErrorCode.hpp>
#include <vcl/syswin.hxx>
#include <vcl/settings.hxx>
#include <vcl/svapp.hxx>
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/container/XHierarchicalNameContainer.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/awt/TextAlign.hpp>
#include <TypeInfo.hxx>
#include <FieldDescriptions.hxx>
#include <comphelper/stl_types.hxx>
#include <comphelper/types.hxx>
#include <comphelper/propertysequence.hxx>

#include <svx/svxids.hrc>

#include <sal/log.hxx>
#include <svl/numformat.hxx>
#include <svl/itempool.hxx>
#include <helpids.h>
#include <svl/itemset.hxx>
#include <sbagrid.hrc>
#include <svl/rngitem.hxx>
#include <svl/intitem.hxx>
#include <svx/numinf.hxx>
#include <svl/zforlist.hxx>
#include <dlgattr.hxx>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/util/NumberFormatter.hpp>
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
#include <com/sun/star/util/XNumberFormatter.hpp>
#include <strings.hrc>
#include <sqlmessage.hxx>
#include <dlgsize.hxx>
#include <svtools/editbrowsebox.hxx>
#include <tools/urlobj.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <svl/numuno.hxx>
#include <svl/filenotation.hxx>
#include <connectivity/FValue.hxx>

#include <editeng/justifyitem.hxx>
#include <memory>

namespace dbaui
{
using namespace ::dbtools;
using namespace ::comphelper;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::task;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::ucb;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace ::svt;
using ::com::sun::star::ucb::InteractiveIOException;
using ::com::sun::star::ucb::IOErrorCode_NO_FILE;
using ::com::sun::star::ucb::IOErrorCode_NOT_EXISTING;

SQLExceptionInfo createConnection(  const OUString& _rsDataSourceName,
                                     const Reference< css::container::XNameAccess >& _xDatabaseContext,
                                    const Reference< css::uno::XComponentContext >& _rxContext,
                                    Reference< css::lang::XEventListener> const & _rEvtLst,
                                    Reference< css::sdbc::XConnection>& _rOUTConnection )
{
    Reference<XPropertySet> xProp;
    try
    {
        xProp.set(_xDatabaseContext->getByName(_rsDataSourceName),UNO_QUERY);
    }
    catch(const Exception&)
    {
    }

    return createConnection(xProp,_rxContext,_rEvtLst,_rOUTConnection);
}

SQLExceptionInfo createConnection(  const Reference< css::beans::XPropertySet>& _xDataSource,
                                    const Reference< css::uno::XComponentContext >& _rxContext,
                                    Reference< css::lang::XEventListener> const & _rEvtLst,
                                    Reference< css::sdbc::XConnection>& _rOUTConnection )
{
    SQLExceptionInfo aInfo;
    if ( !_xDataSource.is() )
    {
        SAL_WARN("dbaccess.ui""createConnection: could not retrieve the data source!");
        return aInfo;
    }

    OUString sPwd, sUser;
    bool bPwdReq = false;
    try
    {
        _xDataSource->getPropertyValue(PROPERTY_PASSWORD) >>= sPwd;
        bPwdReq = ::cppu::any2bool(_xDataSource->getPropertyValue(PROPERTY_ISPASSWORDREQUIRED));
        _xDataSource->getPropertyValue(PROPERTY_USER) >>= sUser;
    }
    catch(const Exception&)
    {
        SAL_WARN("dbaccess.ui""createConnection: error while retrieving data source properties!");
    }

    try
    {
        if(bPwdReq && sPwd.isEmpty())
        {   // password required, but empty -> connect using an interaction handler
            Reference<XCompletedConnection> xConnectionCompletion(_xDataSource, UNO_QUERY);
            if (!xConnectionCompletion.is())
            {
                SAL_WARN("dbaccess.ui""createConnection: missing an interface ... need an error message here!");
            }
            else
            {   // instantiate the default SDB interaction handler
                Reference< XInteractionHandler > xHandler = InteractionHandler::createWithParent(_rxContext, nullptr);
                _rOUTConnection = xConnectionCompletion->connectWithCompletion(xHandler);
            }
        }
        else
        {
            Reference<XDataSource> xDataSource(_xDataSource,UNO_QUERY);
            _rOUTConnection = xDataSource->getConnection(sUser, sPwd);
        }
        // be notified when connection is in disposing
        Reference< XComponent >  xComponent(_rOUTConnection, UNO_QUERY);
        if (xComponent.is() && _rEvtLst.is())
            xComponent->addEventListener(_rEvtLst);
    }
    catch(const SQLContext& e) { aInfo = SQLExceptionInfo(e); }
    catch(const SQLWarning& e) { aInfo = SQLExceptionInfo(e); }
    catch(const SQLException& e) { aInfo = SQLExceptionInfo(e); }
    catch(const Exception&) {
        TOOLS_WARN_EXCEPTION("dbaccess.ui""SbaTableQueryBrowser::OnExpandEntry: could not connect - unknown exception");
    }

    return aInfo;
}

Reference< XDataSource > getDataSourceByName( const OUString& _rDataSourceName,
    weld::Window* _pErrorMessageParent, const Reference< XComponentContext >& _rxContext, ::dbtools::SQLExceptionInfo* _pErrorInfo )
{
    Reference< XDatabaseContext > xDatabaseContext = DatabaseContext::create(_rxContext);

    Reference< XDataSource > xDatasource;
    SQLExceptionInfo aSQLError;
    try
    {
        xDatabaseContext->getByName( _rDataSourceName ) >>= xDatasource;
    }
    catch(const WrappedTargetException& e)
    {
        InteractiveIOException aIOException;
        if  (   ( e.TargetException >>= aIOException )
            &&  (   ( aIOException.Code == IOErrorCode_NO_FILE )
                ||  ( aIOException.Code == IOErrorCode_NOT_EXISTING )
                )
            )
        {
            OUString sErrorMessage( DBA_RES( STR_FILE_DOES_NOT_EXIST ) );
            OFileNotation aTransformer( e.Message );
            sErrorMessage = sErrorMessage.replaceFirst( "$file$", aTransformer.get( OFileNotation::N_SYSTEM ) );
            aSQLError = SQLExceptionInfo( sErrorMessage ).get();
        }
        else
        {
            aSQLError = SQLExceptionInfo( e.TargetException );
        }
    }
    catchconst Exception& )
    {
        DBG_UNHANDLED_EXCEPTION("dbaccess");
    }

    if ( xDatasource.is() )
        return xDatasource;

    if ( aSQLError.isValid() )
    {
        if ( _pErrorInfo )
        {
            *_pErrorInfo = std::move(aSQLError);
        }
        else
        {
            showError( aSQLError, _pErrorMessageParent ? _pErrorMessageParent->GetXWindow() : nullptr, _rxContext );
        }
    }

    return Reference<XDataSource>();
}

Reference< XInterface > getDataSourceOrModel(const Reference< XInterface >& _xObject)
{
    Reference< XInterface > xRet;
    Reference<XDocumentDataSource> xDocumentDataSource(_xObject,UNO_QUERY);
    if ( xDocumentDataSource.is() )
        xRet = xDocumentDataSource->getDatabaseDocument();

    if ( !xRet.is() )
    {
        Reference<XOfficeDatabaseDocument> xOfficeDoc(_xObject,UNO_QUERY);
        if ( xOfficeDoc.is() )
            xRet = xOfficeDoc->getDataSource();
    }

    return xRet;
}

TOTypeInfoSP getTypeInfoFromType(const OTypeInfoMap& _rTypeInfo,
                               sal_Int32 _nType,
                               const OUString& _sTypeName,
                               const OUString& _sCreateParams,
                               sal_Int32 _nPrecision,
                               sal_Int32 _nScale,
                               bool _bAutoIncrement,
                               bool& _brForceToType)
{
    TOTypeInfoSP pTypeInfo;
    _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
    #ifdef DBG_UTIL
            OUString sDBTypeName         = aIter->second->aTypeName;         (void)sDBTypeName;
    #endif
            if  (   (
                        _sTypeName.isEmpty()
                    ||  (aIter->second->aTypeName.equalsIgnoreAsciiCase(_sTypeName))
                    )
                &&  (
                        (
                                !aIter->second->aCreateParams.getLength()
                            &&  _sCreateParams.isEmpty()
                        )
                    ||  (
                                (aIter->second->nPrecision      >= _nPrecision)
                            &&  (aIter->second->nMaximumScale   >= _nScale)
                            &&  ( (_bAutoIncrement && aIter->second->bAutoIncrement) || !_bAutoIncrement )
                        )
                    )
                )
                break;
        }

        if (aIter == aPair.second)
        {
            for(aIter = aPair.first; aIter != aPair.second; ++aIter)
            {
                sal_Int32 nPrec = aIter->second->nPrecision;
                sal_Int32 nScale = aIter->second->nMaximumScale;
                // search the best matching type (now comparing the local names)
                if  (   (aIter->second->aLocalTypeName.equalsIgnoreAsciiCase(_sTypeName))
                    &&  (nPrec  >= _nPrecision)
                    &&  (nScale >= _nScale)
                    &&  ( (_bAutoIncrement && aIter->second->bAutoIncrement) || !_bAutoIncrement )
                    )
                {
                    SAL_WARN("dbaccess.ui""getTypeInfoFromType: assuming column type " <<
                             aIter->second->aTypeName <<  "\" (expected type name " <<
                             _sTypeName << " matches the type's local name).");
                    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)

            for(aIter = aPair.first; aIter != aPair.second; ++aIter)
            {
                // search the best matching type (now comparing the local names)
                sal_Int32 nPrec = aIter->second->nPrecision;
                sal_Int32 nScale = aIter->second->nMaximumScale;
                if  (   (nPrec  >= _nPrecision)
                    &&  (nScale >= _nScale)
                    &&  ( (_bAutoIncrement && aIter->second->bAutoIncrement) || !_bAutoIncrement )
                    )
                    break;
            }
        }
        if (aIter == aPair.second)
        {
            if ( _bAutoIncrement )
            {
                for(aIter = aPair.first; aIter != aPair.second; ++aIter)
                {
                    // search the best matching type (now comparing the local names)
                    sal_Int32 nScale = aIter->second->nMaximumScale;
                    if  (   (nScale >= _nScale)
                        &&  (aIter->second->bAutoIncrement  == _bAutoIncrement)
                        )
                        break;
                }
                if ( aIter == aPair.second )
                {
                    // try it without the auto increment flag
                    pTypeInfo = getTypeInfoFromType(_rTypeInfo,
                                   _nType,
                                   _sTypeName,
                                   _sCreateParams,
                                   _nPrecision,
                                   _nScale,
                                   false,
                                   _brForceToType);
                }
                else
                    pTypeInfo = aIter->second;
            }
            else
            {
                pTypeInfo = aPair.first->second;
                _brForceToType = true;
            }
        }
        else
            pTypeInfo = aIter->second;
    }
    else
    {
        ::comphelper::UStringMixEqual aCase(false);
        // search for typeinfo where the typename is equal _sTypeName
        for (auto const& elem : _rTypeInfo)
        {
            if ( aCase( elem.second->getDBName() , _sTypeName ) )
            {
                pTypeInfo = elem.second;
                break;
            }
        }
    }

    OSL_ENSURE(pTypeInfo, "getTypeInfoFromType: no type info found for this type!");
    return pTypeInfo;
}

void fillTypeInfo(  const Reference< css::sdbc::XConnection>& _rxConnection,
                    std::u16string_view _rsTypeNames,
                    OTypeInfoMap& _rTypeInfoMap,
                    std::vector<OTypeInfoMap::iterator>& _rTypeInfoIters)
{
    if(!_rxConnection.is())
        return;
    Reference< XResultSet> xRs = _rxConnection->getMetaData ()->getTypeInfo ();
    Reference< XRow> xRow(xRs,UNO_QUERY);
    // Information for a single SQL type
    if(!xRs.is())
        return;

    Reference<XResultSetMetaData> xResultSetMetaData = Reference<XResultSetMetaDataSupplier>(xRs,UNO_QUERY_THROW)->getMetaData();
    ::connectivity::ORowSetValue aValue;
    std::vector<sal_Int32> aTypes;
    std::vector<bool> aNullable;
    // Loop on the result set until we reach end of file
    while (xRs->next())
    {
        TOTypeInfoSP pInfo = std::make_shared<OTypeInfo>();
        sal_Int32 nPos = 1;
        if ( aTypes.empty() )
        {
            sal_Int32 nCount = xResultSetMetaData->getColumnCount();
            if ( nCount < 1 )
                nCount = 18;
            aTypes.reserve(nCount+1);
            aTypes.push_back(-1);
            aNullable.push_back(false);
            for (sal_Int32 j = 1; j <= nCount ; ++j)
            {
                aTypes.push_back(xResultSetMetaData->getColumnType(j));
                aNullable.push_back(xResultSetMetaData->isNullable(j) != ColumnValue::NO_NULLS);
            }
        }

        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
        pInfo->aTypeName        = aValue.getString();
        ++nPos;
        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
        pInfo->nType            = aValue.getInt32();
        ++nPos;
        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
        pInfo->nPrecision       = aValue.getInt32();
        ++nPos;
        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow); // LiteralPrefix
        ++nPos;
        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow); //LiteralSuffix
        ++nPos;
        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
        pInfo->aCreateParams    = aValue.getString();
        ++nPos;
        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
        pInfo->bNullable        = aValue.getInt32() == ColumnValue::NULLABLE;
        ++nPos;
        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
        // bCaseSensitive
        ++nPos;
        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
        pInfo->nSearchType      = aValue.getInt16();
        ++nPos;
        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
        // bUnsigned
        ++nPos;
        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
        pInfo->bCurrency        = aValue.getBool();
        ++nPos;
        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
        pInfo->bAutoIncrement   = aValue.getBool();
        ++nPos;
        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
        pInfo->aLocalTypeName   = aValue.getString();
        ++nPos;
        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
        pInfo->nMinimumScale    = aValue.getInt16();
        ++nPos;
        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
        pInfo->nMaximumScale    = aValue.getInt16();
        assert(nPos == 15);
        // 16 and 17 are unused
        nPos = 18;
        aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
        pInfo->nNumPrecRadix    = aValue.getInt32();

        // check if values are less than zero like it happens in a oracle jdbc driver
        if( pInfo->nPrecision < 0)
            pInfo->nPrecision = 0;
        if( pInfo->nMinimumScale < 0)
            pInfo->nMinimumScale = 0;
        if( pInfo->nMaximumScale < 0)
            pInfo->nMaximumScale = 0;
        if( pInfo->nNumPrecRadix <= 1)
            pInfo->nNumPrecRadix = 10;

        std::u16string_view aName;
        switch(pInfo->nType)
        {
            case DataType::CHAR:
                aName = o3tl::getToken(_rsTypeNames, TYPE_CHAR, ';');
                break;
            case DataType::VARCHAR:
                aName = o3tl::getToken(_rsTypeNames, TYPE_TEXT, ';');
                break;
            case DataType::DECIMAL:
                aName = o3tl::getToken(_rsTypeNames, TYPE_DECIMAL, ';');
                break;
            case DataType::NUMERIC:
                aName = o3tl::getToken(_rsTypeNames, TYPE_NUMERIC, ';');
                break;
            case DataType::BIGINT:
                aName = o3tl::getToken(_rsTypeNames, TYPE_BIGINT, ';');
                break;
            case DataType::FLOAT:
                aName = o3tl::getToken(_rsTypeNames, TYPE_FLOAT, ';');
                break;
            case DataType::DOUBLE:
                aName = o3tl::getToken(_rsTypeNames, TYPE_DOUBLE, ';');
                break;
            case DataType::LONGVARCHAR:
                aName = o3tl::getToken(_rsTypeNames, TYPE_MEMO, ';');
                break;
            case DataType::LONGVARBINARY:
                aName = o3tl::getToken(_rsTypeNames, TYPE_IMAGE, ';');
                break;
            case DataType::DATE:
                aName = o3tl::getToken(_rsTypeNames, TYPE_DATE, ';');
                break;
            case DataType::TIME:
                aName = o3tl::getToken(_rsTypeNames, TYPE_TIME, ';');
                break;
            case DataType::TIMESTAMP:
                aName = o3tl::getToken(_rsTypeNames, TYPE_DATETIME, ';');
                break;
            case DataType::BIT:
                if ( !pInfo->aCreateParams.isEmpty() )
                {
                    aName = o3tl::getToken(_rsTypeNames, TYPE_BIT, ';');
                    break;
                }
                [[fallthrough]];
            case DataType::BOOLEAN:
                aName = o3tl::getToken(_rsTypeNames, TYPE_BOOL, ';');
                break;
            case DataType::TINYINT:
                aName = o3tl::getToken(_rsTypeNames, TYPE_TINYINT, ';');
                break;
            case DataType::SMALLINT:
                aName = o3tl::getToken(_rsTypeNames, TYPE_SMALLINT, ';');
                break;
            case DataType::INTEGER:
                aName = o3tl::getToken(_rsTypeNames, TYPE_INTEGER, ';');
                break;
            case DataType::REAL:
                aName = o3tl::getToken(_rsTypeNames, TYPE_REAL, ';');
                break;
            case DataType::BINARY:
                aName = o3tl::getToken(_rsTypeNames, TYPE_BINARY, ';');
                break;
            case DataType::VARBINARY:
                aName = o3tl::getToken(_rsTypeNames, TYPE_VARBINARY, ';');
                break;
            case DataType::SQLNULL:
                aName = o3tl::getToken(_rsTypeNames, TYPE_SQLNULL, ';');
                break;
            case DataType::OBJECT:
                aName = o3tl::getToken(_rsTypeNames, TYPE_OBJECT, ';');
                break;
            case DataType::DISTINCT:
                aName = o3tl::getToken(_rsTypeNames, TYPE_DISTINCT, ';');
                break;
            case DataType::STRUCT:
                aName = o3tl::getToken(_rsTypeNames, TYPE_STRUCT, ';');
                break;
            case DataType::ARRAY:
                aName = o3tl::getToken(_rsTypeNames, TYPE_ARRAY, ';');
                break;
            case DataType::BLOB:
                aName = o3tl::getToken(_rsTypeNames, TYPE_BLOB, ';');
                break;
            case DataType::CLOB:
                aName = o3tl::getToken(_rsTypeNames, TYPE_CLOB, ';');
                break;
            case DataType::REF:
                aName = o3tl::getToken(_rsTypeNames, TYPE_REF, ';');
                break;
            case DataType::OTHER:
                aName = o3tl::getToken(_rsTypeNames, TYPE_OTHER, ';');
                break;
        }
        if ( !aName.empty() )
        {
            pInfo->aUIName = aName;
            pInfo->aUIName += " [ ";
        }
        pInfo->aUIName += pInfo->aTypeName;
        if ( !aName.empty() )
            pInfo->aUIName += " ]";
        // Now that we have the type info, save it in the multimap
        _rTypeInfoMap.emplace(pInfo->nType,pInfo);
    }
    // for a faster index access
    _rTypeInfoIters.reserve(_rTypeInfoMap.size());

    OTypeInfoMap::iterator aIter = _rTypeInfoMap.begin();
    OTypeInfoMap::const_iterator aEnd = _rTypeInfoMap.end();
    for(;aIter != aEnd;++aIter)
        _rTypeInfoIters.push_back(aIter);

    // Close the result set/statement.

    ::comphelper::disposeComponent(xRs);
}

void setColumnProperties(const Reference<XPropertySet>& _rxColumn,const OFieldDescription* _pFieldDesc)
{
    _rxColumn->setPropertyValue(PROPERTY_NAME,Any(_pFieldDesc->GetName()));
    _rxColumn->setPropertyValue(PROPERTY_TYPENAME,Any(_pFieldDesc->getTypeInfo()->aTypeName));
    _rxColumn->setPropertyValue(PROPERTY_TYPE,Any(_pFieldDesc->GetType()));
    _rxColumn->setPropertyValue(PROPERTY_PRECISION,Any(_pFieldDesc->GetPrecision()));
    _rxColumn->setPropertyValue(PROPERTY_SCALE,Any(_pFieldDesc->GetScale()));
    _rxColumn->setPropertyValue(PROPERTY_ISNULLABLE, Any(_pFieldDesc->GetIsNullable()));
    _rxColumn->setPropertyValue(PROPERTY_ISAUTOINCREMENT, css::uno::Any(_pFieldDesc->IsAutoIncrement()));
    _rxColumn->setPropertyValue(PROPERTY_DESCRIPTION,Any(_pFieldDesc->GetDescription()));
    if ( _rxColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_ISCURRENCY) && _pFieldDesc->IsCurrency() )
        _rxColumn->setPropertyValue(PROPERTY_ISCURRENCY, css::uno::Any(_pFieldDesc->IsCurrency()));
    // set autoincrement value when available
    // and only set when the entry is not empty, that lets the value in the column untouched
    if ( _pFieldDesc->IsAutoIncrement() && !_pFieldDesc->GetAutoIncrementValue().isEmpty() && _rxColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_AUTOINCREMENTCREATION) )
        _rxColumn->setPropertyValue(PROPERTY_AUTOINCREMENTCREATION,Any(_pFieldDesc->GetAutoIncrementValue()));
}

OUString createDefaultName(const Reference< XDatabaseMetaData>& _xMetaData,const Reference<XNameAccess>& _xTables,const OUString& _sName)
{
    OSL_ENSURE(_xMetaData.is(),"No MetaData!");
    OUString sDefaultName = _sName;
    try
    {
        OUString sCatalog,sSchema,sCompsedName;
        if(_xMetaData->supportsCatalogsInTableDefinitions())
        {
            try
            {
                Reference< XConnection> xCon = _xMetaData->getConnection();
                if ( xCon.is() )
                    sCatalog = xCon->getCatalog();
                if ( sCatalog.isEmpty() )
                {
                    Reference<XResultSet> xRes = _xMetaData->getCatalogs();
                    Reference<XRow> xRow(xRes,UNO_QUERY);
                    while(xRes.is() && xRes->next())
                    {
                        sCatalog = xRow->getString(1);
                        if(!xRow->wasNull())
                            break;
                    }
                }
            }
            catch(const SQLException&)
            {
            }
        }
        if(_xMetaData->supportsSchemasInTableDefinitions())
        {
            sSchema = _xMetaData->getUserName();
        }
        sCompsedName = ::dbtools::composeTableName( _xMetaData, sCatalog, sSchema, _sName, false, ::dbtools::EComposeRule::InDataManipulation );
        sDefaultName = ::dbtools::createUniqueName(_xTables,sCompsedName);
    }
    catch(const SQLException&)
    {
    }
    return sDefaultName;
}

bool checkDataSourceAvailable(const OUString& _sDataSourceName,const Reference< css::uno::XComponentContext >& _xContext)
{
    Reference< XDatabaseContext > xDataBaseContext = DatabaseContext::create(_xContext);
    bool bRet = xDataBaseContext->hasByName(_sDataSourceName);
    if ( !bRet )
    { // try if this one is a URL
        try
        {
            bRet = xDataBaseContext->getByName(_sDataSourceName).hasValue();
        }
        catch(const Exception&)
        {
        }
    }
    return bRet;
}

sal_Int32 mapTextAlign(const SvxCellHorJustify& _eAlignment)
{
    sal_Int32 nAlignment = css::awt::TextAlign::LEFT;
    switch (_eAlignment)
    {
        case SvxCellHorJustify::Standard:
        case SvxCellHorJustify::Left:      nAlignment = css::awt::TextAlign::LEFT;    break;
        case SvxCellHorJustify::Center:    nAlignment = css::awt::TextAlign::CENTER;  break;
        case SvxCellHorJustify::Right:     nAlignment = css::awt::TextAlign::RIGHT;   break;
        default:
            SAL_WARN("dbaccess.ui""Invalid TextAlign!");
    }
    return nAlignment;
}

SvxCellHorJustify mapTextJustify(sal_Int32 _nAlignment)
{
    SvxCellHorJustify eJustify = SvxCellHorJustify::Left;
    switch (_nAlignment)
    {
        case css::awt::TextAlign::LEFT     : eJustify = SvxCellHorJustify::Left; break;
        case css::awt::TextAlign::CENTER   : eJustify = SvxCellHorJustify::Center; break;
        case css::awt::TextAlign::RIGHT    : eJustify = SvxCellHorJustify::Right; break;
        default:
            SAL_WARN("dbaccess.ui""Invalid TextAlign!");
    }
    return eJustify;
}

void callColumnFormatDialog(const Reference<XPropertySet>& xAffectedCol,
                            const Reference<XPropertySet>& xField,
                            SvNumberFormatter* _pFormatter,
                            weld::Widget* _pParent)
{
    if (!(xAffectedCol.is() && xField.is()))
        return;

    try
    {
        Reference< XPropertySetInfo >  xInfo = xAffectedCol->getPropertySetInfo();
        bool bHasFormat = xInfo->hasPropertyByName(PROPERTY_FORMATKEY);
        sal_Int32 nDataType = ::comphelper::getINT32(xField->getPropertyValue(PROPERTY_TYPE));

        SvxCellHorJustify eJustify(SvxCellHorJustify::Standard);
        Any aAlignment = xAffectedCol->getPropertyValue(PROPERTY_ALIGN);
        if (aAlignment.hasValue())
            eJustify = dbaui::mapTextJustify(::comphelper::getINT16(aAlignment));
        sal_Int32  nFormatKey = 0;
        if ( bHasFormat )
            nFormatKey = ::comphelper::getINT32(xAffectedCol->getPropertyValue(PROPERTY_FORMATKEY));

        if(callColumnFormatDialog(_pParent,_pFormatter,nDataType,nFormatKey,eJustify,bHasFormat))
        {
            xAffectedCol->setPropertyValue(PROPERTY_ALIGN, Any(static_cast<sal_Int16>(dbaui::mapTextAlign(eJustify))));
            if (bHasFormat)
                xAffectedCol->setPropertyValue(PROPERTY_FORMATKEY, Any(nFormatKey));

        }
    }
    catchconst Exception& )
    {
        DBG_UNHANDLED_EXCEPTION("dbaccess");
    }
}

static ItemInfoPackage& getItemInfoPackageColumnFormatDialog()
{
    class ItemInfoPackageColumnFormatDialog : public ItemInfoPackage
    {
        typedef std::array<ItemInfoStatic, SBA_ATTR_ALIGN_HOR_JUSTIFY - SBA_DEF_RANGEFORMAT + 1> ItemInfoArrayColumnFormatDialog;
        ItemInfoArrayColumnFormatDialog maItemInfos {{
            // m_nWhich, m_pItem, m_nSlotID, m_nItemInfoFlags
            { SBA_DEF_RANGEFORMAT, new SfxRangeItem(SBA_DEF_RANGEFORMAT, SBA_DEF_FMTVALUE, SBA_ATTR_ALIGN_HOR_JUSTIFY), 0, SFX_ITEMINFOFLAG_NONE },
            { SBA_DEF_FMTVALUE, new SfxUInt32Item(SBA_DEF_FMTVALUE), SID_ATTR_NUMBERFORMAT_VALUE, SFX_ITEMINFOFLAG_NONE },
            { SBA_ATTR_ALIGN_HOR_JUSTIFY, new SvxHorJustifyItem(SvxCellHorJustify::Standard, SBA_ATTR_ALIGN_HOR_JUSTIFY), SID_ATTR_ALIGN_HOR_JUSTIFY, SFX_ITEMINFOFLAG_NONE },
        }};

        virtual const ItemInfoStatic& getItemInfoStatic(size_t nIndex) const override { return maItemInfos[nIndex]; }

    public:
        virtual size_t size() const override { return maItemInfos.size(); }
        virtual const ItemInfo& getItemInfo(size_t nIndex, SfxItemPool& /*rPool*/) override { return maItemInfos[nIndex]; }
    };

    static std::unique_ptr<ItemInfoPackageColumnFormatDialog> g_aItemInfoPackageColumnFormatDialog;
    if (!g_aItemInfoPackageColumnFormatDialog)
        g_aItemInfoPackageColumnFormatDialog.reset(new ItemInfoPackageColumnFormatDialog);
    return *g_aItemInfoPackageColumnFormatDialog;
}

bool callColumnFormatDialog(weld::Widget* _pParent,
                                SvNumberFormatter* _pFormatter,
                                sal_Int32 _nDataType,
                                sal_Int32& _nFormatKey,
                                SvxCellHorJustify& _eJustify,
                                bool  _bHasFormat)
{
    bool bRet = false;

    // UNO->ItemSet
    static const auto aAttrMap = svl::Items<
        SBA_DEF_RANGEFORMAT, SBA_ATTR_ALIGN_HOR_JUSTIFY,
        SID_ATTR_NUMBERFORMAT_INFO, SID_ATTR_NUMBERFORMAT_INFO,
        SID_ATTR_NUMBERFORMAT_ONE_AREA, SID_ATTR_NUMBERFORMAT_ONE_AREA
    >;

    rtl::Reference<SfxItemPool> pPool(new SfxItemPool(u"GridBrowserProperties"_ustr));
    pPool->registerItemInfoPackage(getItemInfoPackageColumnFormatDialog());
    pPool->SetDefaultMetric( MapUnit::MapTwip );    // ripped, don't understand why

    std::optional<SfxItemSet> pFormatDescriptor(SfxItemSet(*pPool, aAttrMap));
    // fill it
    pFormatDescriptor->Put(SvxHorJustifyItem(_eJustify, SBA_ATTR_ALIGN_HOR_JUSTIFY));
    bool bText = false;
    if (_bHasFormat)
    {
        // if the col is bound to a text field we have to disallow all non-text formats
        if ((DataType::CHAR == _nDataType) || (DataType::VARCHAR == _nDataType) || (DataType::LONGVARCHAR == _nDataType) || (DataType::CLOB == _nDataType))
        {
            bText = true;
            pFormatDescriptor->Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA, true));
            if (!_pFormatter->IsTextFormat(_nFormatKey))
                // text fields can only have text formats
                _nFormatKey = _pFormatter->GetStandardFormat(SvNumFormatType::TEXT, Application::GetSettings().GetLanguageTag().getLanguageType());
        }

        pFormatDescriptor->Put(SfxUInt32Item(SBA_DEF_FMTVALUE, _nFormatKey));
    }

    if (!bText)
    {
        SvxNumberInfoItem aFormatter(_pFormatter, 1234.56789, SID_ATTR_NUMBERFORMAT_INFO);
        pFormatDescriptor->Put(aFormatter);
    }

    {   // want the dialog to be destroyed before our set
        SbaSbAttrDlg aDlg(_pParent, &*pFormatDescriptor, _pFormatter, _bHasFormat);
        if (RET_OK == aDlg.run())
        {
            // ItemSet->UNO
            // UNO-properties
            const SfxItemSet* pSet = aDlg.GetExampleSet();
            // (of course we could put the modified items directly into the column, but then the UNO-model
            // won't reflect these changes, and why do we have a model, then ?)

            // horizontal justify
            const SvxHorJustifyItem* pHorJustify = pSet->GetItem<SvxHorJustifyItem>(SBA_ATTR_ALIGN_HOR_JUSTIFY);

            _eJustify = pHorJustify->GetValue();

            // format key
            if (_bHasFormat)
            {
                const SfxUInt32Item* pFormat = pSet->GetItem<SfxUInt32Item>(SBA_DEF_FMTVALUE);
                _nFormatKey = static_cast<sal_Int32>(pFormat->GetValue());
            }
            bRet = true;
        }
            // deleted formats
        const SfxItemSet* pResult = aDlg.GetOutputItemSet();
        if (pResult)
        {
            const SfxPoolItem* pItem = pResult->GetItem( SID_ATTR_NUMBERFORMAT_INFO );
            const SvxNumberInfoItem* pInfoItem = static_cast<const SvxNumberInfoItem*>(pItem);
            if (pInfoItem)
            {
                for (sal_uInt32 key : pInfoItem->GetDelFormats())
                    _pFormatter->DeleteEntry(key);
            }
        }
    }

    pFormatDescriptor.reset();
    pPool.clear();

    return bRet;
}

std::shared_ptr<const SfxFilter> getStandardDatabaseFilter()
{
    std::shared_ptr<const SfxFilter> pFilter = SfxFilter::GetFilterByName(u"StarOffice XML (Base)"_ustr);
    OSL_ENSURE(pFilter,"Filter: StarOffice XML (Base) could not be found!");
    return pFilter;
}

bool appendToFilter(const Reference<XConnection>& _xConnection,
                    const OUString& _sName,
                    const Reference< XComponentContext >& _rxContext,
                    weld::Window* pParent)
{
    bool bRet = false;
    Reference< XChild> xChild(_xConnection,UNO_QUERY);
    if(xChild.is())
    {
        Reference< XPropertySet> xProp(xChild->getParent(),UNO_QUERY);
        if(xProp.is())
        {
            Sequence< OUString > aFilter;
            xProp->getPropertyValue(PROPERTY_TABLEFILTER) >>= aFilter;
            // first check if we have something like SCHEMA.%
            bool bHasToInsert = true;
            for (const OUString& rItem : aFilter)
            {
                if(rItem.indexOf('%') != -1)
                {
                    sal_Int32 nLen = rItem.lastIndexOf('.');
                    if(nLen != -1 && !rItem.compareTo(_sName,nLen))
                        bHasToInsert = false;
                    else if(rItem.getLength() == 1)
                        bHasToInsert = false;
                }
            }

            bRet = true;
            if(bHasToInsert)
            {
                if(! ::dbaui::checkDataSourceAvailable(::comphelper::getString(xProp->getPropertyValue(PROPERTY_NAME)),_rxContext))
                {
                    OUString aMessage(DBA_RES(STR_TABLEDESIGN_DATASOURCE_DELETED));
                    OSQLWarningBox aWarning(pParent, aMessage);
                    aWarning.run();
                    bRet = false;
                }
                else
                {
                    aFilter.realloc(aFilter.getLength()+1);
                    aFilter.getArray()[aFilter.getLength()-1] = _sName;
                    xProp->setPropertyValue(PROPERTY_TABLEFILTER,Any(aFilter));
                }
            }
        }
    }
    return bRet;
}

void notifySystemWindow(vcl::Window const * _pWindow, vcl::Window* _pToRegister, const ::comphelper::mem_fun1_t<TaskPaneList,vcl::Window*>& _rMemFunc)
{
    OSL_ENSURE(_pWindow,"Window can not be null!");
    SystemWindow* pSystemWindow = _pWindow ? _pWindow->GetSystemWindow() : nullptr;
    if ( pSystemWindow )
    {
        _rMemFunc( pSystemWindow->GetTaskPaneList(), _pToRegister );
    }
}

void adjustBrowseBoxColumnWidth( ::svt::EditBrowseBox* _pBox, sal_uInt16 _nColId )
{
    sal_Int32 nColSize = -1;
    ::tools::Long nDefaultWidth = _pBox->GetDefaultColumnWidth( _pBox->GetColumnTitle( _nColId ) );
    if ( nDefaultWidth != _pBox->GetColumnWidth( _nColId ) )
    {
        Size aSizeMM = _pBox->PixelToLogic( Size( _pBox->GetColumnWidth( _nColId ), 0 ), MapMode( MapUnit::MapMM ) );
        nColSize = aSizeMM.Width() * 10;
    }

    Size aDefaultMM = _pBox->PixelToLogic( Size( nDefaultWidth, 0 ), MapMode( MapUnit::MapMM ) );

    DlgSize aColumnSizeDlg(_pBox->GetFrameWeld(), nColSize, false, aDefaultMM.Width() * 10);
    if (aColumnSizeDlg.run() != RET_OK)
        return;

    sal_Int32 nValue = aColumnSizeDlg.GetValue();
    if ( -1 == nValue )
    {   // default width
        nValue = _pBox->GetDefaultColumnWidth( _pBox->GetColumnTitle( _nColId ) );
    }
    else
    {
        Size aSizeMM( nValue / 10, 0 );
        nValue = _pBox->LogicToPixel( aSizeMM, MapMode( MapUnit::MapMM ) ).Width();
    }
    _pBox->SetColumnWidth( _nColId, nValue );
}

// check if SQL92 name checking is enabled
bool isSQL92CheckEnabled(const Reference<XConnection>& _xConnection)
{
    return ::dbtools::getBooleanDataSourceSetting( _xConnection, PROPERTY_ENABLESQL92CHECK );
}

bool isAppendTableAliasEnabled(const Reference<XConnection>& _xConnection)
{
    return ::dbtools::getBooleanDataSourceSetting( _xConnection, INFO_APPEND_TABLE_ALIAS );
}

bool generateAsBeforeTableAlias(const Reference<XConnection>& _xConnection)
{
    return ::dbtools::getBooleanDataSourceSetting( _xConnection, INFO_AS_BEFORE_CORRELATION_NAME );
}

void fillAutoIncrementValue(const Reference<XPropertySet>& _xDatasource,
                            bool& _rAutoIncrementValueEnabled,
                            OUString& _rsAutoIncrementValue)
{
    if ( !_xDatasource.is() )
        return;

    OSL_ENSURE(_xDatasource->getPropertySetInfo()->hasPropertyByName(PROPERTY_INFO),"NO datasource supplied!");
    Sequence<PropertyValue> aInfo;
    _xDatasource->getPropertyValue(PROPERTY_INFO) >>= aInfo;

    // search the right propertyvalue
    const PropertyValue* pValue =std::find_if(std::cbegin(aInfo), std::cend(aInfo),
                                        [](const PropertyValue& lhs)
                                        {return lhs.Name == PROPERTY_AUTOINCREMENTCREATION;} );

    if ( pValue != std::cend(aInfo) )
        pValue->Value >>= _rsAutoIncrementValue;
    pValue =std::find_if(std::cbegin(aInfo), std::cend(aInfo),
                         [](const PropertyValue& lhs)
                         {return lhs.Name == "IsAutoRetrievingEnabled";} );

    if ( pValue != std::cend(aInfo) )
        pValue->Value >>= _rAutoIncrementValueEnabled;
}

void fillAutoIncrementValue(const Reference<XConnection>& _xConnection,
                            bool& _rAutoIncrementValueEnabled,
                            OUString& _rsAutoIncrementValue)
{
    Reference< XChild> xChild(_xConnection,UNO_QUERY);
    if(xChild.is())
    {
        Reference< XPropertySet> xProp(xChild->getParent(),UNO_QUERY);
        fillAutoIncrementValue(xProp,_rAutoIncrementValueEnabled,_rsAutoIncrementValue);
    }
}

OUString getStrippedDatabaseName(const Reference<XPropertySet>& _xDataSource,OUString& _rsDatabaseName)
{
    if ( _rsDatabaseName.isEmpty() && _xDataSource.is() )
    {
        try
        {
            _xDataSource->getPropertyValue(PROPERTY_NAME) >>= _rsDatabaseName;
        }
        catch(const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION("dbaccess");
        }
    }
    OUString sName = _rsDatabaseName;
    INetURLObject aURL(sName);
    if ( aURL.GetProtocol() != INetProtocol::NotValid )
        sName = aURL.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DecodeMechanism::Unambiguous);
    return sName;
}

void setEvalDateFormatForFormatter(Reference< css::util::XNumberFormatter > const & _rxFormatter)
{
    OSL_ENSURE( _rxFormatter.is(),"setEvalDateFormatForFormatter: Formatter is NULL!");
    if ( !_rxFormatter.is() )
        return;

    Reference< css::util::XNumberFormatsSupplier >  xSupplier = _rxFormatter->getNumberFormatsSupplier();

    auto pSupplierImpl = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(xSupplier);
    OSL_ENSURE(pSupplierImpl,"No Supplier!");

    if ( pSupplierImpl )
    {
        SvNumberFormatter* pFormatter = pSupplierImpl->GetNumberFormatter();
        pFormatter->SetEvalDateFormat(NF_EVALDATEFORMAT_FORMAT);
    }
}

static bool TypeIsGreater(const TOTypeInfoSP& lhs, const TOTypeInfoSP& rhs)
{
    assert(lhs);
    if (!rhs)
        return true;
    if (lhs->nNumPrecRadix == rhs->nNumPrecRadix)
        return lhs->nPrecision > rhs->nPrecision;
    if (lhs->nPrecision == rhs->nPrecision)
        return lhs->nNumPrecRadix > rhs->nNumPrecRadix;
    if ((lhs->nNumPrecRadix > rhs->nNumPrecRadix) == (lhs->nPrecision > rhs->nPrecision))
        return lhs->nPrecision > rhs->nPrecision;
    return std::pow(lhs->nNumPrecRadix, lhs->nPrecision)
           > std::pow(rhs->nNumPrecRadix, rhs->nPrecision);
}

TOTypeInfoSP queryPrimaryKeyType(const OTypeInfoMap& _rTypeInfo)
{
    TOTypeInfoSP pTypeInfo, pFallback;
    // first we search for a largest type which supports autoIncrement
    for (auto const& elem : _rTypeInfo)
    {
        if (elem.second->bAutoIncrement && TypeIsGreater(elem.second, pTypeInfo))
            pTypeInfo = elem.second;
        if (pTypeInfo)
            continue;
        if (elem.second->nType == DataType::INTEGER)
            pFallback = elem.second; // default alternative
        else if (!pFallback && elem.second->nType == DataType::DOUBLE)
            pFallback = elem.second; // alternative
        else if (!pFallback && elem.second->nType == DataType::REAL)
            pFallback = elem.second; // alternative
    }
    if ( !pTypeInfo ) // just a fallback
        pTypeInfo = pFallback ? std::move(pFallback) : queryTypeInfoByType(DataType::VARCHAR, _rTypeInfo);

    OSL_ENSURE(pTypeInfo,"checkColumns: can't find a type which is usable as a key!");
    return pTypeInfo;
}

TOTypeInfoSP queryTypeInfoByType(sal_Int32 _nDataType,const OTypeInfoMap& _rTypeInfo)
{
    OTypeInfoMap::const_iterator aIter = _rTypeInfo.find(_nDataType);
    if(aIter != _rTypeInfo.end())
        return aIter->second;
    // fall back if the type is unknown
    TOTypeInfoSP pTypeInfo;
    switch(_nDataType)
    {
        case DataType::TINYINT:
            if( (pTypeInfo = queryTypeInfoByType(DataType::SMALLINT,_rTypeInfo) ) )
                break;
            [[fallthrough]];
        case DataType::SMALLINT:
            if( (pTypeInfo = queryTypeInfoByType(DataType::INTEGER,_rTypeInfo) ) )
                break;
            [[fallthrough]];
        case DataType::INTEGER:
            if( (pTypeInfo = queryTypeInfoByType(DataType::FLOAT,_rTypeInfo) ) )
                break;
            [[fallthrough]];
        case DataType::FLOAT:
            if( (pTypeInfo = queryTypeInfoByType(DataType::REAL,_rTypeInfo) ) )
                break;
            [[fallthrough]];
        case DataType::DATE:
        case DataType::TIME:
            if( DataType::DATE == _nDataType || DataType::TIME == _nDataType )
            {
                if( (pTypeInfo = queryTypeInfoByType(DataType::TIMESTAMP,_rTypeInfo) ) )
                    break;
            }
            [[fallthrough]];
        case DataType::TIMESTAMP:
        case DataType::REAL:
        case DataType::BIGINT:
            if (  (pTypeInfo = queryTypeInfoByType(DataType::DOUBLE,_rTypeInfo) ) )
                break;
            [[fallthrough]];
        case DataType::DOUBLE:
            if (  (pTypeInfo = queryTypeInfoByType(DataType::NUMERIC,_rTypeInfo) ) )
                break;
            [[fallthrough]];
        case DataType::NUMERIC:
             pTypeInfo = queryTypeInfoByType(DataType::DECIMAL,_rTypeInfo);
            break;
        case DataType::DECIMAL:
            if (  (pTypeInfo = queryTypeInfoByType(DataType::NUMERIC,_rTypeInfo) ) )
                break;
            if (  (pTypeInfo = queryTypeInfoByType(DataType::DOUBLE,_rTypeInfo) ) )
                break;
            break;
        case DataType::VARCHAR:
            if (  (pTypeInfo = queryTypeInfoByType(DataType::LONGVARCHAR,_rTypeInfo) ) )
                break;
            break;
        case DataType::LONGVARCHAR:
            if (  (pTypeInfo = queryTypeInfoByType(DataType::CLOB,_rTypeInfo) ) )
                break;
            break;
        default:
            ;
    }
    if ( !pTypeInfo )
    {
        bool bForce = true;
        pTypeInfo = ::dbaui::getTypeInfoFromType(_rTypeInfo,DataType::VARCHAR,OUString(),u"x"_ustr,50,0,false,bForce);
    }
    OSL_ENSURE(pTypeInfo,"Wrong DataType supplied!");
    return pTypeInfo;
}

sal_Int32 askForUserAction(weld::Window* pParent, TranslateId pTitle, TranslateId pText, bool _bAll, std::u16string_view _sName)
{
    SolarMutexGuard aGuard;
    OUString aMsg = DBA_RES(pText);
    aMsg = aMsg.replaceFirst("%1", _sName);
    OSQLMessageBox aAsk(pParent, DBA_RES(pTitle), aMsg, MessBoxStyle::YesNo | MessBoxStyle::DefaultYes, MessageType::Query);
    if ( _bAll )
    {
        aAsk.add_button(DBA_RES(STR_BUTTON_TEXT_ALL), RET_ALL, HID_CONFIRM_DROP_BUTTON_ALL);
    }
    return aAsk.run();
}

namespace
{
    OUString lcl_createSDBCLevelStatement( const OUString& _rStatement, const Reference< XConnection >& _rxConnection )
    {
        OUString sSDBCLevelStatement( _rStatement );
        try
        {
            Reference< XMultiServiceFactory > xAnalyzerFactory( _rxConnection, UNO_QUERY_THROW );
            Reference< XSingleSelectQueryAnalyzer > xAnalyzer( xAnalyzerFactory->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY_THROW );
            xAnalyzer->setQuery( _rStatement );
            sSDBCLevelStatement = xAnalyzer->getQueryWithSubstitution();
        }
        catchconst Exception& )
        {
            DBG_UNHANDLED_EXCEPTION("dbaccess");
        }
        return sSDBCLevelStatement;
    }
}

Reference< XPropertySet > createView( const OUString& _rName, const Reference< XConnection >& _rxConnection,
                                    const OUString& _rCommand )
{
    Reference<XViewsSupplier> xSup(_rxConnection,UNO_QUERY);
    Reference< XNameAccess > xViews;
    if(xSup.is())
        xViews = xSup->getViews();
    Reference<XDataDescriptorFactory> xFact(xViews,UNO_QUERY);
    OSL_ENSURE(xFact.is(),"No XDataDescriptorFactory available!");
    if(!xFact.is())
        return nullptr;

    Reference<XPropertySet> xView = xFact->createDataDescriptor();
    if ( !xView.is() )
        return nullptr;

    OUString sCatalog,sSchema,sTable;
    ::dbtools::qualifiedNameComponents(_rxConnection->getMetaData(),
                                        _rName,
                                        sCatalog,
                                        sSchema,
                                        sTable,
                                        ::dbtools::EComposeRule::InDataManipulation);

    xView->setPropertyValue(PROPERTY_CATALOGNAME,Any(sCatalog));
    xView->setPropertyValue(PROPERTY_SCHEMANAME,Any(sSchema));
    xView->setPropertyValue(PROPERTY_NAME,Any(sTable));

    xView->setPropertyValue( PROPERTY_COMMAND, Any( _rCommand ) );

    Reference<XAppend> xAppend(xViews,UNO_QUERY);
    if(xAppend.is())
        xAppend->appendByDescriptor(xView);

    xView = nullptr;
    // we need to reget the view because after appending it, it is no longer valid
    // but this time it isn't a view object it is a table object with type "VIEW"
    Reference<XTablesSupplier> xTabSup(_rxConnection,UNO_QUERY);
    Reference< XNameAccess > xTables;
    if ( xTabSup.is() )
    {
        xTables = xTabSup->getTables();
        if ( xTables.is() && xTables->hasByName( _rName ) )
            xTables->getByName( _rName ) >>= xView;
    }

    return xView;
}

Reference<XPropertySet> createView( const OUString& _rName, const Reference< XConnection >& _rxConnection
                                   ,const Reference<XPropertySet>& _rxSourceObject)
{
    OUString sCommand;
    Reference< XPropertySetInfo > xPSI( _rxSourceObject->getPropertySetInfo(), UNO_SET_THROW );
    if ( xPSI->hasPropertyByName( PROPERTY_COMMAND ) )
    {
        _rxSourceObject->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand;

        bool bEscapeProcessing( false );
        OSL_VERIFY( _rxSourceObject->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bEscapeProcessing );
        if ( bEscapeProcessing )
            sCommand = lcl_createSDBCLevelStatement( sCommand, _rxConnection );
    }
    else
    {
        sCommand =  "SELECT * FROM " + composeTableNameForSelect( _rxConnection, _rxSourceObject );
    }
    return createView( _rName, _rxConnection, sCommand );
}

bool insertHierarchyElement(weld::Window* pParent, const Reference< XComponentContext >&&nbsp;_rxContext,
                           const Reference<XHierarchicalNameContainer>& _xNames,
                           const OUString& _sParentFolder,
                           bool _bForm,
                           bool _bCollection,
                           const Reference<XContent>& _xContent,
                           bool _bMove)
{
    OSL_ENSURE( _xNames.is(), "insertHierarchyElement: illegal name container!" );
    if ( !_xNames.is() )
        return false;

    Reference<XNameAccess> xNameAccess( _xNames, UNO_QUERY );
    if ( _xNames->hasByHierarchicalName(_sParentFolder) )
    {
        Reference<XChild> xChild(_xNames->getByHierarchicalName(_sParentFolder),UNO_QUERY);
        xNameAccess.set(xChild,UNO_QUERY);
        if ( !xNameAccess.is() && xChild.is() )
            xNameAccess.set(xChild->getParent(),UNO_QUERY);
    }

    OSL_ENSURE( xNameAccess.is(), "insertHierarchyElement: could not find the proper name container!" );
    if ( !xNameAccess.is() )
        return false;

    OUString sNewName;
    Reference<XPropertySet> xProp(_xContent,UNO_QUERY);
    if ( xProp.is() )
        xProp->getPropertyValue(PROPERTY_NAME) >>= sNewName;

    if ( !_bMove || sNewName.isEmpty() )
    {
        if ( sNewName.isEmpty() || xNameAccess->hasByName(sNewName) )
        {
            OUString sLabel, sTargetName;
            if ( !sNewName.isEmpty() )
                sTargetName = sNewName;
            else
                sTargetName = DBA_RES( _bCollection ? STR_NEW_FOLDER : ((_bForm) ? RID_STR_FORM : RID_STR_REPORT));
            sLabel = DBA_RES( _bCollection ? STR_FOLDER_LABEL  : ((_bForm) ? STR_FRM_LABEL : STR_RPT_LABEL));
            sTargetName = ::dbtools::createUniqueName(xNameAccess,sTargetName);

            // here we have everything needed to create a new query object ...
            HierarchicalNameCheck aNameChecker( _xNames, _sParentFolder );
            // ... ehm, except a new name
            OSaveAsDlg aAskForName(pParent,
                                   _rxContext,
                                   sTargetName,
                                   sLabel,
                                   aNameChecker,
                                   SADFlags::AdditionalDescription | SADFlags::TitlePasteAs);
            if ( RET_OK != aAskForName.run() )
                // cancelled by the user
                return false;

            sNewName = aAskForName.getName();
        }
    }
    else if ( xNameAccess->hasByName(sNewName) )
    {
        OUString sError(DBA_RES(STR_NAME_ALREADY_EXISTS));
        sError = sError.replaceFirst("#",sNewName);
        throw SQLException(sError,nullptr,u"S1000"_ustr,0,Any());
    }

    try
    {
        Reference<XMultiServiceFactory> xORB( xNameAccess, UNO_QUERY_THROW );
        uno::Sequence<uno::Any> aArguments(comphelper::InitAnyPropertySequence(
        {
            {"Name", uno::Any(sNewName)}, // set as folder
            {"Parent", uno::Any(xNameAccess)},
            {PROPERTY_EMBEDDEDOBJECT, uno::Any(_xContent)},
        }));
        OUString sServiceName(_bCollection ? (_bForm ? SERVICE_NAME_FORM_COLLECTION : SERVICE_NAME_REPORT_COLLECTION) : SERVICE_SDB_DOCUMENTDEFINITION);

        Reference<XContent > xNew( xORB->createInstanceWithArguments( sServiceName, aArguments ), UNO_QUERY_THROW );
        Reference< XNameContainer > xNameContainer( xNameAccess, UNO_QUERY_THROW );
        xNameContainer->insertByName( sNewName, Any( xNew ) );
    }
    catchconst IllegalArgumentException& e )
    {
        ::dbtools::throwGenericSQLException( e.Message, e.Context );
    }
    catchconst Exception& )
    {
        DBG_UNHANDLED_EXCEPTION("dbaccess");
        return false;
    }

    return true;
}

Reference< XNumberFormatter > getNumberFormatter(const Reference< XConnection >& _rxConnection, const Reference< css::uno::XComponentContext >& _rxContext )
{
    // create a formatter working with the connections format supplier
    Reference< XNumberFormatter > xFormatter;

    try
    {
        Reference< css::util::XNumberFormatsSupplier >  xSupplier(::dbtools::getNumberFormats(_rxConnection, true, _rxContext));

        if ( xSupplier.is() )
        {
            // create a new formatter
            xFormatter.set(util::NumberFormatter::create( _rxContext ), UNO_QUERY_THROW);
            xFormatter->attachNumberFormatsSupplier(xSupplier);
        }
    }
    catch(const Exception&)
    {
        DBG_UNHANDLED_EXCEPTION("dbaccess");
    }
    return xFormatter;
}

// dbaui

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=95 H=97 G=95

¤ Dauer der Verarbeitung: 0.15 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.