21#include <com/sun/star/sdbc/ColumnValue.hpp>
22#include <com/sun/star/sdbc/DataType.hpp>
23#include <com/sun/star/sdbc/XRow.hpp>
24#include <com/sun/star/ucb/XContentAccess.hpp>
28#include <rtl/math.hxx>
34#include <com/sun/star/util/NumberFormat.hpp>
35#include <com/sun/star/util/NumberFormatter.hpp>
36#include <com/sun/star/util/NumberFormatsSupplier.hpp>
49using namespace ::
cppu;
59using std::lower_bound;
62void OFlatTable::fillColumns(
const css::lang::Locale& _aLocale)
67 m_pFileStream->StartReadingUnicodeText(RTL_TEXTENCODING_DONTKNOW);
80 bRead =
readLine(&rowPos.second, &rowPos.first,
true);
89 bRead =
readLine(&rowPos.second, &rowPos.first);
94 if ( !bHasHeaderLine || !aHeaderLine.
Len())
99 bRead =
readLine(&rowPos.second, &rowPos.first);
118 m_aTypes.assign(nFieldCount+1,DataType::SQLNULL);
128 vector<OUString> aColumnNames;
129 vector<OUString> aTypeNames;
130 aTypeNames.resize(nFieldCount);
132 sal_Int32 nRowCount = 0;
136 sal_Int32 nStartPosHeaderLine = 0;
137 sal_Int32 nStartPosFirstLine = 0;
138 sal_Int32 nStartPosFirstLine2 = 0;
139 for( sal_Int32
i = 0;
i < nFieldCount;
i++ )
143 OUString aColumnName;
144 if ( bHasHeaderLine )
148 if ( aColumnName.isEmpty() )
150 aColumnName =
"C" + OUString::number(
i+1);
152 aColumnNames.push_back(aColumnName);
158 cDecimalDelimiter, cThousandDelimiter, aCharClass);
162 bRead =
readLine(&rowPos.second, &rowPos.first);
166 while(nRowCount < nMaxRowsToScan && bRead);
168 for( sal_Int32
i = 0;
i < nFieldCount;
i++ )
171 OUString aAlias(aColumnNames[
i]);
173 sal_Int32 nExprCnt = 0;
176 aAlias = aColumnNames[
i] + OUString::number(++nExprCnt);
181 ColumnValue::NULLABLE,
197 sal_Int32& io_nType, sal_Int32& io_nPrecisions, sal_Int32& io_nScales, OUString& o_sTypeName,
200 if ( io_nType != DataType::VARCHAR )
202 bool bNumeric = io_nType == DataType::SQLNULL || io_nType == DataType::DOUBLE || io_nType == DataType::DECIMAL || io_nType == DataType::INTEGER;
209 if (aField.isEmpty() ||
216 nStartPosFirstLine2 = nStartPosFirstLine;
226 if (aField2.isEmpty())
234 sal_Int32 nDecimalDelCount = 0;
235 sal_Int32 nSpaceCount = 0;
236 for( sal_Int32 j = 0; j < aField2.getLength(); j++ )
245 if ( ( !cDecimalDelimiter || c != cDecimalDelimiter ) &&
246 ( !cThousandDelimiter || c != cThousandDelimiter ) &&
247 !aCharClass.
isDigit(aField2,j) &&
248 ( j != 0 || (c !=
'+' && c !=
'-' ) ) )
253 if (cDecimalDelimiter && c == cDecimalDelimiter)
263 if (nDecimalDelCount > 1 || nDot > 1 )
265 if (bNumeric && cThousandDelimiter)
268 const std::u16string_view aValue =
o3tl::getToken(aField2, 0, cDecimalDelimiter);
269 for( sal_Int32 j =
static_cast<sal_Int32
>(aValue.size()) - 4; j >= 0; j -= 4)
273 if (c == cThousandDelimiter && j)
297 else if ( io_nType == DataType::DATE || io_nType == DataType::TIMESTAMP || io_nType == DataType::TIME)
300 if (aField.isEmpty() ||
311 if (!aField2.isEmpty() )
326 if (cDecimalDelimiter)
330 io_nType = DataType::DECIMAL;
331 o_sTypeName =
"DECIMAL";
335 io_nType = DataType::DOUBLE;
336 o_sTypeName =
"DOUBLE";
341 io_nType = DataType::INTEGER;
350 case css::util::NumberFormat::DATE:
351 io_nType = DataType::DATE;
352 o_sTypeName =
"DATE";
354 case css::util::NumberFormat::DATETIME:
355 io_nType = DataType::TIMESTAMP;
356 o_sTypeName =
"TIMESTAMP";
358 case css::util::NumberFormat::TIME:
359 io_nType = DataType::TIME;
360 o_sTypeName =
"TIME";
363 io_nType = DataType::VARCHAR;
366 o_sTypeName =
"VARCHAR";
373 if (aField.isEmpty() ||
379 nStartPosFirstLine2 = nStartPosFirstLine;
390 const OUString& Name,
391 const OUString&
Type,
392 const OUString& Description ,
393 const OUString& SchemaName,
394 const OUString& CatalogName
402 ,m_cStringDelimiter(_pConnection->getStringDelimiter())
403 ,m_cFieldDelimiter(_pConnection->getFieldDelimiter())
404 ,m_bNeedToReadLine(false)
418 xProp->getPropertyValue(
"NullDate") >>=
m_aNullDate;
440 nSize > 100000 ? 16384 :
441 nSize > 10000 ? 4096 : 1024);
462 sName = xRow->getString(1);
463 aURL.SetSmartProtocol(INetProtocol::File);
465 aURL.SetSmartURL( sUrl );
468 sExt =
aURL.getExtension();
473 if ( !sExt.isEmpty() )
474 sName =
sName.replaceAt(
sName.getLength() - (sExt.getLength() + 1), sExt.getLength()+1,
u"");
478 sURL = xContentAccess->queryContentIdentifierString();
494 ::osl::MutexGuard aGuard(
m_aMutex );
496 ::std::vector< OUString> aVector;
511 OFileTable::disposing();
519 vector<Type> aOwnTypes;
520 aOwnTypes.reserve(
aTypes.getLength());
522 const Type* pEnd = pBegin +
aTypes.getLength();
523 for(;pBegin != pEnd;++pBegin)
531 aOwnTypes.push_back(*pBegin);
564 if(
readLine(&rowPos.second, &rowPos.first))
577 sal_Int32 nStartPos = 0;
578 OSQLColumns::const_iterator aIter = _rCols.begin();
579 OSQLColumns::const_iterator aEnd = _rCols.end();
580 const OValueRefVector::size_type
nCount = _rRow->size();
581 for (OValueRefVector::size_type
i = 1;
589 (*_rRow)[
i]->setNull();
596 case DataType::TIMESTAMP:
609 case DataType::TIMESTAMP:
618 (*_rRow)[
i]->setNull();
621 case DataType::DOUBLE:
622 case DataType::INTEGER:
623 case DataType::DECIMAL:
624 case DataType::NUMERIC:
627 OUString aStrConverted;
628 if ( DataType::INTEGER !=
nType )
630 OSL_ENSURE((cDecimalDelimiter &&
nType != DataType::INTEGER) ||
631 (!cDecimalDelimiter &&
nType == DataType::INTEGER),
634 OUStringBuffer
aBuf(
aStr.getLength());
636 for (sal_Int32 j = 0; j <
aStr.getLength(); ++j)
639 if (cDecimalDelimiter && cChar == cDecimalDelimiter)
641 else if ( cChar ==
'.' )
643 else if (cThousandDelimiter && cChar == cThousandDelimiter)
650 aStrConverted =
aBuf.makeStringAndClear();
654 if ( cThousandDelimiter )
655 aStrConverted =
aStr.replaceAll(OUStringChar(cThousandDelimiter),
"");
657 aStrConverted =
aStr;
659 const double nVal = ::rtl::math::stringToDouble(aStrConverted,
'.',
',');
662 if ( DataType::DECIMAL ==
nType || DataType::NUMERIC ==
nType )
663 *(*_rRow)[
i] = OUString::number(nVal);
675 (*_rRow)[
i]->setTypeKind(
nType);
684 SAL_INFO(
"connectivity.flat",
"flat lionel@mamane.lu OFlatTable::refreshHeader" );
690 template<
typename Tp,
typename Te>
struct RangeBefore
692 bool operator() (
const Tp &p,
const Te &e)
694 assert(
p.first <=
p.second);
695 return p.second <= e;
702 OSL_ENSURE(
m_pFileStream,
"OFlatTable::seekRow: FileStream is NULL!");
705 switch(eCursorPosition)
729 assert(
m_nRowPos == 1 || nCurPos == lastRowPos.second);
735 if(!
readLine(&newRowPos.second, &newRowPos.first))
741 nCurPos = newRowPos.second;
759 nCurPos = aPositions.second;
773 const sal_Int32 nNewRowPos =
m_nRowPos + nOffset;
801 nCurPos = lastRowPos.second;
807 assert(nOffset >= 0);
830 vector< TRowPositionInFile >::const_iterator aFind = lower_bound(
m_aRowPosToFilePos.begin(),
833 RangeBefore< TRowPositionInFile, sal_Int32 >());
841 nCurPos = aFind->second;
864 sal_Int32 nLastOffset = 0;
866 bool isFieldStarting =
true;
869 bool wasQuote =
false;
876 wasQuote = !wasQuote;
884 isFieldStarting =
true;
892 isFieldStarting =
false;
896 isFieldStarting =
true;
899 isFieldStarting =
true;
909 nLastOffset = sLine.
Len();
941 "Setting position for row " << rowNum <<
" to (" << rowPos.first <<
", " << rowPos.second <<
"), "
static double toDouble(std::string_view rString)
bool isDigit(const OUString &rStr, sal_Int32 nPos) const
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
const LanguageTag & GetLanguageTag() const
OUString GetTokenSpecial(sal_Int32 &nStartPos, sal_Unicode cTok, sal_Unicode cStrDel='\0') const
sal_Int32 GetTokenCount(sal_Unicode cTok, sal_Unicode cStrDel) const
void SetString(const OUString &aStr)
bool matchesExtension(const OUString &_rExt) const
virtual css::uno::Reference< css::sdbc::XDatabaseMetaData > SAL_CALL getMetaData() override
css::uno::Reference< css::ucb::XDynamicResultSet > getDir() const
const OUString & getExtension() const
OFileDriver * getDriver() const
const css::uno::Reference< css::uno::XComponentContext > & getComponentContext() const
OConnection * m_pConnection
const OUString & getSchema() const
OUString SAL_CALL getName() override
static std::unique_ptr< SvStream > createStream_simpleError(const OUString &_rFileName, StreamMode _eOpenMode)
::rtl::Reference< OSQLColumns > m_aColumns
std::unique_ptr< SvStream > m_pFileStream
sal_Unicode getThousandDelimiter() const
sal_Int32 getMaxRowsToScan() const
sal_Unicode getDecimalDelimiter() const
bool isHeaderLine() const
void setRowPos(std::vector< TRowPositionInFile >::size_type rowNum, const TRowPositionInFile &rowPos)
bool readLine(sal_Int32 *pEndPos, sal_Int32 *pStartPos, bool nonEmpty=false)
virtual bool seekRow(IResultSetHelper::Movement eCursorPosition, sal_Int32 nOffset, sal_Int32 &nCurPos) override
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
virtual void refreshColumns() override
OFlatConnection * getFlatConnection()
virtual void refreshHeader() override
void fillColumns(const css::lang::Locale &_aLocale)
virtual void SAL_CALL disposing() override
QuotedTokenizedString m_aCurrentLine
virtual bool fetchRow(OValueRefRow &_rRow, const OSQLColumns &_rCols, bool bRetrieveData) override
std::vector< sal_Int32 > m_aPrecisions
sal_Unicode m_cStringDelimiter
css::util::Date m_aNullDate
css::uno::Reference< css::util::XNumberFormatter > m_xNumberFormatter
OFlatTable(sdbcx::OCollection *_pTables, OFlatConnection *_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
void impl_fillColumnInfo_nothrow(QuotedTokenizedString const &aFirstLine, sal_Int32 &nStartPosFirstLine, sal_Int32 &nStartPosFirstLine2, sal_Int32 &io_nType, sal_Int32 &io_nPrecisions, sal_Int32 &io_nScales, OUString &o_sTypeName, const sal_Unicode cDecimalDelimiter, const sal_Unicode cThousandDelimiter, const CharClass &aCharClass)
std::vector< TRowPositionInFile > m_aRowPosToFilePos
std::vector< sal_Int32 > m_aScales
sal_Unicode m_cFieldDelimiter
void construct() override
OUString getEntry() const
std::unique_ptr< OCollection > m_xColumns
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
mutable::osl::Mutex m_aMutex
#define SAL_WARN_IF(condition, area, stream)
#define SAL_INFO(area, stream)
sal_Int16 getNumberFormatType(const css::uno::Reference< css::util::XNumberFormats > &xFormats, sal_Int32 nKey)
std::pair< sal_Int32, sal_Int32 > TRowPositionInFile
ORefVector< css::uno::Reference< css::beans::XPropertySet > > OSQLColumns
OSQLColumns::const_iterator find(const OSQLColumns::const_iterator &first, const OSQLColumns::const_iterator &last, std::u16string_view _rVal, const ::comphelper::UStringMixEqual &_rCase)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
static bool isQuoted(std::string_view str)