/**************************************************************
 * 
 * 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
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"



// INCLUDE ---------------------------------------------------------------

#include <stdio.h>
#include <tools/urlobj.hxx>
#include <svl/converter.hxx>
#include <svl/zforlist.hxx>
#include <comphelper/types.hxx>
#include <ucbhelper/content.hxx>
#include <unotools/sharedunocomponent.hxx>
#include <comphelper/processfactory.hxx>
#include <svx/txenctab.hxx>
#include <svx/dbcharsethelper.hxx>

#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/sdbc/DataType.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <com/sun/star/sdbc/XDriver.hpp>
#include <com/sun/star/sdbc/XDriverAccess.hpp>
#include <com/sun/star/sdbc/XDriverManager.hpp>
#include <com/sun/star/sdbc/XResultSetUpdate.hpp>
#include <com/sun/star/sdbc/XRow.hpp>
#include <com/sun/star/sdbc/XRowSet.hpp>
#include <com/sun/star/sdbc/XRowUpdate.hpp>
#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
#include <com/sun/star/sdbcx/XAppend.hpp>
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/ucb/NameClash.hpp>
#include <com/sun/star/ucb/TransferInfo.hpp>
#include <com/sun/star/ucb/XCommandInfo.hpp>

#include "scerrors.hxx"
#include "docsh.hxx"
#include "filter.hxx"
#include "progress.hxx"
#include "collect.hxx"
#include "cell.hxx"
#include "editutil.hxx"
#include "cellform.hxx"
#include "dbdocutl.hxx"
#include "dociter.hxx"
#include "globstr.hrc"

using namespace com::sun::star;

// -----------------------------------------------------------------------

#define SC_SERVICE_ROWSET			"com.sun.star.sdb.RowSet"
#define SC_SERVICE_DRVMAN			"com.sun.star.sdbc.DriverManager"

//!	move to a header file?
//#define SC_DBPROP_DATASOURCENAME	"DataSourceName"
#define SC_DBPROP_ACTIVECONNECTION	"ActiveConnection"
#define SC_DBPROP_COMMAND			"Command"
#define SC_DBPROP_COMMANDTYPE		"CommandType"

#define SC_DBPROP_NAME				"Name"
#define SC_DBPROP_TYPE				"Type"
#define SC_DBPROP_PRECISION			"Precision"
#define SC_DBPROP_SCALE				"Scale"

#define SC_DBPROP_EXTENSION			"Extension"
#define SC_DBPROP_CHARSET			"CharSet"

#define SC_ROWCOUNT_ERROR		(-1)

namespace
{
    sal_uLong lcl_getDBaseConnection(uno::Reference<sdbc::XDriverManager>& _rDrvMgr,uno::Reference<sdbc::XConnection>& _rConnection,String& _rTabName,const String& rFullFileName,rtl_TextEncoding eCharSet)
    {
        INetURLObject aURL;
	    aURL.SetSmartProtocol( INET_PROT_FILE );
	    aURL.SetSmartURL( rFullFileName );
        _rTabName = aURL.getBase( INetURLObject::LAST_SEGMENT, true,
                INetURLObject::DECODE_UNAMBIGUOUS );
	    String aExtension = aURL.getExtension();
	    aURL.removeSegment();
	    aURL.removeFinalSlash();
	    String aPath = aURL.GetMainURL(INetURLObject::NO_DECODE);
        uno::Reference<lang::XMultiServiceFactory> xFactory = comphelper::getProcessServiceFactory();
		if (!xFactory.is()) return SCERR_EXPORT_CONNECT;

		_rDrvMgr.set( xFactory->createInstance(
							rtl::OUString::createFromAscii( SC_SERVICE_DRVMAN ) ),
							uno::UNO_QUERY);
		DBG_ASSERT( _rDrvMgr.is(), "can't get DriverManager" );
		if (!_rDrvMgr.is()) return SCERR_EXPORT_CONNECT;

		// get connection

		String aConnUrl = String::CreateFromAscii("sdbc:dbase:");
		aConnUrl += aPath;

		svxform::ODataAccessCharsetHelper aHelper;
        ::std::vector< rtl_TextEncoding > aEncodings;
        aHelper.getSupportedTextEncodings( aEncodings );
        ::std::vector< rtl_TextEncoding >::iterator aIter = ::std::find(aEncodings.begin(),aEncodings.end(),(rtl_TextEncoding) eCharSet);
        if ( aIter == aEncodings.end() )
        {
            DBG_ERRORFILE( "DBaseImport: dbtools::OCharsetMap doesn't know text encoding" );
            return SCERR_IMPORT_CONNECT;
        } // if ( aIter == aMap.end() )
        rtl::OUString aCharSetStr;
        if ( RTL_TEXTENCODING_DONTKNOW != *aIter )
		{	// it's not the virtual "system charset"
			const char* pIanaName = rtl_getMimeCharsetFromTextEncoding( *aIter );
			OSL_ENSURE( pIanaName, "invalid mime name!" );
			if ( pIanaName )
				aCharSetStr = ::rtl::OUString::createFromAscii( pIanaName );
		}

		uno::Sequence<beans::PropertyValue> aProps(2);
		aProps[0].Name = rtl::OUString::createFromAscii(SC_DBPROP_EXTENSION);
		aProps[0].Value <<= rtl::OUString( aExtension );
		aProps[1].Name = rtl::OUString::createFromAscii(SC_DBPROP_CHARSET);
		aProps[1].Value <<= aCharSetStr;

		_rConnection = _rDrvMgr->getConnectionWithInfo( aConnUrl, aProps );
        return 0L;
    }
}
// -----------------------------------------------------------------------
// MoveFile/KillFile/IsDocument: similar to SfxContentHelper

// static
sal_Bool ScDocShell::MoveFile( const INetURLObject& rSourceObj, const INetURLObject& rDestObj )
{
	sal_Bool bMoveData = sal_True;
	sal_Bool bRet = sal_True, bKillSource = sal_False;
	if ( rSourceObj.GetProtocol() != rDestObj.GetProtocol() )
	{
		bMoveData = sal_False;
		bKillSource = sal_True;
	}
	String aName = rDestObj.getName();
	INetURLObject aDestPathObj = rDestObj;
	aDestPathObj.removeSegment();
	aDestPathObj.setFinalSlash();

	try
	{
		::ucbhelper::Content aDestPath( aDestPathObj.GetMainURL(INetURLObject::NO_DECODE),
							uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
		uno::Reference< ::com::sun::star::ucb::XCommandInfo > xInfo = aDestPath.getCommands();
		rtl::OUString aTransferName = rtl::OUString::createFromAscii( "transfer" );
		if ( xInfo->hasCommandByName( aTransferName ) )
		{
			aDestPath.executeCommand( aTransferName, uno::makeAny(
                ::com::sun::star::ucb::TransferInfo( bMoveData, rSourceObj.GetMainURL(INetURLObject::NO_DECODE), aName,
               										::com::sun::star::ucb::NameClash::ERROR ) ) );
		}
		else
		{
			DBG_ERRORFILE( "transfer command not available" );
		}
	}
	catch( uno::Exception& )
	{
		// ucb may throw different exceptions on failure now
		bRet = sal_False;
	}

	if ( bKillSource )
		KillFile( rSourceObj );

	return bRet;
}


// static
sal_Bool ScDocShell::KillFile( const INetURLObject& rURL )
{
	sal_Bool bRet = sal_True;
	try
	{
		::ucbhelper::Content aCnt( rURL.GetMainURL(INetURLObject::NO_DECODE),
						uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
		aCnt.executeCommand( rtl::OUString::createFromAscii( "delete" ),
								comphelper::makeBoolAny( sal_True ) );
	}
	catch( uno::Exception& )
	{
		// ucb may throw different exceptions on failure now
		bRet = sal_False;
	}

	return bRet;
}

// static
sal_Bool ScDocShell::IsDocument( const INetURLObject& rURL )
{
	sal_Bool bRet = sal_False;
	try
	{
		::ucbhelper::Content aCnt( rURL.GetMainURL(INetURLObject::NO_DECODE),
						uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
		bRet = aCnt.isDocument();
	}
    catch( uno::Exception& )
	{
		// ucb may throw different exceptions on failure now - warning only
		DBG_WARNING( "Any other exception" );
	}

	return bRet;
}

// -----------------------------------------------------------------------

sal_uLong ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet,
								sal_Bool bSimpleColWidth[MAXCOLCOUNT] )
{
	sal_uLong nErr = eERR_OK;
	long i;
    long nColCount = 0;

	try
	{
		String aTabName;
        uno::Reference<sdbc::XDriverManager> xDrvMan;
        uno::Reference<sdbc::XConnection> xConnection;
		sal_uLong nRet = lcl_getDBaseConnection(xDrvMan,xConnection,aTabName,rFullFileName,eCharSet);
        if ( !xConnection.is() || !xDrvMan.is() )
            return nRet;
        ::utl::DisposableComponent aConnectionHelper(xConnection);
		
        ScProgress aProgress( this, ScGlobal::GetRscString( STR_LOAD_DOC ), 0 );
        uno::Reference<lang::XMultiServiceFactory> xFactory = comphelper::getProcessServiceFactory();
		uno::Reference<sdbc::XRowSet> xRowSet( xFactory->createInstance(
							rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ),
							uno::UNO_QUERY);
        ::utl::DisposableComponent aRowSetHelper(xRowSet);
		uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY );
		DBG_ASSERT( xRowProp.is(), "can't get RowSet" );
		if (!xRowProp.is()) return SCERR_IMPORT_CONNECT;

		sal_Int32 nType = sdb::CommandType::TABLE;
		uno::Any aAny;

		aAny <<= xConnection;
		xRowProp->setPropertyValue(
					rtl::OUString::createFromAscii(SC_DBPROP_ACTIVECONNECTION), aAny );

		aAny <<= nType;
		xRowProp->setPropertyValue(
					rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny );

		aAny <<= rtl::OUString( aTabName );
		xRowProp->setPropertyValue(
					rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny );

		xRowSet->execute();

		uno::Reference<sdbc::XResultSetMetaData> xMeta;
		uno::Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp( xRowSet, uno::UNO_QUERY );
		if ( xMetaSupp.is() )
			xMeta = xMetaSupp->getMetaData();
		if ( xMeta.is() )
			nColCount = xMeta->getColumnCount();	// this is the number of real columns

		if ( nColCount > MAXCOL+1 )
		{
			nColCount = MAXCOL+1;
			nErr = SCWARN_IMPORT_RANGE_OVERFLOW;	// warning
		}

		uno::Reference<sdbc::XRow> xRow( xRowSet, uno::UNO_QUERY );
		DBG_ASSERT( xRow.is(), "can't get Row" );
		if (!xRow.is()) return SCERR_IMPORT_CONNECT;

		// currency flag is not needed for dBase
		uno::Sequence<sal_Int32> aColTypes( nColCount );	// column types
		sal_Int32* pTypeArr = aColTypes.getArray();
		for (i=0; i<nColCount; i++)
			pTypeArr[i] = xMeta->getColumnType( i+1 );

		//	read column names
		//!	add type descriptions

        aProgress.SetState( 0 );
        ScColumn::bDoubleAlloc = sal_True;      // row count isn't readily available in advance

		for (i=0; i<nColCount; i++)
		{
			String aHeader = xMeta->getColumnLabel( i+1 );

			switch ( pTypeArr[i] )
			{
				case sdbc::DataType::BIT:
					aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",L" ));
					break;
				case sdbc::DataType::DATE:
					aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",D" ));
					break;
				case sdbc::DataType::LONGVARCHAR:
					aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",M" ));
					break;
				case sdbc::DataType::VARCHAR:
					aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",C," ));
					aHeader += String::CreateFromInt32( xMeta->getColumnDisplaySize( i+1 ) );
					break;
				case sdbc::DataType::DECIMAL:
					{
						long nPrec = xMeta->getPrecision( i+1 );
						long nScale = xMeta->getScale( i+1 );
						aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",N," ));
						aHeader += String::CreateFromInt32(
									SvDbaseConverter::ConvertPrecisionToDbase(
										nPrec, nScale ) );
						aHeader += ',';
						aHeader += String::CreateFromInt32( nScale );
					}
					break;
			}

			aDocument.SetString( static_cast<SCCOL>(i), 0, 0, aHeader );
		}

		SCROW nRow = 1;		// 0 is column titles
		sal_Bool bEnd = sal_False;
		while ( !bEnd && xRowSet->next() )
		{
			if ( nRow <= MAXROW )
			{
				SCCOL nCol = 0;
				for (i=0; i<nColCount; i++)
				{
					ScDatabaseDocUtil::PutData( &aDocument, nCol, nRow, 0,
												xRow, i+1, pTypeArr[i], sal_False,
												&bSimpleColWidth[nCol] );
					++nCol;
				}
				++nRow;
			}
			else		// past the end of the spreadsheet
			{
				bEnd = sal_True;							// don't continue
				nErr = SCWARN_IMPORT_RANGE_OVERFLOW;	// warning message
			}
		}
	}
	catch ( sdbc::SQLException& )
	{
		nErr = SCERR_IMPORT_CONNECT;
	}
	catch ( uno::Exception& )
	{
		DBG_ERROR("Unexpected exception in database");
		nErr = ERRCODE_IO_GENERAL;
	}

    ScColumn::bDoubleAlloc = sal_False;
    if ( nColCount > 0 )
        aDocument.DoColResize( 0, 0, static_cast<SCCOL>(nColCount) - 1, 0 );

	return nErr;
}

// -----------------------------------------------------------------------

inline sal_Bool IsAsciiDigit( sal_Unicode c )
{
	return 0x30 <= c && c <= 0x39;
}

inline sal_Bool IsAsciiAlpha( sal_Unicode c )
{
	return (0x41 <= c && c <= 0x5a) || (0x61 <= c && c <= 0x7a);
}

void lcl_GetColumnTypes( ScDocShell& rDocShell,
							const ScRange& rDataRange, sal_Bool bHasFieldNames,
							rtl::OUString* pColNames, sal_Int32* pColTypes,
							sal_Int32* pColLengths, sal_Int32* pColScales,
							sal_Bool& bHasMemo, CharSet eCharSet )
{
	//	updating of column titles didn't work in 5.2 and isn't always wanted
	//	(saving normally shouldn't modify the document)
	//!	read flag from configuration
	sal_Bool bUpdateTitles = sal_False;

	ScDocument* pDoc = rDocShell.GetDocument();
	SvNumberFormatter* pNumFmt = pDoc->GetFormatTable();

	SCTAB nTab = rDataRange.aStart.Tab();
	SCCOL nFirstCol = rDataRange.aStart.Col();
	SCROW nFirstRow = rDataRange.aStart.Row();
	SCCOL nLastCol = rDataRange.aEnd.Col();
	SCROW nLastRow = rDataRange.aEnd.Row();

	ScStrCollection aFieldNamesCollection;

	long nField = 0;
	SCROW nFirstDataRow = ( bHasFieldNames ? nFirstRow + 1 : nFirstRow );
	for ( SCCOL nCol = nFirstCol; nCol <= nLastCol; nCol++ )
	{
		sal_Bool bTypeDefined = sal_False;
		sal_Bool bPrecDefined = sal_False;
		sal_Int32 nFieldLen = 0;
		sal_Int32 nPrecision = 0;
		sal_Int32 nDbType = sdbc::DataType::SQLNULL;
		String aFieldName, aString;

		// Feldname[,Type[,Width[,Prec]]]
		// Typ etc.: L; D; C[,W]; N[,W[,P]]
		if ( bHasFieldNames )
		{
			pDoc->GetString( nCol, nFirstRow, nTab, aString );
			aString.ToUpperAscii();
			xub_StrLen nToken = aString.GetTokenCount( ',' );
			if ( nToken > 1 )
			{
				aFieldName = aString.GetToken( 0, ',' );
				aString.EraseAllChars( ' ' );
				switch ( aString.GetToken( 1, ',' ).GetChar(0) )
				{
					case 'L' :
						nDbType = sdbc::DataType::BIT;
						nFieldLen = 1;
						bTypeDefined = sal_True;
						bPrecDefined = sal_True;
						break;
					case 'D' :
						nDbType = sdbc::DataType::DATE;
						nFieldLen = 8;
						bTypeDefined = sal_True;
						bPrecDefined = sal_True;
						break;
					case 'M' :
						nDbType = sdbc::DataType::LONGVARCHAR;
						nFieldLen = 10;
						bTypeDefined = sal_True;
						bPrecDefined = sal_True;
						bHasMemo = sal_True;
						break;
					case 'C' :
						nDbType = sdbc::DataType::VARCHAR;
						bTypeDefined = sal_True;
						bPrecDefined = sal_True;
						break;
					case 'N' :
						nDbType = sdbc::DataType::DECIMAL;
						bTypeDefined = sal_True;
						break;
				}
				if ( bTypeDefined && !nFieldLen && nToken > 2 )
				{
					nFieldLen = aString.GetToken( 2, ',' ).ToInt32();
					if ( !bPrecDefined && nToken > 3 )
					{
						String aTmp( aString.GetToken( 3, ',' ) );
						if ( CharClass::isAsciiNumeric(aTmp) )
						{
							nPrecision = aTmp.ToInt32();
							bPrecDefined = sal_True;
						}
					}
				}
			}
			else
				aFieldName = aString;

			// Feldnamen pruefen und ggbf. gueltigen Feldnamen erzeugen.
			// Erstes Zeichen muss Buchstabe sein,
			// weitere nur alphanumerisch und Unterstrich erlaubt,
			// "_DBASELOCK" ist reserviert (obsolet weil erstes Zeichen kein Buchstabe),
			// keine doppelten Namen.
			if ( !IsAsciiAlpha( aFieldName.GetChar(0) ) )
				aFieldName.Insert( 'N', 0 );
			String aTmpStr;
			sal_Unicode c;
            for ( const sal_Unicode* p = aFieldName.GetBuffer(); ( c = *p ) != 0; p++ )
			{
				if ( IsAsciiAlpha( c ) || IsAsciiDigit( c ) || c == '_' )
					aTmpStr += c;
				else
					aTmpStr += '_';
			}
			aFieldName = aTmpStr;
			if ( aFieldName.Len() > 10 )
				aFieldName.Erase( 10 );
			StrData* pStrData = new StrData( aFieldName );
			if ( !aFieldNamesCollection.Insert( pStrData ) )
			{	// doppelter Feldname, numerisch erweitern
				sal_uInt16 nSub = 1;
				String aFixPart( aFieldName );
				do
				{
					++nSub;
					String aVarPart = String::CreateFromInt32( nSub );
					if ( aFixPart.Len() + aVarPart.Len() > 10 )
						aFixPart.Erase( 10 - aVarPart.Len() );
					aFieldName = aFixPart;
					aFieldName += aVarPart;
					pStrData->SetString( aFieldName );
				} while ( !aFieldNamesCollection.Insert( pStrData ) );
			}
		}
		else
		{
			aFieldName = 'N';
			aFieldName += String::CreateFromInt32(nCol+1);
		}

		if ( !bTypeDefined )
		{	// Feldtyp
			ScBaseCell* pCell;
			pDoc->GetCell( nCol, nFirstDataRow, nTab, pCell );
			if ( !pCell || pCell->HasStringData() )
				nDbType = sdbc::DataType::VARCHAR;
			else
			{
				sal_uInt32 nFormat;
				pDoc->GetNumberFormat( nCol, nFirstDataRow, nTab, nFormat );
				if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA
				  && ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0) )
				{
					nFormat = ScGlobal::GetStandardFormat(
						((ScFormulaCell*)pCell)->GetValue(), *pNumFmt, nFormat,
						((ScFormulaCell*)pCell)->GetFormatType() );
				}
				switch ( pNumFmt->GetType( nFormat ) )
				{
					case NUMBERFORMAT_LOGICAL :
						nDbType = sdbc::DataType::BIT;
						nFieldLen = 1;
						break;
					case NUMBERFORMAT_DATE :
						nDbType = sdbc::DataType::DATE;
						nFieldLen = 8;
						break;
					case NUMBERFORMAT_TIME :
					case NUMBERFORMAT_DATETIME :
						nDbType = sdbc::DataType::VARCHAR;
						break;
					default:
						nDbType = sdbc::DataType::DECIMAL;
				}
			}
		}
		sal_Bool bSdbLenAdjusted = sal_False;
		sal_Bool bSdbLenBad = sal_False;
		// Feldlaenge
		if ( nDbType == sdbc::DataType::VARCHAR && !nFieldLen )
		{	// maximale Feldbreite bestimmen
			nFieldLen = pDoc->GetMaxStringLen( nTab, nCol, nFirstDataRow,
				nLastRow, eCharSet );
			if ( nFieldLen == 0 )
				nFieldLen = 1;
		}
        else if ( nDbType == sdbc::DataType::DECIMAL )
        {	// maximale Feldbreite und Nachkommastellen bestimmen
            xub_StrLen nLen;
            sal_uInt16 nPrec;
            nLen = pDoc->GetMaxNumberStringLen( nPrec, nTab, nCol,
                nFirstDataRow, nLastRow );
            // dBaseIII Limit Nachkommastellen: 15
			if ( nPrecision > 15 )
				nPrecision = 15;
			if ( nPrec > 15 )
				nPrec = 15;
			if ( bPrecDefined && nPrecision != nPrec )
			{	// Laenge auf vorgegebene Nachkommastellen anpassen
				if ( nPrecision )
                    nLen = sal::static_int_cast<xub_StrLen>( nLen + ( nPrecision - nPrec ) );
				else
					nLen -= nPrec+1;			// auch den . mit raus
			}
			if ( nLen > nFieldLen && !bTypeDefined )
				nFieldLen = nLen;
			if ( !bPrecDefined )
				nPrecision = nPrec;
			if ( nFieldLen == 0 )
				nFieldLen = 1;
			else if ( nFieldLen > 19 )
				nFieldLen = 19;		// dBaseIII Limit Feldlaenge numerisch: 19
			if ( nPrecision && nFieldLen < nPrecision + 2 )
				nFieldLen = nPrecision + 2;		// 0. muss mit reinpassen
			// 538 MUST: Sdb internal representation adds 2 to the field length!
			// To give the user what he wants we must substract it here.
 			//! CAVEAT! There is no way to define a numeric field with a length
 			//! of 1 and no decimals!
			if ( nFieldLen == 1 && nPrecision == 0 )
				bSdbLenBad = sal_True;
			nFieldLen = SvDbaseConverter::ConvertPrecisionToOdbc( nFieldLen, nPrecision );
			bSdbLenAdjusted = sal_True;
		}
		if ( nFieldLen > 254 )
		{
			if ( nDbType == sdbc::DataType::VARCHAR )
			{	// zu lang fuer normales Textfeld => Memofeld
				nDbType = sdbc::DataType::LONGVARCHAR;
				nFieldLen = 10;
				bHasMemo = sal_True;
			}
			else
				nFieldLen = 254;					// dumm gelaufen..
		}

		pColNames[nField] = aFieldName;
		pColTypes[nField] = nDbType;
		pColLengths[nField] = nFieldLen;
		pColScales[nField] = nPrecision;

		// undo change to field length, reflect reality
		if ( bSdbLenAdjusted )
		{
			nFieldLen = SvDbaseConverter::ConvertPrecisionToDbase( nFieldLen, nPrecision );
			if ( bSdbLenBad && nFieldLen == 1 )
				nFieldLen = 2;		// THIS is reality
		}
		if ( bUpdateTitles )
		{	// Angabe anpassen und ausgeben
			String aOutString = aFieldName;
			switch ( nDbType )
			{
				case sdbc::DataType::BIT :
					aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",L" ));
					break;
				case sdbc::DataType::DATE :
					aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",D" ));
					break;
				case sdbc::DataType::LONGVARCHAR :
					aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",M" ));
					break;
				case sdbc::DataType::VARCHAR :
					aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",C," ));
					aOutString += String::CreateFromInt32( nFieldLen );
					break;
				case sdbc::DataType::DECIMAL :
					aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",N," ));
					aOutString += String::CreateFromInt32( nFieldLen );
					aOutString += ',';
					aOutString += String::CreateFromInt32( nPrecision );
					break;
			}
			if ( !aOutString.EqualsIgnoreCaseAscii( aString ) )
			{
				pDoc->SetString( nCol, nFirstRow, nTab, aOutString );
				rDocShell.PostPaint( nCol, nFirstRow, nTab, nCol, nFirstRow, nTab, PAINT_GRID );
			}
		}
		++nField;
	}
}


inline void lcl_getLongVarCharEditString( String& rString,
        const ScBaseCell* pCell, ScFieldEditEngine& rEditEngine )
{
    rEditEngine.SetText( *((const ScEditCell*)pCell)->GetData() );
    rString = rEditEngine.GetText( LINEEND_CRLF );
}

inline void lcl_getLongVarCharString( String& rString, ScBaseCell* pCell,
        ScDocument& rDocument, SCCOL nCol, SCROW nRow, SCTAB nTab,
        SvNumberFormatter& rNumFmt )
{
    sal_uInt32 nFormat;
    Color* pColor;
    rDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
    ScCellFormat::GetString( pCell, nFormat, rString, &pColor, rNumFmt );
}


sal_uLong ScDocShell::DBaseExport( const String& rFullFileName, CharSet eCharSet, sal_Bool& bHasMemo )
{
	// remove the file so the dBase driver doesn't find an invalid file
	INetURLObject aDeleteObj( rFullFileName, INET_PROT_FILE );
	KillFile( aDeleteObj );

	sal_uLong nErr = eERR_OK;
	uno::Any aAny;

	SCCOL nFirstCol, nLastCol;
	SCROW  nFirstRow, nLastRow;
	SCTAB nTab = GetSaveTab();
	aDocument.GetDataStart( nTab, nFirstCol, nFirstRow );
	aDocument.GetCellArea( nTab, nLastCol, nLastRow );
    if ( nFirstCol > nLastCol )
        nFirstCol = nLastCol;
    if ( nFirstRow > nLastRow )
        nFirstRow = nLastRow;
	ScProgress aProgress( this, ScGlobal::GetRscString( STR_SAVE_DOC ),
													nLastRow - nFirstRow );
	SvNumberFormatter* pNumFmt = aDocument.GetFormatTable();

	sal_Bool bHasFieldNames = sal_True;
	for ( SCCOL nDocCol = nFirstCol; nDocCol <= nLastCol && bHasFieldNames; nDocCol++ )
	{	// nur Strings in erster Zeile => sind Feldnamen
		if ( !aDocument.HasStringData( nDocCol, nFirstRow, nTab ) )
			bHasFieldNames = sal_False;
	}

	long nColCount = nLastCol - nFirstCol + 1;
	uno::Sequence<rtl::OUString> aColNames( nColCount );
	uno::Sequence<sal_Int32> aColTypes( nColCount );
	uno::Sequence<sal_Int32> aColLengths( nColCount );
	uno::Sequence<sal_Int32> aColScales( nColCount );

	ScRange aDataRange( nFirstCol, nFirstRow, nTab, nLastCol, nLastRow, nTab );
	lcl_GetColumnTypes( *this, aDataRange, bHasFieldNames,
						aColNames.getArray(), aColTypes.getArray(),
						aColLengths.getArray(), aColScales.getArray(),
						bHasMemo, eCharSet );
    // also needed for exception catch
    SCROW nDocRow = 0;
    ScFieldEditEngine aEditEngine( aDocument.GetEditPool() );
    String aString;
    String aTabName;

	try
	{
        uno::Reference<sdbc::XDriverManager> xDrvMan;
        uno::Reference<sdbc::XConnection> xConnection;
		sal_uLong nRet = lcl_getDBaseConnection(xDrvMan,xConnection,aTabName,rFullFileName,eCharSet);
        if ( !xConnection.is() || !xDrvMan.is() )
            return nRet;
        ::utl::DisposableComponent aConnectionHelper(xConnection);

		// get dBase driver
        uno::Reference< sdbc::XDriverAccess> xAccess(xDrvMan,uno::UNO_QUERY);
        uno::Reference< sdbcx::XDataDefinitionSupplier > xDDSup( xAccess->getDriverByURL( xConnection->getMetaData()->getURL() ), uno::UNO_QUERY );
		if ( !xDDSup.is() ) 
            return SCERR_EXPORT_CONNECT;

		// create table
		uno::Reference<sdbcx::XTablesSupplier> xTablesSupp =xDDSup->getDataDefinitionByConnection( xConnection );
		DBG_ASSERT( xTablesSupp.is(), "can't get Data Definition" );
		if (!xTablesSupp.is()) return SCERR_EXPORT_CONNECT;

		uno::Reference<container::XNameAccess> xTables = xTablesSupp->getTables();
		DBG_ASSERT( xTables.is(), "can't get Tables" );
		if (!xTables.is()) return SCERR_EXPORT_CONNECT;

		uno::Reference<sdbcx::XDataDescriptorFactory> xTablesFact( xTables, uno::UNO_QUERY );
		DBG_ASSERT( xTablesFact.is(), "can't get tables factory" );
		if (!xTablesFact.is()) return SCERR_EXPORT_CONNECT;

		uno::Reference<sdbcx::XAppend> xTablesAppend( xTables, uno::UNO_QUERY );
		DBG_ASSERT( xTablesAppend.is(), "can't get tables XAppend" );
		if (!xTablesAppend.is()) return SCERR_EXPORT_CONNECT;

		uno::Reference<beans::XPropertySet> xTableDesc = xTablesFact->createDataDescriptor();
		DBG_ASSERT( xTableDesc.is(), "can't get table descriptor" );
		if (!xTableDesc.is()) return SCERR_EXPORT_CONNECT;

		aAny <<= rtl::OUString( aTabName );
		xTableDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_NAME), aAny );

		// create columns

		uno::Reference<sdbcx::XColumnsSupplier> xColumnsSupp( xTableDesc, uno::UNO_QUERY );
		DBG_ASSERT( xColumnsSupp.is(), "can't get columns supplier" );
		if (!xColumnsSupp.is()) return SCERR_EXPORT_CONNECT;

		uno::Reference<container::XNameAccess> xColumns = xColumnsSupp->getColumns();
		DBG_ASSERT( xColumns.is(), "can't get columns" );
		if (!xColumns.is()) return SCERR_EXPORT_CONNECT;

		uno::Reference<sdbcx::XDataDescriptorFactory> xColumnsFact( xColumns, uno::UNO_QUERY );
		DBG_ASSERT( xColumnsFact.is(), "can't get columns factory" );
		if (!xColumnsFact.is()) return SCERR_EXPORT_CONNECT;

		uno::Reference<sdbcx::XAppend> xColumnsAppend( xColumns, uno::UNO_QUERY );
		DBG_ASSERT( xColumnsAppend.is(), "can't get columns XAppend" );
		if (!xColumnsAppend.is()) return SCERR_EXPORT_CONNECT;

		const rtl::OUString* pColNames = aColNames.getConstArray();
		const sal_Int32* pColTypes     = aColTypes.getConstArray();
		const sal_Int32* pColLengths   = aColLengths.getConstArray();
		const sal_Int32* pColScales    = aColScales.getConstArray();
		long nCol;

		for (nCol=0; nCol<nColCount; nCol++)
		{
			uno::Reference<beans::XPropertySet> xColumnDesc = xColumnsFact->createDataDescriptor();
			DBG_ASSERT( xColumnDesc.is(), "can't get column descriptor" );
			if (!xColumnDesc.is()) return SCERR_EXPORT_CONNECT;

			aAny <<= pColNames[nCol];
			xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_NAME), aAny );

			aAny <<= pColTypes[nCol];
			xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_TYPE), aAny );

			aAny <<= pColLengths[nCol];
			xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_PRECISION), aAny );

			aAny <<= pColScales[nCol];
			xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_SCALE), aAny );

			xColumnsAppend->appendByDescriptor( xColumnDesc );
		}

		xTablesAppend->appendByDescriptor( xTableDesc );

		// re-open connection
//		xConnection = xDrvMan->getConnectionWithInfo( aConnUrl, aProps );
//		DBG_ASSERT( xConnection.is(), "can't get Connection" );
//		if (!xConnection.is()) return SCERR_EXPORT_CONNECT;

		// get row set for writing
        uno::Reference<lang::XMultiServiceFactory> xFactory = comphelper::getProcessServiceFactory();
		uno::Reference<sdbc::XRowSet> xRowSet( xFactory->createInstance(
							rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ),
							uno::UNO_QUERY);
        ::utl::DisposableComponent aRowSetHelper(xRowSet);
		uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY );
		DBG_ASSERT( xRowProp.is(), "can't get RowSet" );
		if (!xRowProp.is()) return SCERR_EXPORT_CONNECT;

		aAny <<= xConnection;
		xRowProp->setPropertyValue(
					rtl::OUString::createFromAscii(SC_DBPROP_ACTIVECONNECTION), aAny );

		aAny <<= (sal_Int32) sdb::CommandType::TABLE;
		xRowProp->setPropertyValue(
					rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny );

		aAny <<= rtl::OUString( aTabName );
		xRowProp->setPropertyValue(
					rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny );

		xRowSet->execute();

		// write data rows

		uno::Reference<sdbc::XResultSetUpdate> xResultUpdate( xRowSet, uno::UNO_QUERY );
		DBG_ASSERT( xResultUpdate.is(), "can't get XResultSetUpdate" );
		if (!xResultUpdate.is()) return SCERR_EXPORT_CONNECT;

		uno::Reference<sdbc::XRowUpdate> xRowUpdate( xRowSet, uno::UNO_QUERY );
		DBG_ASSERT( xRowUpdate.is(), "can't get XRowUpdate" );
		if (!xRowUpdate.is()) return SCERR_EXPORT_CONNECT;

		SCROW nFirstDataRow = ( bHasFieldNames ? nFirstRow + 1 : nFirstRow );
		double fVal;

		for ( nDocRow = nFirstDataRow; nDocRow <= nLastRow; nDocRow++ )
		{
			xResultUpdate->moveToInsertRow();

			for (nCol=0; nCol<nColCount; nCol++)
			{
                SCCOL nDocCol = sal::static_int_cast<SCCOL>( nFirstCol + nCol );

				switch (pColTypes[nCol])
				{
					case sdbc::DataType::LONGVARCHAR:
						{
							ScBaseCell* pCell;
							aDocument.GetCell( nDocCol, nDocRow, nTab, pCell );
							if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
							{
								if ( pCell->GetCellType() == CELLTYPE_EDIT )
								{	// #60761# Paragraphs erhalten
                                    lcl_getLongVarCharEditString( aString,
                                            pCell, aEditEngine);
								}
								else
								{
                                    lcl_getLongVarCharString( aString, pCell,
                                            aDocument, nDocCol, nDocRow, nTab,
                                            *pNumFmt);
								}
								xRowUpdate->updateString( nCol+1, aString );
							}
							else
								xRowUpdate->updateNull( nCol+1 );
						}
						break;

					case sdbc::DataType::VARCHAR:
						aDocument.GetString( nDocCol, nDocRow, nTab, aString );
						xRowUpdate->updateString( nCol+1, aString );
						if ( nErr == eERR_OK && pColLengths[nCol] < aString.Len() )
							nErr = SCWARN_EXPORT_DATALOST;
						break;

					case sdbc::DataType::DATE:
						{
							aDocument.GetValue( nDocCol, nDocRow, nTab, fVal );
							// #39274# zwischen 0 Wert und 0 kein Wert unterscheiden
							sal_Bool bIsNull = (fVal == 0.0);
							if ( bIsNull )
								bIsNull = !aDocument.HasValueData( nDocCol, nDocRow, nTab );
							if ( bIsNull )
							{
								xRowUpdate->updateNull( nCol+1 );
								if ( nErr == eERR_OK &&
										aDocument.HasStringData( nDocCol, nDocRow, nTab ) )
									nErr = SCWARN_EXPORT_DATALOST;
							}
							else
							{
								Date aDate = *(pNumFmt->GetNullDate());		// tools date
								aDate += (long)fVal;						//! approxfloor?
								util::Date aUnoDate( aDate.GetDay(), aDate.GetMonth(), aDate.GetYear() );
								xRowUpdate->updateDate( nCol+1, aUnoDate );
							}
						}
						break;

					case sdbc::DataType::DECIMAL:
					case sdbc::DataType::BIT:
						aDocument.GetValue( nDocCol, nDocRow, nTab, fVal );
						if ( fVal == 0.0 && nErr == eERR_OK &&
											aDocument.HasStringData( nDocCol, nDocRow, nTab ) )
							nErr = SCWARN_EXPORT_DATALOST;
						if ( pColTypes[nCol] == sdbc::DataType::BIT )
							xRowUpdate->updateBoolean( nCol+1, ( fVal != 0.0 ) );
						else
							xRowUpdate->updateDouble( nCol+1, fVal );
						break;

					default:
						DBG_ERROR( "ScDocShell::DBaseExport: unknown FieldType" );
						if ( nErr == eERR_OK )
							nErr = SCWARN_EXPORT_DATALOST;
						aDocument.GetValue( nDocCol, nDocRow, nTab, fVal );
						xRowUpdate->updateDouble( nCol+1, fVal );
				}
			}

			xResultUpdate->insertRow();

			//!	error handling and recovery of old
			//!	ScDocShell::SbaSdbExport is still missing!

			if ( !aProgress.SetStateOnPercent( nDocRow - nFirstRow ) )
			{	// UserBreak
				nErr = SCERR_EXPORT_DATA;
				break;
			}
		}

		comphelper::disposeComponent( xRowSet );
		comphelper::disposeComponent( xConnection );
	}
	catch ( sdbc::SQLException& aException )
	{
        sal_Int32 nError = aException.ErrorCode;
#if OSL_DEBUG_LEVEL > 1
        fprintf( stderr, "ScDocShell::DBaseExport: SQLException ErrorCode: %d, SQLState: %s, Message: %s\n",
                (int)nError, OUStringToOString( aException.SQLState,
                    RTL_TEXTENCODING_UTF8).getStr(), OUStringToOString(
                        aException.Message, RTL_TEXTENCODING_UTF8).getStr());
#endif
        if (nError == 22018 || nError == 22001)
        {
            // SQL error 22018: Character not in target encoding.
            // SQL error 22001: String length exceeds field width (after encoding).
            bool bEncErr = (nError == 22018);
            bool bIsOctetTextEncoding = rtl_isOctetTextEncoding( eCharSet);
            DBG_ASSERT( !bEncErr || bIsOctetTextEncoding, "ScDocShell::DBaseExport: encoding error and not an octect textencoding");
            SCCOL nDocCol = nFirstCol;
            const sal_Int32* pColTypes = aColTypes.getConstArray();
            const sal_Int32* pColLengths = aColLengths.getConstArray();
            ScHorizontalCellIterator aIter( &aDocument, nTab, nFirstCol,
                    nDocRow, nLastCol, nDocRow);
            ScBaseCell* pCell = NULL;
            bool bTest = true;
            while (bTest && ((pCell = aIter.GetNext( nDocCol, nDocRow)) != NULL))
            {
                SCCOL nCol = nDocCol - nFirstCol;
                switch (pColTypes[nCol])
                {
                    case sdbc::DataType::LONGVARCHAR:
                        {
                            if ( pCell->GetCellType() != CELLTYPE_NOTE )
                            {
                                if ( pCell->GetCellType() == CELLTYPE_EDIT )
                                    lcl_getLongVarCharEditString( aString,
                                            pCell, aEditEngine);
                                else
                                    lcl_getLongVarCharString( aString,
                                            pCell, aDocument, nDocCol,
                                            nDocRow, nTab, *pNumFmt);
                            }
                        }
                        break;

                    case sdbc::DataType::VARCHAR:
                        aDocument.GetString( nDocCol, nDocRow, nTab, aString);
                        break;

                    // NOTE: length of DECIMAL fields doesn't need to be
                    // checked here, the database driver adjusts the field
                    // width accordingly.

                    default:
                        bTest = false;
                }
                if (bTest)
                {
                    sal_Int32 nLen;
                    if (bIsOctetTextEncoding)
                    {
                        rtl::OUString aOUString( aString);
                        rtl::OString aOString;
                        if (!aOUString.convertToString( &aOString, eCharSet,
                                    RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
                                    RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
                        {
                            bTest = false;
                            bEncErr = true;
                        }
                        nLen = aOString.getLength();
#if OSL_DEBUG_LEVEL > 1
                        if (!bTest)
                            fprintf( stderr, "ScDocShell::DBaseExport encoding error, string with default replacements: ``%s''\n",
                                    OUStringToOString( aOUString, eCharSet).getStr());
#endif
                    }
                    else
                        nLen = aString.Len() * sizeof(sal_Unicode);
                    if (!bEncErr &&
                            pColTypes[nCol] != sdbc::DataType::LONGVARCHAR &&
                            pColLengths[nCol] < nLen)
                    {
                        bTest = false;
#if OSL_DEBUG_LEVEL > 1
                        fprintf( stderr, "ScDocShell::DBaseExport: field width: %d, encoded length: %d\n",
                                (int)pColLengths[nCol], (int)nLen);
#endif
                    }
                }
                else
                    bTest = true;
            }
            String sPosition( ScAddress( nDocCol, nDocRow, nTab).GetColRowString());
            String sEncoding( SvxTextEncodingTable().GetTextString( eCharSet));
            nErr = *new TwoStringErrorInfo( (bEncErr ? SCERR_EXPORT_ENCODING :
                        SCERR_EXPORT_FIELDWIDTH), sPosition, sEncoding,
                    ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR);
        }
        else if ( aException.Message.getLength() )
            nErr = *new StringErrorInfo( (SCERR_EXPORT_SQLEXCEPTION), aException.Message, ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR);
        else
            nErr = SCERR_EXPORT_DATA;
	}
	catch ( uno::Exception& )
	{
		DBG_ERROR("Unexpected exception in database");
		nErr = ERRCODE_IO_GENERAL;
	}

	return nErr;
}


