diff options
Diffstat (limited to 'connectivity/source/drivers/writer')
-rw-r--r-- | connectivity/source/drivers/writer/WCatalog.cxx | 60 | ||||
-rw-r--r-- | connectivity/source/drivers/writer/WConnection.cxx | 248 | ||||
-rw-r--r-- | connectivity/source/drivers/writer/WDatabaseMetaData.cxx | 112 | ||||
-rw-r--r-- | connectivity/source/drivers/writer/WDriver.cxx | 80 | ||||
-rw-r--r-- | connectivity/source/drivers/writer/WTable.cxx | 253 | ||||
-rw-r--r-- | connectivity/source/drivers/writer/WTables.cxx | 45 | ||||
-rw-r--r-- | connectivity/source/drivers/writer/Wservices.cxx | 90 | ||||
-rw-r--r-- | connectivity/source/drivers/writer/writer.component | 17 |
8 files changed, 905 insertions, 0 deletions
diff --git a/connectivity/source/drivers/writer/WCatalog.cxx b/connectivity/source/drivers/writer/WCatalog.cxx new file mode 100644 index 000000000..8671af7bd --- /dev/null +++ b/connectivity/source/drivers/writer/WCatalog.cxx @@ -0,0 +1,60 @@ +/* -*- 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 <writer/WCatalog.hxx> +#include <writer/WTables.hxx> + +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> + +#include <connectivity/sdbcx/VCollection.hxx> + +#include <writer/WConnection.hxx> + +using namespace ::com::sun::star; + +namespace connectivity::writer +{ +OWriterCatalog::OWriterCatalog(OWriterConnection* pConnection) + : file::OFileCatalog(pConnection) +{ +} + +void OWriterCatalog::refreshTables() +{ + ::std::vector<OUString> aVector; + uno::Sequence<OUString> aTypes; + OWriterConnection::ODocHolder aDocHolder(static_cast<OWriterConnection*>(m_pConnection)); + uno::Reference<sdbc::XResultSet> xResult = m_xMetaData->getTables(uno::Any(), "%", "%", aTypes); + + if (xResult.is()) + { + uno::Reference<sdbc::XRow> xRow(xResult, uno::UNO_QUERY); + while (xResult->next()) + aVector.push_back(xRow->getString(3)); + } + if (m_pTables) + m_pTables->reFill(aVector); + else + m_pTables = std::make_unique<OWriterTables>(m_xMetaData, *this, m_aMutex, aVector); +} + +} // namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/writer/WConnection.cxx b/connectivity/source/drivers/writer/WConnection.cxx new file mode 100644 index 000000000..c4cc699e4 --- /dev/null +++ b/connectivity/source/drivers/writer/WConnection.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 <writer/WConnection.hxx> +#include <writer/WDatabaseMetaData.hxx> +#include <writer/WCatalog.hxx> +#include <writer/WDriver.hxx> +#include <resource/sharedresources.hxx> +#include <strings.hrc> +#include <com/sun/star/frame/Desktop.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <tools/urlobj.hxx> +#include <sal/log.hxx> +#include <component/CPreparedStatement.hxx> +#include <component/CStatement.hxx> +#include <unotools/pathoptions.hxx> +#include <connectivity/dbexception.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <tools/diagnose_ex.h> + +using namespace ::com::sun::star; + +using OConnection_BASE = connectivity::file::OConnection; + +namespace connectivity::writer +{ +OWriterConnection::OWriterConnection(ODriver* _pDriver) + : OConnection(_pDriver) + , m_nDocCount(0) +{ +} + +OWriterConnection::~OWriterConnection() = default; + +void OWriterConnection::construct(const OUString& rURL, + const uno::Sequence<beans::PropertyValue>& rInfo) +{ + // open file + + sal_Int32 nLen = rURL.indexOf(':'); + nLen = rURL.indexOf(':', nLen + 1); + OUString aDSN(rURL.copy(nLen + 1)); + + m_aFileName = aDSN; + INetURLObject aURL; + aURL.SetSmartProtocol(INetProtocol::File); + { + SvtPathOptions aPathOptions; + m_aFileName = aPathOptions.SubstituteVariable(m_aFileName); + } + aURL.SetSmartURL(m_aFileName); + if (aURL.GetProtocol() == INetProtocol::NotValid) + { + // don't pass invalid URL to loadComponentFromURL + throw sdbc::SQLException(); + } + m_aFileName = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE); + + m_sPassword.clear(); + const char pPwd[] = "password"; + + const beans::PropertyValue* pIter = rInfo.getConstArray(); + const beans::PropertyValue* pEnd = pIter + rInfo.getLength(); + for (; pIter != pEnd; ++pIter) + { + if (pIter->Name == pPwd) + { + pIter->Value >>= m_sPassword; + break; + } + } // for(;pIter != pEnd;++pIter) + ODocHolder aDocHolder(this); // just to test that the doc can be loaded + acquireDoc(); +} + +uno::Reference<text::XTextDocument> const& OWriterConnection::acquireDoc() +{ + if (m_xDoc.is()) + { + osl_atomic_increment(&m_nDocCount); + return m_xDoc; + } + // open read-only as long as updating isn't implemented + uno::Sequence<beans::PropertyValue> aArgs(2); + aArgs[0].Name = "Hidden"; + aArgs[0].Value <<= true; + aArgs[1].Name = "ReadOnly"; + aArgs[1].Value <<= true; + + if (!m_sPassword.isEmpty()) + { + const sal_Int32 nPos = aArgs.getLength(); + aArgs.realloc(nPos + 1); + aArgs[nPos].Name = "Password"; + aArgs[nPos].Value <<= m_sPassword; + } + + uno::Reference<frame::XDesktop2> xDesktop + = frame::Desktop::create(getDriver()->getComponentContext()); + uno::Reference<lang::XComponent> xComponent; + uno::Any aLoaderException; + try + { + xComponent = xDesktop->loadComponentFromURL(m_aFileName, "_blank", 0, aArgs); + } + catch (const uno::Exception&) + { + aLoaderException = ::cppu::getCaughtException(); + } + + m_xDoc.set(xComponent, uno::UNO_QUERY); + + // if the URL is not a text document, throw the exception here + // instead of at the first access to it + if (!m_xDoc.is()) + { + if (aLoaderException.hasValue()) + { + uno::Exception aLoaderError; + OSL_VERIFY(aLoaderException >>= aLoaderError); + + SAL_WARN("connectivity.writer", + "empty m_xDoc, " << exceptionToString(aLoaderException)); + } + + const OUString sError(m_aResources.getResourceStringWithSubstitution( + STR_COULD_NOT_LOAD_FILE, "$filename$", m_aFileName)); + ::dbtools::throwGenericSQLException(sError, *this); + } + osl_atomic_increment(&m_nDocCount); + m_xCloseVetoButTerminateListener.set(new CloseVetoButTerminateListener); + m_xCloseVetoButTerminateListener->start(m_xDoc, xDesktop); + return m_xDoc; +} + +void OWriterConnection::releaseDoc() +{ + if (osl_atomic_decrement(&m_nDocCount) == 0) + { + if (m_xCloseVetoButTerminateListener.is()) + { + m_xCloseVetoButTerminateListener->stop(); // dispose m_xDoc + m_xCloseVetoButTerminateListener.clear(); + } + m_xDoc.clear(); + } +} + +void OWriterConnection::disposing() +{ + ::osl::MutexGuard aGuard(m_aMutex); + + m_nDocCount = 0; + if (m_xCloseVetoButTerminateListener.is()) + { + m_xCloseVetoButTerminateListener->stop(); // dispose m_xDoc + m_xCloseVetoButTerminateListener.clear(); + } + m_xDoc.clear(); + + OConnection::disposing(); +} + +// XServiceInfo + +IMPLEMENT_SERVICE_INFO(OWriterConnection, "com.sun.star.sdbc.drivers.writer.Connection", + "com.sun.star.sdbc.Connection") + +uno::Reference<sdbc::XDatabaseMetaData> SAL_CALL OWriterConnection::getMetaData() +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + uno::Reference<sdbc::XDatabaseMetaData> xMetaData = m_xMetaData; + if (!xMetaData.is()) + { + xMetaData = new OWriterDatabaseMetaData(this); + m_xMetaData = xMetaData; + } + + return xMetaData; +} + +css::uno::Reference<css::sdbcx::XTablesSupplier> OWriterConnection::createCatalog() +{ + ::osl::MutexGuard aGuard(m_aMutex); + uno::Reference<css::sdbcx::XTablesSupplier> xTab = m_xCatalog; + if (!xTab.is()) + { + auto pCat = new OWriterCatalog(this); + xTab = pCat; + m_xCatalog = xTab; + } + return xTab; +} + +uno::Reference<sdbc::XStatement> SAL_CALL OWriterConnection::createStatement() +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + uno::Reference<sdbc::XStatement> xReturn = new component::OComponentStatement(this); + m_aStatements.push_back(uno::WeakReferenceHelper(xReturn)); + return xReturn; +} + +uno::Reference<sdbc::XPreparedStatement> + SAL_CALL OWriterConnection::prepareStatement(const OUString& sql) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + auto pStmt = new component::OComponentPreparedStatement(this); + uno::Reference<sdbc::XPreparedStatement> xHoldAlive = pStmt; + pStmt->construct(sql); + m_aStatements.push_back(uno::WeakReferenceHelper(*pStmt)); + return pStmt; +} + +uno::Reference<sdbc::XPreparedStatement> + SAL_CALL OWriterConnection::prepareCall(const OUString& /*sql*/) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + ::dbtools::throwFeatureNotImplementedSQLException("XConnection::prepareCall", *this); + return nullptr; +} + +} // namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/writer/WDatabaseMetaData.cxx b/connectivity/source/drivers/writer/WDatabaseMetaData.cxx new file mode 100644 index 000000000..2e55a46d2 --- /dev/null +++ b/connectivity/source/drivers/writer/WDatabaseMetaData.cxx @@ -0,0 +1,112 @@ +/* -*- 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 <writer/WDatabaseMetaData.hxx> +#include <writer/WConnection.hxx> +#include <com/sun/star/sdbc/SQLException.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/XTextTablesSupplier.hpp> + +using namespace ::com::sun::star; + +namespace connectivity::writer +{ +OWriterDatabaseMetaData::OWriterDatabaseMetaData(file::OConnection* pConnection) + : OComponentDatabaseMetaData(pConnection) +{ +} + +OWriterDatabaseMetaData::~OWriterDatabaseMetaData() = default; + +OUString SAL_CALL OWriterDatabaseMetaData::getURL() +{ + ::osl::MutexGuard aGuard(m_aMutex); + + return "sdbc:writer:" + m_pConnection->getURL(); +} + +uno::Reference<sdbc::XResultSet> SAL_CALL OWriterDatabaseMetaData::getTables( + const uno::Any& /*catalog*/, const OUString& /*schemaPattern*/, + const OUString& tableNamePattern, const uno::Sequence<OUString>& types) +{ + ::osl::MutexGuard aGuard(m_aMutex); + + auto pResult = new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTables); + uno::Reference<sdbc::XResultSet> xRef = pResult; + + // check if ORowSetValue type is given + // when no types are given then we have to return all tables e.g. TABLE + + OUString aTable("TABLE"); + + bool bTableFound = true; + sal_Int32 nLength = types.getLength(); + if (nLength) + { + bTableFound = false; + + const OUString* pIter = types.getConstArray(); + const OUString* pEnd = pIter + nLength; + for (; pIter != pEnd; ++pIter) + { + if (*pIter == aTable) + { + bTableFound = true; + break; + } + } + } + if (!bTableFound) + return xRef; + + // get the table names from the document + + OWriterConnection::ODocHolder aDocHolder(static_cast<OWriterConnection*>(m_pConnection)); + uno::Reference<text::XTextTablesSupplier> xDoc(aDocHolder.getDoc(), uno::UNO_QUERY); + if (!xDoc.is()) + throw sdbc::SQLException(); + uno::Reference<container::XNameAccess> xTables = xDoc->getTextTables(); + if (!xTables.is()) + throw sdbc::SQLException(); + uno::Sequence<OUString> aTableNames = xTables->getElementNames(); + + ODatabaseMetaDataResultSet::ORows aRows; + sal_Int32 nTableCount = aTableNames.getLength(); + for (sal_Int32 nTable = 0; nTable < nTableCount; nTable++) + { + OUString aName = aTableNames[nTable]; + if (match(tableNamePattern, aName, '\0')) + { + ODatabaseMetaDataResultSet::ORow aRow{ nullptr, nullptr, nullptr }; + aRow.reserve(6); + aRow.push_back(new ORowSetValueDecorator(aName)); + aRow.push_back(new ORowSetValueDecorator(aTable)); + aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue()); + aRows.push_back(aRow); + } + } + + pResult->setRows(aRows); + + return xRef; +} + +} // namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/writer/WDriver.cxx b/connectivity/source/drivers/writer/WDriver.cxx new file mode 100644 index 000000000..63dc1f3f4 --- /dev/null +++ b/connectivity/source/drivers/writer/WDriver.cxx @@ -0,0 +1,80 @@ +/* -*- 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 <writer/WDriver.hxx> +#include <writer/WConnection.hxx> +#include <com/sun/star/lang/DisposedException.hpp> +#include <connectivity/dbexception.hxx> +#include <resource/sharedresources.hxx> +#include <strings.hrc> +#include <comphelper/processfactory.hxx> + +using namespace connectivity::file; +using namespace ::com::sun::star; + +namespace connectivity::writer +{ +OUString ODriver::getImplementationName_Static() { return "com.sun.star.comp.sdbc.writer.ODriver"; } + +OUString SAL_CALL ODriver::getImplementationName() { return getImplementationName_Static(); } + +uno::Reference<css::uno::XInterface> +ODriver_CreateInstance(const uno::Reference<lang::XMultiServiceFactory>& _rxFactory) +{ + return *(new ODriver(comphelper::getComponentContext(_rxFactory))); +} + +uno::Reference<sdbc::XConnection> + SAL_CALL ODriver::connect(const OUString& url, const uno::Sequence<beans::PropertyValue>& info) +{ + ::osl::MutexGuard aGuard(m_aMutex); + if (ODriver_BASE::rBHelper.bDisposed) + throw lang::DisposedException(); + + if (!acceptsURL(url)) + return nullptr; + + auto pCon = new OWriterConnection(this); + pCon->construct(url, info); + uno::Reference<sdbc::XConnection> xCon = pCon; + m_xConnections.push_back(uno::WeakReferenceHelper(*pCon)); + + return xCon; +} + +sal_Bool SAL_CALL ODriver::acceptsURL(const OUString& url) +{ + return url.startsWith("sdbc:writer:"); +} + +uno::Sequence<sdbc::DriverPropertyInfo> SAL_CALL +ODriver::getPropertyInfo(const OUString& url, const uno::Sequence<beans::PropertyValue>& /*info*/) +{ + if (!acceptsURL(url)) + { + SharedResources aResources; + const OUString sMessage = aResources.getResourceString(STR_URI_SYNTAX_ERROR); + ::dbtools::throwGenericSQLException(sMessage, *this); + } + return uno::Sequence<sdbc::DriverPropertyInfo>(); +} + +} // namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/writer/WTable.cxx b/connectivity/source/drivers/writer/WTable.cxx new file mode 100644 index 000000000..7236df247 --- /dev/null +++ b/connectivity/source/drivers/writer/WTable.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 <writer/WTable.hxx> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/SQLException.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/XTextTable.hpp> +#include <com/sun/star/text/XTextTablesSupplier.hpp> +#include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/text/XText.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <writer/WConnection.hxx> +#include <connectivity/sdbcx/VColumn.hxx> +#include <sal/log.hxx> +#include <comphelper/servicehelper.hxx> +#include <cppuhelper/typeprovider.hxx> + +namespace com::sun::star::text +{ +class XTextDocument; +} + +using namespace ::com::sun::star; + +static void lcl_GetDataArea(const uno::Reference<text::XTextTable>& xTable, sal_Int32& rColumnCount, + sal_Int32& rRowCount) +{ + uno::Reference<container::XIndexAccess> xColumns = xTable->getColumns(); + if (xColumns.is()) + rColumnCount = xColumns->getCount(); + + uno::Reference<container::XIndexAccess> xRows = xTable->getRows(); + if (xRows.is()) + rRowCount = xRows->getCount() - 1; // first row (headers) is not counted +} + +static void lcl_GetColumnInfo(const uno::Reference<text::XTextTable>& xTable, sal_Int32 nDocColumn, + bool bHasHeaders, OUString& rName, sal_Int32& rDataType, + bool& rCurrency) +{ + uno::Reference<table::XCellRange> xCellRange(xTable, uno::UNO_QUERY); + // get column name from first row, if range contains headers + if (bHasHeaders) + { + uno::Reference<text::XText> xHeaderText( + xCellRange->getCellByPosition(nDocColumn, /*nStartRow*/ 0), uno::UNO_QUERY); + if (xHeaderText.is()) + rName = xHeaderText->getString(); + } + + rCurrency = false; + rDataType = sdbc::DataType::VARCHAR; +} + +static void lcl_SetValue(connectivity::ORowSetValue& rValue, + const uno::Reference<text::XTextTable>& xTable, sal_Int32 nStartCol, + bool bHasHeaders, sal_Int32 nDBRow, sal_Int32 nDBColumn) +{ + sal_Int32 nDocColumn = nStartCol + nDBColumn - 1; // database counts from 1 + sal_Int32 nDocRow = nDBRow - 1; + if (bHasHeaders) + ++nDocRow; + + uno::Reference<table::XCellRange> xCellRange(xTable, uno::UNO_QUERY); + uno::Reference<table::XCell> xCell; + try + { + xCell = xCellRange->getCellByPosition(nDocColumn, nDocRow); + } + catch (const lang::IndexOutOfBoundsException& /*rException*/) + { + SAL_WARN("connectivity.writer", + "getCellByPosition(" << nDocColumn << ", " << nDocRow << ") failed"); + rValue = OUString(); + } + + if (xCell.is()) + { + const uno::Reference<text::XText> xText(xCell, uno::UNO_QUERY); + if (xText.is()) + rValue = xText->getString(); + } +} + +namespace connectivity::writer +{ +void OWriterTable::fillColumns() +{ + if (!m_xTable.is()) + throw sdbc::SQLException(); + + OUString aTypeName; + ::comphelper::UStringMixEqual aCase( + m_pConnection->getMetaData()->supportsMixedCaseQuotedIdentifiers()); + const bool bStoresMixedCaseQuotedIdentifiers + = getConnection()->getMetaData()->supportsMixedCaseQuotedIdentifiers(); + + for (sal_Int32 i = 0; i < m_nDataCols; i++) + { + OUString aColumnName; + sal_Int32 eType = sdbc::DataType::OTHER; + bool bCurrency = false; + + lcl_GetColumnInfo(m_xTable, m_nStartCol + i, m_bHasHeaders, aColumnName, eType, bCurrency); + + sal_Int32 nPrecision = 0; //! ... + sal_Int32 nDecimals = 0; //! ... + + switch (eType) + { + case sdbc::DataType::VARCHAR: + aTypeName = "VARCHAR"; + break; + case sdbc::DataType::DECIMAL: + aTypeName = "DECIMAL"; + break; + case sdbc::DataType::BIT: + aTypeName = "BOOL"; + break; + case sdbc::DataType::DATE: + aTypeName = "DATE"; + break; + case sdbc::DataType::TIME: + aTypeName = "TIME"; + break; + case sdbc::DataType::TIMESTAMP: + aTypeName = "TIMESTAMP"; + break; + default: + SAL_WARN("connectivity.writer", "missing type name"); + aTypeName.clear(); + } + + // check if the column name already exists + OUString aAlias = aColumnName; + auto aFind = connectivity::find(m_aColumns->begin(), m_aColumns->end(), aAlias, aCase); + sal_Int32 nExprCnt = 0; + while (aFind != m_aColumns->end()) + { + aAlias = aColumnName + OUString::number(++nExprCnt); + aFind = connectivity::find(m_aColumns->begin(), m_aColumns->end(), aAlias, aCase); + } + + auto pColumn = new sdbcx::OColumn( + aAlias, aTypeName, OUString(), OUString(), sdbc::ColumnValue::NULLABLE, nPrecision, + nDecimals, eType, false, false, bCurrency, bStoresMixedCaseQuotedIdentifiers, + m_CatalogName, getSchema(), getName()); + uno::Reference<XPropertySet> xCol = pColumn; + m_aColumns->push_back(xCol); + } +} + +OWriterTable::OWriterTable(sdbcx::OCollection* _pTables, OWriterConnection* _pConnection, + const OUString& Name, const OUString& Type) + : OWriterTable_BASE(_pTables, _pConnection, Name, Type, OUString() /*Description*/, + OUString() /*SchemaName*/, OUString() /*CatalogName*/) + , m_pWriterConnection(_pConnection) + , m_nStartCol(0) + , m_nDataCols(0) + , m_bHasHeaders(false) +{ +} + +void OWriterTable::construct() +{ + uno::Reference<text::XTextDocument> xDoc = m_pWriterConnection->acquireDoc(); + if (xDoc.is()) + { + uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(xDoc, uno::UNO_QUERY); + uno::Reference<container::XNameAccess> xTables = xTextTablesSupplier->getTextTables(); + if (xTables.is() && xTables->hasByName(m_Name)) + { + m_xTable.set(xTables->getByName(m_Name), uno::UNO_QUERY); + if (m_xTable.is()) + { + lcl_GetDataArea(m_xTable, m_nDataCols, m_nDataRows); + m_bHasHeaders = true; + } + } + } + + fillColumns(); + + refreshColumns(); +} + +void SAL_CALL OWriterTable::disposing() +{ + OFileTable::disposing(); + ::osl::MutexGuard aGuard(m_aMutex); + m_aColumns = nullptr; + if (m_pWriterConnection) + m_pWriterConnection->releaseDoc(); + m_pWriterConnection = nullptr; +} + +uno::Sequence<sal_Int8> OWriterTable::getUnoTunnelId() +{ + static ::cppu::OImplementationId implId; + + return implId.getImplementationId(); +} + +sal_Int64 OWriterTable::getSomething(const uno::Sequence<sal_Int8>& rId) +{ + return (isUnoTunnelId<OWriterTable>(rId)) ? reinterpret_cast<sal_Int64>(this) + : OWriterTable_BASE::getSomething(rId); +} + +bool OWriterTable::fetchRow(OValueRefRow& _rRow, const OSQLColumns& _rCols, bool bRetrieveData) +{ + // read the bookmark + + _rRow->setDeleted(false); + *(*_rRow)[0] = m_nFilePos; + + if (!bRetrieveData) + return true; + + // fields + + const OValueRefVector::size_type nCount = std::min(_rRow->size(), _rCols.size() + 1); + for (OValueRefVector::size_type i = 1; i < nCount; i++) + { + if ((*_rRow)[i]->isBound()) + { + lcl_SetValue((*_rRow)[i]->get(), m_xTable, m_nStartCol, m_bHasHeaders, m_nFilePos, i); + } + } + return true; +} + +} // namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/writer/WTables.cxx b/connectivity/source/drivers/writer/WTables.cxx new file mode 100644 index 000000000..15dc9e0c1 --- /dev/null +++ b/connectivity/source/drivers/writer/WTables.cxx @@ -0,0 +1,45 @@ +/* -*- 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 <writer/WTables.hxx> + +#include <sal/config.h> + +#include <writer/WConnection.hxx> +#include <file/FCatalog.hxx> +#include <writer/WTable.hxx> + +using namespace ::com::sun::star; + +namespace connectivity::writer +{ +sdbcx::ObjectType OWriterTables::createObject(const OUString& rName) +{ + auto pTable = new OWriterTable(this, + static_cast<OWriterConnection*>( + static_cast<file::OFileCatalog&>(m_rParent).getConnection()), + rName, "TABLE"); + sdbcx::ObjectType xRet = pTable; + pTable->construct(); + return xRet; +} + +} // namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/writer/Wservices.cxx b/connectivity/source/drivers/writer/Wservices.cxx new file mode 100644 index 000000000..7f997d7d1 --- /dev/null +++ b/connectivity/source/drivers/writer/Wservices.cxx @@ -0,0 +1,90 @@ +/* -*- 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 <writer/WDriver.hxx> +#include <cppuhelper/factory.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +using namespace com::sun::star; + +using createFactoryFunc = uno::Reference<lang::XSingleServiceFactory> (*)( + const uno::Reference<lang::XMultiServiceFactory>& rServiceManager, + const OUString& rComponentName, ::cppu::ComponentInstantiation pCreateFunction, + const uno::Sequence<OUString>& rServiceNames, rtl_ModuleCount*); + +namespace +{ +struct ProviderRequest +{ +private: + uno::Reference<lang::XSingleServiceFactory> xRet; + uno::Reference<lang::XMultiServiceFactory> const xServiceManager; + OUString const sImplementationName; + +public: + ProviderRequest(void* pServiceManager, char const* pImplementationName) + : xServiceManager(static_cast<lang::XMultiServiceFactory*>(pServiceManager)) + , sImplementationName(OUString::createFromAscii(pImplementationName)) + { + } + + bool CREATE_PROVIDER(const OUString& Implname, const uno::Sequence<OUString>& Services, + ::cppu::ComponentInstantiation Factory, createFactoryFunc creator) + { + if (!xRet.is() && (Implname == sImplementationName)) + { + try + { + xRet = creator(xServiceManager, sImplementationName, Factory, Services, nullptr); + } + catch (...) + { + } + } + return xRet.is(); + } + + uno::XInterface* getProvider() const { return xRet.get(); } +}; +} + +extern "C" SAL_DLLPUBLIC_EXPORT void* +connectivity_writer_component_getFactory(const char* pImplementationName, void* pServiceManager, + void* /*pRegistryKey*/) +{ + void* pRet = nullptr; + if (pServiceManager) + { + ProviderRequest aReq(pServiceManager, pImplementationName); + + aReq.CREATE_PROVIDER(connectivity::writer::ODriver::getImplementationName_Static(), + connectivity::writer::ODriver::getSupportedServiceNames_Static(), + connectivity::writer::ODriver_CreateInstance, + ::cppu::createSingleFactory); + + if (aReq.getProvider()) + aReq.getProvider()->acquire(); + + pRet = aReq.getProvider(); + } + + return pRet; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/writer/writer.component b/connectivity/source/drivers/writer/writer.component new file mode 100644 index 000000000..3bf9d6e79 --- /dev/null +++ b/connectivity/source/drivers/writer/writer.component @@ -0,0 +1,17 @@ +<?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/. + --> + +<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@" + prefix="connectivity_writer" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.comp.sdbc.writer.ODriver"> + <service name="com.sun.star.sdbc.Driver"/> + <service name="com.sun.star.sdbcx.Driver"/> + </implementation> +</component> |