21#include <com/sun/star/sdbc/ColumnValue.hpp>
22#include <com/sun/star/sdbc/DataType.hpp>
23#include <com/sun/star/sdbc/SQLException.hpp>
24#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
25#include <com/sun/star/sheet/XSpreadsheet.hpp>
26#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
27#include <com/sun/star/sheet/XCellRangesQuery.hpp>
28#include <com/sun/star/sheet/XDatabaseRanges.hpp>
29#include <com/sun/star/sheet/XDatabaseRange.hpp>
30#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
31#include <com/sun/star/sheet/XUsedAreaCursor.hpp>
32#include <com/sun/star/sheet/CellFlags.hpp>
33#include <com/sun/star/sheet/FormulaResult.hpp>
34#include <com/sun/star/util/NumberFormat.hpp>
35#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
36#include <com/sun/star/text/XText.hpp>
39#include <rtl/ustrbuf.hxx>
41#include <rtl/math.hxx>
48using namespace ::
cppu;
67 if ( !xUsedQuery.is() )
70 const sal_Int16 nContentFlags =
71 CellFlags::STRING | CellFlags::VALUE | CellFlags::DATETIME | CellFlags::FORMULA | CellFlags::ANNOTATION;
76 const sal_Int32
nCount = aAddresses.getLength();
77 const CellRangeAddress*
pData = aAddresses.getConstArray();
80 rEndCol = std::max(
pData[
i].EndColumn, rEndCol);
81 rEndRow = std::max(
pData[
i].EndRow, rEndRow);
91 rColumnCount = rRowCount = 0;
97 xCursor->collapseToSize( 1, 1 );
98 xCursor->collapseToCurrentRegion();
100 CellRangeAddress aRegionAddr = xRange->getRangeAddress();
101 sal_Int32 nEndCol = aRegionAddr.EndColumn;
102 sal_Int32 nEndRow = aRegionAddr.EndRow;
111 xUsed->gotoEndOfUsedArea(
false );
112 CellRangeAddress aUsedAddr = xRange->getRangeAddress();
114 if ( aUsedAddr.EndColumn > aRegionAddr.EndColumn )
117 aRegionAddr.EndColumn + 1, 0, aUsedAddr.EndColumn, aUsedAddr.EndRow );
121 if ( aUsedAddr.EndRow > aRegionAddr.EndRow )
125 0, aRegionAddr.EndRow + 1, aRegionAddr.EndColumn, aUsedAddr.EndRow );
130 rColumnCount = nEndCol + 1;
136 CellContentType eCellType = xCell->getType();
137 if ( eCellType == CellContentType_FORMULA )
142 xProp->getPropertyValue(
"CellContentType" ) >>= eCellType;
144 catch (UnknownPropertyException&)
146 eCellType = CellContentType_VALUE;
155 if ( xCell.is() && xCell->getType() == CellContentType_EMPTY )
162 CellRangeAddress aTotalRange = xAddr->getRangeAddress();
163 sal_Int32 nLastRow = aTotalRange.EndRow;
175 if ( xEnum.is() && xEnum->hasMoreElements() )
178 xCell.set(xEnum->nextElement(),UNO_QUERY);
196 CellRangeAddress aTotalRange = xAddr->getRangeAddress();
197 sal_Int32 nLastRow = aTotalRange.EndRow;
204 if ( xTextContent.is() && xTextContent->hasElements() )
209 if ( xTextFormula.is() && xTextFormula->hasElements() )
216 sal_Int32 nDocColumn, sal_Int32 nStartRow,
bool bHasHeaders,
217 OUString& rName, sal_Int32& rDataType,
bool& rCurrency )
225 Reference<XText> xHeaderText( xSheet->getCellByPosition( nDocColumn, nStartRow ), UNO_QUERY );
226 if ( xHeaderText.is() )
227 rName = xHeaderText->getString();
232 sal_Int32 nDataRow = nStartRow;
245 if ( eCellType == CellContentType_TEXT ||
lcl_HasTextInColumn( xSheet, nDocColumn, nDataRow ) )
246 rDataType = DataType::VARCHAR;
247 else if ( eCellType == CellContentType_VALUE )
251 sal_Int16
nNumType = NumberFormat::NUMBER;
256 if ( xProp->getPropertyValue(
"NumberFormat" ) >>= nKey )
269 if (
nNumType & NumberFormat::TEXT )
270 rDataType = DataType::VARCHAR;
271 else if (
nNumType & NumberFormat::NUMBER )
272 rDataType = DataType::DECIMAL;
273 else if (
nNumType & NumberFormat::CURRENCY )
276 rDataType = DataType::DECIMAL;
278 else if ( (
nNumType & NumberFormat::DATETIME ) == NumberFormat::DATETIME )
281 rDataType = DataType::TIMESTAMP;
283 else if (
nNumType & NumberFormat::DATE )
284 rDataType = DataType::DATE;
285 else if (
nNumType & NumberFormat::TIME )
286 rDataType = DataType::TIME;
287 else if (
nNumType & NumberFormat::LOGICAL )
288 rDataType = DataType::BIT;
290 rDataType = DataType::DECIMAL;
295 rDataType = DataType::VARCHAR;
301 sal_Int32 nStartCol, sal_Int32 nStartRow,
bool bHasHeaders,
302 const ::Date& rNullDate,
303 sal_Int32 nDBRow, sal_Int32 nDBColumn, sal_Int32 nType )
305 sal_Int32 nDocColumn = nStartCol + nDBColumn - 1;
306 sal_Int32 nDocRow = nStartRow + nDBRow - 1;
310 const Reference<XCell> xCell = xSheet->getCellByPosition( nDocColumn, nDocRow );
317 case DataType::VARCHAR:
318 if ( eCellType == CellContentType_EMPTY )
325 rValue = xText->getString();
328 case DataType::DECIMAL:
329 if ( eCellType == CellContentType_VALUE )
330 rValue = xCell->getValue();
335 if ( eCellType == CellContentType_VALUE )
336 rValue = xCell->getValue() != 0.0;
341 if ( eCellType == CellContentType_VALUE )
343 ::Date aDate( rNullDate );
344 aDate.
AddDays(::rtl::math::approxFloor( xCell->getValue() ));
351 if ( eCellType == CellContentType_VALUE )
353 double fCellVal = xCell->getValue();
354 double fTime = fCellVal - rtl::math::approxFloor( fCellVal );
358 css::util::Time aTime;
361 aTime.Seconds =
static_cast<sal_uInt16
>( nIntTime % 60 );
363 aTime.Minutes =
static_cast<sal_uInt16
>( nIntTime % 60 );
365 OSL_ENSURE( nIntTime < 24,
"error in time calculation" );
366 aTime.Hours =
static_cast<sal_uInt16
>(nIntTime);
372 case DataType::TIMESTAMP:
373 if ( eCellType == CellContentType_VALUE )
375 double fCellVal = xCell->getValue();
376 double fDays = ::rtl::math::approxFloor( fCellVal );
377 double fTime = fCellVal - fDays;
386 css::util::DateTime aDateTime;
390 aDateTime.Seconds =
static_cast<sal_uInt16
>( nIntTime % 60 );
392 aDateTime.Minutes =
static_cast<sal_uInt16
>( nIntTime % 60 );
394 OSL_ENSURE( nIntTime < 24,
"error in time calculation" );
395 aDateTime.Hours =
static_cast<sal_uInt16
>(nIntTime);
397 ::Date aDate( rNullDate );
399 aDateTime.Day = aDate.
GetDay();
401 aDateTime.Year = aDate.
GetYear();
417 return OUString(
static_cast<sal_Unicode>(
'A' + nColumn ) );
424 return aBuffer.makeStringAndClear();
428void OCalcTable::fillColumns()
431 throw SQLException();
435 const bool bStoresMixedCaseQuotedIdentifiers =
getConnection()->
getMetaData()->supportsMixedCaseQuotedIdentifiers();
439 OUString aColumnName;
440 sal_Int32
eType = DataType::OTHER;
441 bool bCurrency =
false;
444 aColumnName,
eType, bCurrency );
446 if ( aColumnName.isEmpty() )
449 sal_Int32 nPrecision = 0;
450 sal_Int32 nDecimals = 0;
454 case DataType::VARCHAR:
455 aTypeName =
"VARCHAR";
457 case DataType::DECIMAL:
458 aTypeName =
"DECIMAL";
469 case DataType::TIMESTAMP:
470 aTypeName =
"TIMESTAMP";
473 SAL_WARN(
"connectivity.drivers",
"missing type name");
478 OUString aAlias = aColumnName;
480 sal_Int32 nExprCnt = 0;
483 aAlias = aColumnName + OUString::number(++nExprCnt);
488 ColumnValue::NULLABLE, nPrecision, nDecimals,
489 eType,
false,
false, bCurrency,
490 bStoresMixedCaseQuotedIdentifiers,
499 const OUString& Name,
500 const OUString&
Type,
501 const OUString& Description ,
502 const OUString& SchemaName,
503 const OUString& CatalogName
509 ,m_pCalcConnection(_pConnection)
513 ,m_bHasHeaders(false)
525 if ( xSheets.is() && xSheets->hasByName(
m_Name ) )
542 if ( xRanges.is() && xRanges->hasByName(
m_Name ) )
551 bool bRangeHeader =
true;
553 if ( xFiltProp.is() )
554 xFiltProp->getPropertyValue(
"ContainsHeader") >>= bRangeHeader;
558 if ( xSheetRange.is() && xAddr.is() )
560 m_xSheet = xSheetRange->getSpreadsheet();
561 CellRangeAddress aRangeAddr = xAddr->getRangeAddress();
587 css::util::Date aDateStruct;
588 if ( xProp->getPropertyValue(
"NullDate") >>= aDateStruct )
602 OFileTable::disposing();
616 _rRow->setDeleted(
false);
624 const OValueRefVector::size_type
nCount = std::min(_rRow->size(), _rCols.size() + 1);
625 for (OValueRefVector::size_type
i = 1;
i <
nCount;
i++)
627 if ( (*_rRow)[
i]->isBound() )
static CellContentType lcl_GetContentOrResultType(const Reference< XCell > &xCell)
static bool lcl_HasTextInColumn(const Reference< XSpreadsheet > &xSheet, sal_Int32 nDocColumn, sal_Int32 nDocRow)
static OUString lcl_GetColumnStr(sal_Int32 nColumn)
static Reference< XCell > lcl_GetUsedCell(const Reference< XSpreadsheet > &xSheet, sal_Int32 nDocColumn, sal_Int32 nDocRow)
static void lcl_GetColumnInfo(const Reference< XSpreadsheet > &xSheet, const Reference< XNumberFormats > &xFormats, sal_Int32 nDocColumn, sal_Int32 nStartRow, bool bHasHeaders, OUString &rName, sal_Int32 &rDataType, bool &rCurrency)
static void lcl_UpdateArea(const Reference< XCellRange > &xUsedRange, sal_Int32 &rEndCol, sal_Int32 &rEndRow)
static void lcl_SetValue(ORowSetValue &rValue, const Reference< XSpreadsheet > &xSheet, sal_Int32 nStartCol, sal_Int32 nStartRow, bool bHasHeaders, const ::Date &rNullDate, sal_Int32 nDBRow, sal_Int32 nDBColumn, sal_Int32 nType)
static void lcl_GetDataArea(const Reference< XSpreadsheet > &xSheet, sal_Int32 &rColumnCount, sal_Int32 &rRowCount)
css::util::Date GetUNODate() const
void AddDays(sal_Int32 nAddDays)
sal_Int16 GetYear() const
sal_uInt16 GetDay() const
sal_uInt16 GetMonth() const
css::uno::Reference< css::sheet::XSpreadsheetDocument > const & acquireDoc()
void construct() override
css::uno::Reference< css::util::XNumberFormats > m_xFormats
virtual bool fetchRow(OValueRefRow &_rRow, const OSQLColumns &_rCols, bool bRetrieveData) override
virtual void SAL_CALL disposing() override
OCalcTable(sdbcx::OCollection *_pTables, OCalcConnection *_pConnection, const OUString &Name, const OUString &Type, const OUString &Description=OUString(), const OUString &SchemaName=OUString(), const OUString &CatalogName=OUString())
std::vector< sal_Int32 > m_aTypes
css::uno::Reference< css::sheet::XSpreadsheet > m_xSheet
OCalcConnection * m_pCalcConnection
Shared Table base class for Writer tables and Calc sheets.
virtual void refreshColumns() override
virtual css::uno::Reference< css::sdbc::XDatabaseMetaData > SAL_CALL getMetaData() override
OConnection * m_pConnection
const OUString & getSchema() const
OUString SAL_CALL getName() override
::rtl::Reference< OSQLColumns > m_aColumns
OConnection * getConnection() const
mutable::osl::Mutex m_aMutex
#define SAL_WARN(area, stream)
std::unique_ptr< sal_Int32[]> pData
OSQLColumns::const_iterator find(const OSQLColumns::const_iterator &first, const OSQLColumns::const_iterator &last, std::u16string_view _rVal, const ::comphelper::UStringMixEqual &_rCase)
constexpr OUStringLiteral EMPTY
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
std::unique_ptr< char[]> aBuffer