summaryrefslogtreecommitdiff
path: root/connectivity/source/drivers/evoab/LFolderList.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'connectivity/source/drivers/evoab/LFolderList.cxx')
-rw-r--r--connectivity/source/drivers/evoab/LFolderList.cxx563
1 files changed, 563 insertions, 0 deletions
diff --git a/connectivity/source/drivers/evoab/LFolderList.cxx b/connectivity/source/drivers/evoab/LFolderList.cxx
new file mode 100644
index 000000000000..02d3fb284312
--- /dev/null
+++ b/connectivity/source/drivers/evoab/LFolderList.cxx
@@ -0,0 +1,563 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_connectivity.hxx"
+
+#include <ctype.h>
+#include <algorithm>
+#include "LFolderList.hxx"
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <svl/converter.hxx>
+#include "LConnection.hxx"
+#include "LColumns.hxx"
+#include <osl/thread.h>
+#include <tools/config.hxx>
+#include <comphelper/sequence.hxx>
+#include <svl/zforlist.hxx>
+#include <rtl/math.hxx>
+#include <stdio.h> //sprintf
+#include <comphelper/extract.hxx>
+#include <comphelper/numbers.hxx>
+#include "LDriver.hxx"
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <unotools/configmgr.hxx>
+#include <i18npool/mslangid.hxx>
+#include "connectivity/dbconversion.hxx"
+#include <comphelper/types.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <tools/debug.hxx>
+#include "connectivity/dbexception.hxx"
+#ifndef CONNECTIVITY_EVOAB_DEBUG_HELPER_HXX
+#include "LDebug.hxx"
+#endif
+#include <unotools/syslocale.hxx>
+
+using namespace ::comphelper;
+using namespace connectivity;
+using namespace connectivity::evoab;
+using namespace connectivity::file;
+using namespace ::cppu;
+using namespace utl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+// -------------------------------------------------------------------------
+void OEvoabFolderList::fillColumns(const ::com::sun::star::lang::Locale& _aLocale)
+{
+ sal_Bool bRead = sal_True;
+
+ QuotedTokenizedString aHeaderLine;
+ OEvoabConnection* pConnection = (OEvoabConnection*)m_pConnection;
+
+ // read first row
+ QuotedTokenizedString aFirstLine;
+ bRead = m_pFileStream->ReadByteStringLine(aFirstLine,pConnection->getTextEncoding());
+
+ while(bRead && !aFirstLine.Len())
+ {
+ bRead = m_pFileStream->ReadByteStringLine(aFirstLine,pConnection->getTextEncoding());
+ }
+ // use first row as headerline because we need the number of columns
+ aHeaderLine = aFirstLine;
+
+ // column count
+ xub_StrLen nFieldCount = aHeaderLine.GetTokenCount(pConnection->getFieldDelimiter(),pConnection->getStringDelimiter());
+
+ if(!m_aColumns.isValid())
+ m_aColumns = new OSQLColumns();
+ else
+ m_aColumns->get().clear();
+
+ m_aTypes.clear();
+ m_aPrecisions.clear();
+ m_aScales.clear();
+ // reserve some space
+ m_aColumns->get().reserve(nFieldCount);
+ m_aTypes.reserve(nFieldCount);
+ m_aPrecisions.reserve(nFieldCount);
+ m_aScales.reserve(nFieldCount);
+
+ sal_Bool bCase = getConnection()->getMetaData()->supportsMixedCaseQuotedIdentifiers();
+ CharClass aCharClass(pConnection->getDriver()->getFactory(),_aLocale);
+ // read description
+ sal_Unicode cDecimalDelimiter = pConnection->getDecimalDelimiter();
+ sal_Unicode cThousandDelimiter = pConnection->getThousandDelimiter();
+ String aColumnName;
+ ::rtl::OUString aTypeName;
+ ::comphelper::UStringMixEqual aCase(bCase);
+ xub_StrLen nStartPosFirstLine = 0; // use for eficient way to get the tokens
+ xub_StrLen nStartPosFirstLine2 = 0;
+ for (xub_StrLen i = 0; i < nFieldCount; i++)
+ {
+
+ // no column name so ...
+ aColumnName = 'C';
+ aColumnName += String::CreateFromInt32(i+1);
+
+ sal_Int32 eType;
+ sal_uInt16 nPrecision = 0;
+ sal_uInt16 nScale = 0;
+
+ sal_Bool bNumeric = sal_False;
+ sal_uIntPtr nIndex = 0;
+
+ // first without fielddelimiter
+ String aField;
+ aFirstLine.GetTokenSpecial(aField,nStartPosFirstLine,pConnection->getFieldDelimiter(),'\0');
+ if (aField.Len() == 0 ||
+ (pConnection->getStringDelimiter() && pConnection->getStringDelimiter() == aField.GetChar(0)))
+ {
+ bNumeric = sal_False;
+ }
+ else
+ {
+ String aField2;
+ if ( pConnection->getStringDelimiter() != '\0' )
+ aFirstLine.GetTokenSpecial(aField2,nStartPosFirstLine2,pConnection->getFieldDelimiter(),pConnection->getStringDelimiter());
+ else
+ aField2 = aField;
+
+ if (aField2.Len() == 0)
+ {
+ bNumeric = sal_False;
+ }
+ else
+ {
+ bNumeric = sal_True;
+ xub_StrLen nDot = 0;
+ for (xub_StrLen j = 0; j < aField2.Len(); j++)
+ {
+ sal_Unicode c = aField2.GetChar(j);
+ // nur Ziffern und Dezimalpunkt und Tausender-Trennzeichen?
+ if ((!cDecimalDelimiter || c != cDecimalDelimiter) &&
+ (!cThousandDelimiter || c != cThousandDelimiter) &&
+ !aCharClass.isDigit(aField2,j))
+ {
+ bNumeric = sal_False;
+ break;
+ }
+ if (cDecimalDelimiter && c == cDecimalDelimiter)
+ {
+ nPrecision = 15; // we have an decimal value
+ nScale = 2;
+ nDot++;
+ }
+ }
+
+ if (nDot > 1) // if there is more than one dot it isn't a number
+ bNumeric = sal_False;
+ if (bNumeric && cThousandDelimiter)
+ {
+ // Ist der Trenner richtig angegeben?
+ String aValue = aField2.GetToken(0,cDecimalDelimiter);
+ for (sal_Int32 j = aValue.Len() - 4; j >= 0; j -= 4)
+ {
+ sal_Unicode c = aValue.GetChar(j);
+ // nur Ziffern und Dezimalpunkt und Tausender-Trennzeichen?
+ if (c == cThousandDelimiter && j)
+ continue;
+ else
+ {
+ bNumeric = sal_False;
+ break;
+ }
+ }
+ }
+
+ // jetzt koennte es noch ein Datumsfeld sein
+ if (!bNumeric)
+ {
+ try
+ {
+ nIndex = m_xNumberFormatter->detectNumberFormat(::com::sun::star::util::NumberFormat::ALL,aField2);
+ }
+ catch(Exception&)
+ {
+ }
+ }
+ }
+ }
+
+ sal_Int32 nFlags = 0;
+ if (bNumeric)
+ {
+ if (cDecimalDelimiter)
+ {
+ if(nPrecision)
+ {
+ eType = DataType::DECIMAL;
+ aTypeName = ::rtl::OUString::createFromAscii("DECIMAL");
+ }
+ else
+ {
+ eType = DataType::DOUBLE;
+ aTypeName = ::rtl::OUString::createFromAscii("DOUBLE");
+ }
+ }
+ else
+ eType = DataType::INTEGER;
+ nFlags = ColumnSearch::BASIC;
+ }
+ else
+ {
+
+ switch (comphelper::getNumberFormatType(m_xNumberFormatter,nIndex))
+ {
+ case NUMBERFORMAT_DATE:
+ eType = DataType::DATE;
+ aTypeName = ::rtl::OUString::createFromAscii("DATE");
+ break;
+ case NUMBERFORMAT_DATETIME:
+ eType = DataType::TIMESTAMP;
+ aTypeName = ::rtl::OUString::createFromAscii("TIMESTAMP");
+ break;
+ case NUMBERFORMAT_TIME:
+ eType = DataType::TIME;
+ aTypeName = ::rtl::OUString::createFromAscii("TIME");
+ break;
+ default:
+ eType = DataType::VARCHAR;
+ nPrecision = 0; // nyi: Daten koennen aber laenger sein!
+ nScale = 0;
+ aTypeName = ::rtl::OUString::createFromAscii("VARCHAR");
+ };
+ nFlags |= ColumnSearch::CHAR;
+ }
+
+ // check if the columname already exists
+ String aAlias(aColumnName);
+ OSQLColumns::Vector::const_iterator aFind = connectivity::find(m_aColumns->get().begin(),m_aColumns->get().end(),aAlias,aCase);
+ sal_Int32 nExprCnt = 0;
+ while(aFind != m_aColumns->get().end())
+ {
+ (aAlias = aColumnName) += String::CreateFromInt32(++nExprCnt);
+ aFind = connectivity::find(m_aColumns->get().begin(),m_aColumns->get().end(),aAlias,aCase);
+ }
+
+ sdbcx::OColumn* pColumn = new sdbcx::OColumn(aAlias,aTypeName,::rtl::OUString(),
+ ColumnValue::NULLABLE,
+ nPrecision,
+ nScale,
+ eType,
+ sal_False,
+ sal_False,
+ sal_False,
+ bCase);
+ Reference< XPropertySet> xCol = pColumn;
+ m_aColumns->get().push_back(xCol);
+ m_aTypes.push_back(eType);
+ m_aPrecisions.push_back(nPrecision);
+ m_aScales.push_back(nScale);
+ }
+ m_pFileStream->Seek(STREAM_SEEK_TO_BEGIN);
+}
+// -------------------------------------------------------------------------
+DBG_NAME( OEvoabFolderList );
+OEvoabFolderList::OEvoabFolderList(OEvoabConnection* _pConnection)
+ :m_nFilePos(0)
+ ,m_pFileStream(NULL)
+ ,m_pConnection(_pConnection)
+ ,m_bIsNull(sal_False)
+{
+ DBG_CTOR( OEvoabFolderList, NULL );
+ m_aColumns = new OSQLColumns();
+
+ construct();
+}
+// -----------------------------------------------------------------------------
+void OEvoabFolderList::construct()
+{
+ SvtSysLocale aLocale;
+ ::com::sun::star::lang::Locale aAppLocale(aLocale.GetLocaleDataPtr()->getLocale());
+ Sequence< ::com::sun::star::uno::Any > aArg(1);
+ aArg[0] <<= aAppLocale;
+
+ Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier(m_pConnection->getDriver()->getFactory()->createInstanceWithArguments(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatsSupplier"),aArg),UNO_QUERY);
+ m_xNumberFormatter = Reference< ::com::sun::star::util::XNumberFormatter >(m_pConnection->getDriver()->getFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")),UNO_QUERY);
+ m_xNumberFormatter->attachNumberFormatsSupplier(xSupplier);
+
+ INetURLObject aURL;
+ aURL.SetURL(m_pConnection->getDriver()->getEvoFolderListFileURL());
+
+ String aFileName = aURL.GetMainURL(INetURLObject::NO_DECODE);
+
+ EVO_TRACE_STRING("OJ::construct()::aFileName = %s\n", aFileName );
+ m_pFileStream = createStream_simpleError( aFileName,STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE);
+
+ if(!m_pFileStream)
+ m_pFileStream = createStream_simpleError( aFileName,STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYNONE);
+
+ if(m_pFileStream)
+ {
+ m_pFileStream->Seek(STREAM_SEEK_TO_END);
+ sal_Int32 nSize = m_pFileStream->Tell();
+ m_pFileStream->Seek(STREAM_SEEK_TO_BEGIN);
+
+ // Buffersize abhaengig von der Filegroesse
+ m_pFileStream->SetBufferSize(nSize > 1000000 ? 32768 :
+ nSize > 100000 ? 16384 :
+ nSize > 10000 ? 4096 : 1024);
+ OSL_TRACE("OEvoabFolderList::construct()::m_pFileStream->Tell() = %d\n", nSize );
+
+ fillColumns(aAppLocale);
+ }
+}
+
+
+//------------------------------------------------------------------
+sal_Bool OEvoabFolderList::fetchRow(OValueRow _rRow,const OSQLColumns & _rCols)
+{
+ (_rRow->get())[0] = m_nFilePos; // the "bookmark"
+
+ OEvoabConnection* pConnection = (OEvoabConnection*)m_pConnection;
+ // Felder:
+ xub_StrLen nStartPos = 0;
+ String aStr;
+ OSQLColumns::Vector::const_iterator aIter = _rCols.get().begin();
+ for (sal_Int32 i = 0; aIter != _rCols.get().end();++aIter, ++i)
+ {
+ m_aCurrentLine.GetTokenSpecial(aStr,nStartPos,pConnection->getFieldDelimiter(),pConnection->getStringDelimiter());
+ //OSL_TRACE("OEvoabFolderList::fetchRow()::aStr = %s\n", ((OUtoCStr(::rtl::OUString(aStr))) ? (OUtoCStr(::rtl::OUString(aStr))):("NULL")) );
+
+ if (aStr.Len() == 0)
+ (_rRow->get())[i+1].setNull();
+ else
+ {
+ // length depending on the data type
+ sal_Int32 nType = m_aTypes[i];
+ switch(nType)
+ {
+ case DataType::TIMESTAMP:
+ case DataType::DATE:
+ case DataType::TIME:
+ {
+ double nRes = 0.0;
+ try
+ {
+ nRes = m_xNumberFormatter->convertStringToNumber(::com::sun::star::util::NumberFormat::ALL,aStr);
+ Reference<XPropertySet> xProp(m_xNumberFormatter->getNumberFormatsSupplier()->getNumberFormatSettings(),UNO_QUERY);
+ com::sun::star::util::Date aDate;
+ xProp->getPropertyValue(::rtl::OUString::createFromAscii("NullDate")) >>= aDate;
+
+ switch(nType)
+ {
+ case DataType::DATE:
+ (_rRow->get())[i+1] = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(nRes,aDate));
+ break;
+ case DataType::TIMESTAMP:
+ (_rRow->get())[i+1] = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDateTime(nRes,aDate));
+ break;
+ default:
+ (_rRow->get())[i+1] = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(nRes));
+ }
+ }
+ catch(Exception&)
+ {
+ (_rRow->get())[i+1].setNull();
+ }
+ } break;
+ case DataType::DOUBLE:
+ case DataType::INTEGER:
+ case DataType::DECIMAL: // #99178# OJ
+ case DataType::NUMERIC:
+ {
+ sal_Unicode cDecimalDelimiter = pConnection->getDecimalDelimiter();
+ sal_Unicode cThousandDelimiter = pConnection->getThousandDelimiter();
+ String aStrConverted;
+
+ OSL_ENSURE(cDecimalDelimiter && nType != DataType::INTEGER ||
+ !cDecimalDelimiter && nType == DataType::INTEGER,
+ "FalscherTyp");
+
+ // In Standard-Notation (DezimalPUNKT ohne Tausender-Komma) umwandeln:
+ for (xub_StrLen j = 0; j < aStr.Len(); ++j)
+ {
+ if (cDecimalDelimiter && aStr.GetChar(j) == cDecimalDelimiter)
+ aStrConverted += '.';
+ else if ( aStr.GetChar(j) == '.' ) // special case, if decimal seperator isn't '.' we have to vut the string after it
+ break; // #99189# OJ
+ else if (cThousandDelimiter && aStr.GetChar(j) == cThousandDelimiter)
+ {
+ // weglassen
+ }
+ else
+ aStrConverted += aStr.GetChar(j) ;
+ }
+ double nVal = ::rtl::math::stringToDouble(aStrConverted.GetBuffer(),',','.',NULL,NULL);
+
+ // #99178# OJ
+ if ( DataType::DECIMAL == nType || DataType::NUMERIC == nType )
+ (_rRow->get())[i+1] = String::CreateFromDouble(nVal);
+ else
+ (_rRow->get())[i+1] = nVal;
+ } break;
+
+ default:
+ {
+ // Wert als String in Variable der Row uebernehmen
+ (_rRow->get())[i+1] = aStr;
+ }
+ break;
+ }
+ }
+ }
+ return sal_True;
+}
+
+
+//------------------------------------------------------------------
+sal_Bool OEvoabFolderList::seekRow(IResultSetHelper::Movement eCursorPosition)
+{
+ //OSL_TRACE("OEvoabFolderList::seekRow()::(before SeekRow)m_aCurrentLine = %d\n", ((OUtoCStr(::rtl::OUString(m_aCurrentLine))) ? (OUtoCStr(::rtl::OUString(m_aCurrentLine))):("NULL")) );
+
+ if ( !m_pFileStream )
+ return sal_False;
+ OEvoabConnection* pConnection = (OEvoabConnection*)m_pConnection;
+ // ----------------------------------------------------------
+ // Positionierung vorbereiten:
+ //OSL_TRACE("OEvoabFolderList::seekRow()::(before SeekRow,m_pFileStriam Exist)m_aCurrentLine = %d\n", ((OUtoCStr(::rtl::OUString(m_aCurrentLine))) ? (OUtoCStr(::rtl::OUString(m_aCurrentLine))):("NULL")) );
+
+ switch(eCursorPosition)
+ {
+ case IResultSetHelper::FIRST:
+ m_nFilePos = 0;
+ // run through
+
+ case IResultSetHelper::NEXT:
+ m_pFileStream->Seek(m_nFilePos);
+
+ if (m_pFileStream->IsEof())
+ {
+ OSL_TRACE( "OEvoabFolderList::seekRow: EOF /before/ reading the line." );
+ return sal_False;
+ }
+
+ m_pFileStream->ReadByteStringLine(m_aCurrentLine,pConnection->getTextEncoding());
+ if (m_pFileStream->IsEof())
+ {
+ OSL_TRACE( "OEvoabFolderList::seekRow: EOF /after/ reading the line." );
+ if ( !m_aCurrentLine.Len() )
+ {
+ OSL_TRACE( "OEvoabFolderList::seekRow: empty line read." );
+ return sal_False;
+ }
+ }
+ m_nFilePos = m_pFileStream->Tell();
+ break;
+
+ default:
+ OSL_ENSURE( sal_False, "OEvoabFolderList::seekRow: unsupported positioning!" );
+ break;
+ }
+
+ //OSL_TRACE("OEvoabFolderList::seekRow()::(after SeekRow)m_aCurrentLine = %d\n", ((OUtoCStr(::rtl::OUString(m_aCurrentLine))) ? (OUtoCStr(::rtl::OUString(m_aCurrentLine))):("NULL")) );
+
+ return sal_True;
+}
+// -----------------------------------------------------------------------------
+SvStream* OEvoabFolderList::createStream_simpleError( const String& _rFileName, StreamMode _eOpenMode)
+{
+ utl::UcbLockBytesHandler* p_null_dummy=NULL;
+ SvStream* pReturn = ::utl::UcbStreamHelper::CreateStream( _rFileName, _eOpenMode, p_null_dummy);
+ if (pReturn && (ERRCODE_NONE != pReturn->GetErrorCode()))
+ {
+ delete pReturn;
+ pReturn = NULL;
+ }
+ return pReturn;
+}
+// -----------------------------------------------------------------------------
+const ORowSetValue& OEvoabFolderList::getValue(sal_Int32 _nColumnIndex ) throw(::com::sun::star::sdbc::SQLException)
+{
+ checkIndex( _nColumnIndex );
+
+ m_bIsNull = (m_aRow->get())[_nColumnIndex].isNull();
+ return (m_aRow->get())[_nColumnIndex];
+}
+// -----------------------------------------------------------------------------
+void OEvoabFolderList::checkIndex(sal_Int32 _nColumnIndex ) throw(::com::sun::star::sdbc::SQLException)
+{
+ if ( _nColumnIndex <= 0 || _nColumnIndex >= (sal_Int32)m_aRow->get().size() ) {
+// ::dbtools::throwInvalidIndexException();
+ ;
+ }
+}
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OEvoabFolderList::getString( sal_Int32 _nColumnIndex ) throw(SQLException, RuntimeException)
+{
+ return getValue(_nColumnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL OEvoabFolderList::getInt( sal_Int32 _nColumnIndex ) throw(SQLException, RuntimeException)
+{
+ return getValue( _nColumnIndex );
+}
+// -----------------------------------------------------------------------------
+void OEvoabFolderList::initializeRow(sal_Int32 _nColumnCount)
+{
+ if(!m_aRow.isValid())
+ {
+ m_aRow = new OValueVector(_nColumnCount);
+ (m_aRow->get())[0].setBound(sal_True);
+ ::std::for_each(m_aRow->get().begin()+1,m_aRow->get().end(),TSetBound(sal_False));
+ }
+ //OSL_TRACE("OEvoabFolderList::initializeRow()::_nColumnCount = %d\n", _nColumnCount);
+
+}
+// -------------------------------------------------------------------------
+
+sal_Bool SAL_CALL OEvoabFolderList::first( ) throw(SQLException, RuntimeException)
+{
+ sal_Bool bSuccess = seekRow(IResultSetHelper::FIRST);
+
+ EVO_TRACE_STRING("OEvoabFolderList::first(): returning %s\n", ::rtl::OUString::valueOf(bSuccess) );
+ return bSuccess;
+}
+// -------------------------------------------------------------------------
+
+sal_Bool SAL_CALL OEvoabFolderList::next( ) throw(SQLException, RuntimeException)
+{
+ sal_Bool bSuccess = seekRow(IResultSetHelper::NEXT);
+
+ EVO_TRACE_STRING("OEvoabFolderList::next(): returning %s\n", ::rtl::OUString::valueOf(bSuccess) );
+ return bSuccess;
+}
+// -------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL OEvoabFolderList::getRow( ) throw(SQLException, RuntimeException)
+{
+ sal_Bool bRet = fetchRow(m_aRow,getTableColumns().getBody());
+ EVO_TRACE_STRING("OEvoabFolderList::getRow()::fetchRow() = %s\n", ::rtl::OUString::valueOf(bRet) );
+
+ return bRet;
+}