2000-09-18 15:18:56 +00:00
|
|
|
|
/*************************************************************************
|
|
|
|
|
*
|
|
|
|
|
* $RCSfile: DTable.cxx,v $
|
|
|
|
|
*
|
2000-11-17 06:37:01 +00:00
|
|
|
|
* $Revision: 1.19 $
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2000-11-17 06:37:01 +00:00
|
|
|
|
* last change: $Author: oj $ $Date: 2000-11-17 07:37:01 $
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
|
|
|
|
* The Contents of this file are made available subject to the terms of
|
|
|
|
|
* either of the following licenses
|
|
|
|
|
*
|
|
|
|
|
* - GNU Lesser General Public License Version 2.1
|
|
|
|
|
* - Sun Industry Standards Source License Version 1.1
|
|
|
|
|
*
|
|
|
|
|
* Sun Microsystems Inc., October, 2000
|
|
|
|
|
*
|
|
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
|
* =============================================
|
|
|
|
|
* Copyright 2000 by Sun Microsystems, Inc.
|
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
|
|
|
*
|
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
|
|
|
*
|
|
|
|
|
* This library 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 for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
|
* MA 02111-1307 USA
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* Sun Industry Standards Source License Version 1.1
|
|
|
|
|
* =================================================
|
|
|
|
|
* The contents of this file are subject to the Sun Industry Standards
|
|
|
|
|
* Source License Version 1.1 (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.openoffice.org/license.html.
|
|
|
|
|
*
|
|
|
|
|
* Software provided under this License is provided on an "AS IS" basis,
|
2000-09-20 05:52:26 +00:00
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
|
2000-09-18 15:18:56 +00:00
|
|
|
|
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
|
|
|
|
|
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
|
|
|
|
|
* See the License for the specific provisions governing your rights and
|
|
|
|
|
* obligations concerning the Software.
|
|
|
|
|
*
|
|
|
|
|
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
|
|
|
|
|
*
|
|
|
|
|
* Copyright: 2000 by Sun Microsystems, Inc.
|
|
|
|
|
*
|
|
|
|
|
* All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s): _______________________________________
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
|
|
#ifndef _CONNECTIVITY_DBASE_TABLE_HXX_
|
|
|
|
|
#include "dbase/DTable.hxx"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
|
|
|
|
|
#include <com/sun/star/sdbc/ColumnValue.hpp>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
|
|
|
|
|
#include <com/sun/star/sdbc/DataType.hpp>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _COM_SUN_STAR_UCB_XCONTENTACCESS_HPP_
|
|
|
|
|
#include <com/sun/star/ucb/XContentAccess.hpp>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _COM_SUN_STAR_SQLC_XROW_HPP_
|
|
|
|
|
#include <com/sun/star/sdbc/XRow.hpp>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _SV_CONVERTER_HXX_
|
|
|
|
|
#include <svtools/converter.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _CONNECTIVITY_DBASE_DCONNECTION_HXX_
|
|
|
|
|
#include "dbase/DConnection.hxx"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _CONNECTIVITY_DBASE_COLUMNS_HXX_
|
|
|
|
|
#include "dbase/DColumns.hxx"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _OSL_THREAD_H_
|
|
|
|
|
#include <osl/thread.h>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _CONFIG_HXX //autogen
|
|
|
|
|
#include <vcl/config.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _CONNECTIVITY_DBASE_INDEX_HXX_
|
|
|
|
|
#include "dbase/DIndex.hxx"
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _CONNECTIVITY_DBASE_INDEXES_HXX_
|
|
|
|
|
#include "dbase/DIndexes.hxx"
|
|
|
|
|
#endif
|
2000-10-09 11:34:19 +00:00
|
|
|
|
#ifndef _COMPHELPER_SEQUENCE_HXX_
|
|
|
|
|
#include <comphelper/sequence.hxx>
|
2000-09-18 15:18:56 +00:00
|
|
|
|
#endif
|
|
|
|
|
#ifndef _CONNECTIVITY_DATECONVERSION_HXX_
|
2000-09-29 14:30:09 +00:00
|
|
|
|
#include "connectivity/DateConversion.hxx"
|
2000-09-18 15:18:56 +00:00
|
|
|
|
#endif
|
|
|
|
|
#ifndef _INTN_HXX //autogen
|
|
|
|
|
#include <tools/intn.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _ZFORLIST_HXX //autogen
|
|
|
|
|
#include <svtools/zforlist.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _SOLMATH_HXX //autogen wg. SolarMath
|
|
|
|
|
#include <tools/solmath.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#include <stdio.h> //sprintf
|
|
|
|
|
#ifndef _UCBHELPER_CONTENT_HXX
|
|
|
|
|
#include <ucbhelper/content.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _CPPUHELPER_EXTRACT_HXX_
|
|
|
|
|
#include <cppuhelper/extract.hxx>
|
|
|
|
|
#endif
|
2000-10-24 15:14:04 +00:00
|
|
|
|
#define CONNECTIVITY_PROPERTY_NAME_SPACE dbase
|
|
|
|
|
#ifndef _CONNECTIVITY_PROPERTYIDS_HXX_
|
|
|
|
|
#include "propertyids.hxx"
|
|
|
|
|
#endif
|
2000-11-16 09:47:23 +00:00
|
|
|
|
#ifndef _UNTOOLS_UCBSTREAMHELPER_HXX
|
|
|
|
|
#include <unotools/ucbstreamhelper.hxx>
|
|
|
|
|
#endif
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
using namespace connectivity;
|
|
|
|
|
using namespace connectivity::dbase;
|
|
|
|
|
using namespace connectivity::file;
|
|
|
|
|
using namespace ucb;
|
|
|
|
|
using namespace cppu;
|
|
|
|
|
using namespace ::com::sun::star::uno;
|
|
|
|
|
using namespace ::com::sun::star::ucb;
|
|
|
|
|
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 ODbaseTable::readHeader()
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->RefreshBuffer(); // sicherstellen, dass die Kopfinformationen tatsaechlich neu gelesen werden
|
|
|
|
|
m_pFileStream->Seek(STREAM_SEEK_TO_BEGIN);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
BYTE aTyp;
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pFileStream) >> aTyp;
|
|
|
|
|
m_pFileStream->Read((char*)m_aHeader.db_aedat, 3*sizeof(BYTE));
|
|
|
|
|
(*m_pFileStream) >> m_aHeader.db_anz;
|
|
|
|
|
(*m_pFileStream) >> m_aHeader.db_kopf;
|
|
|
|
|
(*m_pFileStream) >> m_aHeader.db_slng;
|
|
|
|
|
m_pFileStream->Read((char*)m_aHeader.db_frei, 20*sizeof(BYTE));
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
if (m_aHeader.db_anz < 0 ||
|
|
|
|
|
m_aHeader.db_kopf <= 0 ||
|
|
|
|
|
m_aHeader.db_slng <= 0 ||
|
|
|
|
|
((m_aHeader.db_kopf - 1) / 32 - 1) <= 0) // anzahl felder
|
|
|
|
|
{
|
|
|
|
|
// Dies ist keine DBase Datei
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Konsistenzpruefung des Header:
|
|
|
|
|
m_aHeader.db_typ = (DBFType)aTyp;
|
|
|
|
|
switch (m_aHeader.db_typ)
|
|
|
|
|
{
|
|
|
|
|
case dBaseIII:
|
|
|
|
|
case dBaseIV:
|
|
|
|
|
case dBaseV:
|
|
|
|
|
case dBaseFS:
|
|
|
|
|
case dBaseFSMemo:
|
|
|
|
|
case dBaseIVMemoSQL:
|
|
|
|
|
case dBaseIIIMemo:
|
|
|
|
|
case dBaseIVMemo:
|
|
|
|
|
case FoxProMemo:
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
{ // Dies ist keine DBase Datei
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
void ODbaseTable::fillColumns()
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->Seek(STREAM_SEEK_TO_BEGIN);
|
|
|
|
|
m_pFileStream->Seek(32L);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Anzahl Felder:
|
|
|
|
|
sal_uInt32 nFieldCount = (m_aHeader.db_kopf - 1) / 32 - 1;
|
|
|
|
|
|
|
|
|
|
String aStrFieldName;aStrFieldName.AssignAscii("Column");
|
|
|
|
|
sal_Int32 nFieldCnt = 0;
|
|
|
|
|
::rtl::OUString aTypeName;
|
|
|
|
|
|
|
|
|
|
for (sal_uInt32 i = 0; i < nFieldCount; i++)
|
|
|
|
|
{
|
|
|
|
|
DBFColumn aDBFColumn;
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->Read((char*)&aDBFColumn, sizeof(aDBFColumn));
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Info auslesen und in SdbColumn packen:
|
2000-09-29 14:30:09 +00:00
|
|
|
|
String aColumnName((const char *)aDBFColumn.db_fnm,getConnection()->getTextEncoding());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// while (aOriginalColumns->ColumnNumber(aColumnName) != SDB_COLUMN_NOTFOUND)
|
|
|
|
|
// (aColumnName = aStrFieldName) += String::CreateFromsal_Int32(++nFieldCnt);
|
|
|
|
|
|
|
|
|
|
sal_Int32 nPrecision = aDBFColumn.db_flng;
|
|
|
|
|
sal_Int32 eType;
|
|
|
|
|
|
|
|
|
|
switch (aDBFColumn.db_typ)
|
|
|
|
|
{
|
|
|
|
|
case 'C':
|
|
|
|
|
eType = DataType::VARCHAR;
|
|
|
|
|
aTypeName = ::rtl::OUString::createFromAscii("VARCHAR");
|
|
|
|
|
break;
|
|
|
|
|
case 'F':
|
|
|
|
|
case 'N':
|
|
|
|
|
eType = DataType::DECIMAL;
|
|
|
|
|
aTypeName = ::rtl::OUString::createFromAscii("DECIMAL");
|
|
|
|
|
|
|
|
|
|
// Bei numerischen Feldern werden zwei Zeichen mehr geschrieben, als die Precision der Spaltenbeschreibung eigentlich
|
|
|
|
|
// angibt, um Platz fuer das eventuelle Vorzeichen und das Komma zu haben. Das muss ich jetzt aber wieder rausrechnen.
|
|
|
|
|
nPrecision = SvDbaseConverter::ConvertPrecisionToOdbc(nPrecision,aDBFColumn.db_dez);
|
|
|
|
|
// leider gilt das eben Gesagte nicht fuer aeltere Versionen ....
|
|
|
|
|
;
|
|
|
|
|
break;
|
|
|
|
|
case 'L':
|
|
|
|
|
eType = DataType::BIT;
|
|
|
|
|
aTypeName = ::rtl::OUString::createFromAscii("BIT");
|
|
|
|
|
break;
|
|
|
|
|
case 'D':
|
|
|
|
|
eType = DataType::DATE;
|
|
|
|
|
aTypeName = ::rtl::OUString::createFromAscii("DATE");
|
|
|
|
|
break;
|
|
|
|
|
case 'M':
|
|
|
|
|
eType = DataType::LONGVARCHAR;
|
|
|
|
|
aTypeName = ::rtl::OUString::createFromAscii("LONGVARCHAR");
|
|
|
|
|
nPrecision = 0;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
aTypeName = ::rtl::OUString::createFromAscii("OTHER");
|
|
|
|
|
eType = DataType::OTHER;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sal_Int32 nFlags = 0;
|
|
|
|
|
switch (aDBFColumn.db_typ)
|
|
|
|
|
{
|
|
|
|
|
case 'C':
|
|
|
|
|
case 'D':
|
|
|
|
|
case 'L': nFlags = ColumnSearch::FULL; break;
|
|
|
|
|
case 'F':
|
|
|
|
|
case 'N': nFlags = ColumnSearch::BASIC; break;
|
|
|
|
|
case 'M': nFlags = ColumnSearch::CHAR; break;
|
|
|
|
|
default:
|
|
|
|
|
nFlags = ColumnSearch::NONE;
|
|
|
|
|
|
|
|
|
|
}
|
2000-10-05 13:40:11 +00:00
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
sdbcx::OColumn* pColumn = new sdbcx::OColumn(aColumnName,aTypeName,::rtl::OUString(),
|
|
|
|
|
ColumnValue::NULLABLE,nPrecision,aDBFColumn.db_dez,eType,sal_False,sal_False,sal_False,
|
|
|
|
|
getConnection()->getMetaData()->storesMixedCaseQuotedIdentifiers());
|
2000-10-30 07:07:33 +00:00
|
|
|
|
Reference< XPropertySet> xCol = pColumn;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
m_aColumns->push_back(xCol);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
ODbaseTable::ODbaseTable(ODbaseConnection* _pConnection) : ODbaseTable_BASE(_pConnection)
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
// initialize the header
|
|
|
|
|
m_aHeader.db_typ = dBaseIII;
|
|
|
|
|
m_aHeader.db_anz = 0;
|
|
|
|
|
m_aHeader.db_kopf = 0;
|
|
|
|
|
m_aHeader.db_slng = 0;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
ODbaseTable::ODbaseTable(ODbaseConnection* _pConnection,
|
|
|
|
|
const ::rtl::OUString& _Name,
|
|
|
|
|
const ::rtl::OUString& _Type,
|
|
|
|
|
const ::rtl::OUString& _Description ,
|
|
|
|
|
const ::rtl::OUString& _SchemaName,
|
|
|
|
|
const ::rtl::OUString& _CatalogName
|
|
|
|
|
) : ODbaseTable_BASE(_pConnection,_Name,
|
|
|
|
|
_Type,
|
|
|
|
|
_Description,
|
|
|
|
|
_SchemaName,
|
|
|
|
|
_CatalogName)
|
2000-11-17 06:37:01 +00:00
|
|
|
|
,m_pMemoStream(NULL)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
// initialize the header
|
|
|
|
|
m_aHeader.db_typ = dBaseIII;
|
|
|
|
|
m_aHeader.db_anz = 0;
|
|
|
|
|
m_aHeader.db_kopf = 0;
|
|
|
|
|
m_aHeader.db_slng = 0;
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
INetURLObject aURL;
|
2000-11-16 09:47:23 +00:00
|
|
|
|
aURL.SetURL(getEntry());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
if(aURL.getExtension() != m_pConnection->getExtension())
|
|
|
|
|
aURL.setExtension(m_pConnection->getExtension());
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
// Content aContent(aURL.GetURLNoPass());
|
|
|
|
|
String aFileName(getEntry());
|
|
|
|
|
|
|
|
|
|
m_pFileStream = ::utl::UcbStreamHelper::CreateStream( aFileName,STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
if(!m_pFileStream)
|
|
|
|
|
m_pFileStream = ::utl::UcbStreamHelper::CreateStream( aFileName,STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYNONE );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
if(m_pFileStream)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
readHeader();
|
|
|
|
|
|
|
|
|
|
if (HasMemoFields())
|
|
|
|
|
{
|
|
|
|
|
// Memo-Dateinamen bilden (.DBT):
|
|
|
|
|
// nyi: Unschoen fuer Unix und Mac!
|
|
|
|
|
|
|
|
|
|
if (m_aHeader.db_typ == FoxProMemo) // foxpro verwendet andere extension
|
|
|
|
|
aURL.SetExtension(String::CreateFromAscii("fpt")); // nyi: Gross-/Kleinschreibung bei Unix? Klein ist sicherlich schoener.
|
|
|
|
|
else
|
|
|
|
|
aURL.SetExtension(String::CreateFromAscii("dbt")); // nyi: Gross-/Kleinschreibung bei Unix? Klein ist sicherlich schoener.
|
|
|
|
|
|
|
|
|
|
// Wenn die Memodatei nicht gefunden wird, werden die Daten trotzdem angezeigt
|
|
|
|
|
// allerdings koennen keine Updates durchgefuehrt werden
|
|
|
|
|
// jedoch die Operation wird ausgefuehrt
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream = ::utl::UcbStreamHelper::CreateStream( aURL.GetURLNoPass(), STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE);
|
|
|
|
|
if (m_pMemoStream)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
ReadMemoHeader();
|
|
|
|
|
}
|
|
|
|
|
fillColumns();
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->Seek(STREAM_SEEK_TO_END);
|
|
|
|
|
UINT32 nFileSize = m_pFileStream->Tell();
|
|
|
|
|
m_pFileStream->Seek(STREAM_SEEK_TO_BEGIN);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Buffersize abhaengig von der Filegroesse
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->SetBufferSize(nFileSize > 1000000 ? 32768 :
|
2000-09-18 15:18:56 +00:00
|
|
|
|
nFileSize > 100000 ? 16384 :
|
|
|
|
|
nFileSize > 10000 ? 4096 : 1024);
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
if (m_pMemoStream)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
// Puffer genau auf Laenge eines Satzes stellen
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Seek(STREAM_SEEK_TO_END);
|
|
|
|
|
nFileSize = m_pMemoStream->Tell();
|
|
|
|
|
m_pMemoStream->Seek(STREAM_SEEK_TO_BEGIN);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Buffersize abhaengig von der Filegroesse
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->SetBufferSize(nFileSize > 1000000 ? 32768 :
|
2000-09-18 15:18:56 +00:00
|
|
|
|
nFileSize > 100000 ? 16384 :
|
|
|
|
|
nFileSize > 10000 ? 4096 :
|
|
|
|
|
m_aMemoHeader.db_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AllocBuffer();
|
|
|
|
|
|
|
|
|
|
refreshColumns();
|
|
|
|
|
refreshIndexes();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
BOOL ODbaseTable::ReadMemoHeader()
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
|
|
|
|
|
m_pMemoStream->RefreshBuffer(); // sicherstellen das die Kopfinformationen tatsaechlich neu gelesen werden
|
|
|
|
|
m_pMemoStream->Seek(0L);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pMemoStream) >> m_aMemoHeader.db_next;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
switch (m_aHeader.db_typ)
|
|
|
|
|
{
|
|
|
|
|
case dBaseIIIMemo: // dBase III: feste Blockgr<67><72>e
|
|
|
|
|
case dBaseIVMemo:
|
|
|
|
|
// manchmal wird aber auch dBase3 dBase4 Memo zugeordnet
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Seek(20L);
|
|
|
|
|
(*m_pMemoStream) >> m_aMemoHeader.db_size;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if (m_aMemoHeader.db_size > 1 && m_aMemoHeader.db_size != 512) // 1 steht auch fuer dBase 3
|
|
|
|
|
m_aMemoHeader.db_typ = MemodBaseIV;
|
|
|
|
|
else if (m_aMemoHeader.db_size > 1 && m_aMemoHeader.db_size == 512)
|
|
|
|
|
{
|
|
|
|
|
// nun gibt es noch manche Dateien, die verwenden eine G<><47>enangabe,
|
|
|
|
|
// sind aber dennoch dBase Dateien
|
|
|
|
|
char sHeader[4];
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Seek(m_aMemoHeader.db_size);
|
|
|
|
|
m_pMemoStream->Read(sHeader,4);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
if ((m_pMemoStream->GetErrorCode() != ERRCODE_NONE) || ((BYTE)sHeader[0]) != 0xFF || ((BYTE)sHeader[1]) != 0xFF || ((BYTE)sHeader[2]) != 0x08)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
m_aMemoHeader.db_typ = MemodBaseIII;
|
|
|
|
|
else
|
|
|
|
|
m_aMemoHeader.db_typ = MemodBaseIV;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_aMemoHeader.db_typ = MemodBaseIII;
|
|
|
|
|
m_aMemoHeader.db_size = 512;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case FoxProMemo:
|
|
|
|
|
m_aMemoHeader.db_typ = MemoFoxPro;
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Seek(6L);
|
|
|
|
|
m_pMemoStream->SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN);
|
|
|
|
|
(*m_pMemoStream) >> m_aMemoHeader.db_size;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
// -------------------------------------------------------------------------
|
2000-09-20 05:52:26 +00:00
|
|
|
|
String ODbaseTable::getEntry()
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
::rtl::OUString aURL;
|
2000-09-20 05:52:26 +00:00
|
|
|
|
Reference< XResultSet > xDir = m_pConnection->getDir()->getStaticResultSet();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
Reference< XRow> xRow(xDir,UNO_QUERY);
|
2000-09-20 05:52:26 +00:00
|
|
|
|
::rtl::OUString aName;
|
|
|
|
|
sal_Int32 nLen = m_pConnection->getExtension().Len()+1;
|
|
|
|
|
xDir->beforeFirst();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
while(xDir->next())
|
|
|
|
|
{
|
2000-09-20 05:52:26 +00:00
|
|
|
|
aName = xRow->getString(1);
|
|
|
|
|
aName = aName.replaceAt(aName.getLength()-nLen,nLen,::rtl::OUString());
|
|
|
|
|
if(aName == m_Name)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
Reference< XContentAccess > xContentAccess( xDir, UNO_QUERY );
|
2000-10-31 08:52:18 +00:00
|
|
|
|
#if SUPD>611
|
|
|
|
|
aURL = xContentAccess->queryContentIdentifierString();
|
|
|
|
|
#else
|
2000-09-18 15:18:56 +00:00
|
|
|
|
aURL = xContentAccess->queryContentIdentfierString();
|
2000-10-31 08:52:18 +00:00
|
|
|
|
#endif
|
2000-09-18 15:18:56 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
xDir->beforeFirst(); // move back to before first record
|
2000-09-20 05:52:26 +00:00
|
|
|
|
return aURL.getStr();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
void ODbaseTable::refreshColumns()
|
|
|
|
|
{
|
|
|
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
|
|
|
|
|
|
::std::vector< ::rtl::OUString> aVector;
|
|
|
|
|
|
|
|
|
|
for(OSQLColumns::const_iterator aIter = m_aColumns->begin();aIter != m_aColumns->end();++aIter)
|
|
|
|
|
aVector.push_back(Reference< XNamed>(*aIter,UNO_QUERY)->getName());
|
|
|
|
|
|
|
|
|
|
if(m_pColumns)
|
|
|
|
|
delete m_pColumns;
|
|
|
|
|
m_pColumns = new ODbaseColumns(this,m_aMutex,aVector);
|
|
|
|
|
}
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
void ODbaseTable::refreshIndexes()
|
|
|
|
|
{
|
|
|
|
|
::std::vector< ::rtl::OUString> aVector;
|
2000-11-16 09:47:23 +00:00
|
|
|
|
if(m_pFileStream)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
INetURLObject aURL;
|
|
|
|
|
aURL.SetURL(getEntry());
|
|
|
|
|
|
|
|
|
|
aURL.setExtension(String::CreateFromAscii("inf"));
|
|
|
|
|
Config aInfFile(aURL.GetURLNoPass());
|
|
|
|
|
aInfFile.SetGroup(dBASE_III_GROUP);
|
|
|
|
|
sal_Int32 nKeyCnt = aInfFile.GetKeyCount();
|
|
|
|
|
ByteString aKeyName;
|
|
|
|
|
ByteString aIndexName;
|
|
|
|
|
|
|
|
|
|
for (sal_Int32 nKey = 0,nPos=0; nKey < nKeyCnt; nKey++)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
// Verweist der Key auf ein Indexfile?...
|
|
|
|
|
aKeyName = aInfFile.GetKeyName( nKey );
|
|
|
|
|
//...wenn ja, Indexliste der Tabelle hinzufuegen
|
|
|
|
|
if (aKeyName.Copy(0,3) == ByteString("NDX") )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
aIndexName = aInfFile.ReadKey(aKeyName);
|
|
|
|
|
aURL.setName(String(aIndexName,getConnection()->getTextEncoding()));
|
|
|
|
|
Content aCnt(aURL.GetURLNoPass(),Reference<XCommandEnvironment>());
|
|
|
|
|
if (aCnt.isDocument())
|
|
|
|
|
{
|
|
|
|
|
aVector.push_back(aURL.getBase());
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(m_pIndexes)
|
|
|
|
|
delete m_pIndexes;
|
|
|
|
|
m_pIndexes = new ODbaseIndexes(this,m_aMutex,aVector);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
void SAL_CALL ODbaseTable::disposing(void)
|
|
|
|
|
{
|
|
|
|
|
OFileTable::disposing();
|
|
|
|
|
::osl::MutexGuard aGuard(m_aMutex);
|
2000-10-17 08:15:19 +00:00
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
for(OSQLColumns::const_iterator aIter = m_aColumns->begin();aIter != m_aColumns->end();++aIter)
|
|
|
|
|
{
|
2000-10-30 07:07:33 +00:00
|
|
|
|
::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> xProp = *aIter;
|
2000-10-17 08:15:19 +00:00
|
|
|
|
xProp = NULL;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2000-11-03 13:21:22 +00:00
|
|
|
|
m_aColumns->clear();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
Sequence< Type > SAL_CALL ODbaseTable::getTypes( ) throw(RuntimeException)
|
|
|
|
|
{
|
|
|
|
|
Sequence< Type > aTypes = OTable_TYPEDEF::getTypes();
|
|
|
|
|
Sequence< Type > aRet(aTypes.getLength()-3);
|
|
|
|
|
const Type* pBegin = aTypes.getConstArray();
|
|
|
|
|
const Type* pEnd = pBegin + aTypes.getLength();
|
|
|
|
|
sal_Int32 i=0;
|
|
|
|
|
for(;pBegin != pEnd;++pBegin,++i)
|
|
|
|
|
{
|
|
|
|
|
if(!(*pBegin == ::getCppuType((const Reference<XKeysSupplier>*)0) ||
|
|
|
|
|
*pBegin == ::getCppuType((const Reference<XRename>*)0) ||
|
|
|
|
|
*pBegin == ::getCppuType((const Reference<XAlterTable>*)0) ||
|
|
|
|
|
*pBegin == ::getCppuType((const Reference<XDataDescriptorFactory>*)0)))
|
|
|
|
|
{
|
|
|
|
|
aRet.getArray()[i] = *pBegin;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
aRet.getArray()[i] = ::getCppuType( (const Reference< ::com::sun::star::lang::XUnoTunnel > *)0 );
|
|
|
|
|
|
|
|
|
|
return aRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
Any SAL_CALL ODbaseTable::queryInterface( const Type & rType ) throw(RuntimeException)
|
|
|
|
|
{
|
|
|
|
|
if( rType == ::getCppuType((const Reference<XKeysSupplier>*)0) ||
|
|
|
|
|
rType == ::getCppuType((const Reference<XRename>*)0) ||
|
|
|
|
|
rType == ::getCppuType((const Reference<XAlterTable>*)0) ||
|
|
|
|
|
rType == ::getCppuType((const Reference<XDataDescriptorFactory>*)0))
|
|
|
|
|
return Any();
|
|
|
|
|
|
|
|
|
|
Any aRet = ::cppu::queryInterface(rType,static_cast< ::com::sun::star::lang::XUnoTunnel*> (this));
|
|
|
|
|
if(aRet.hasValue())
|
|
|
|
|
return aRet;
|
|
|
|
|
|
|
|
|
|
return OTable_TYPEDEF::queryInterface(rType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
Sequence< sal_Int8 > ODbaseTable::getUnoTunnelImplementationId()
|
|
|
|
|
{
|
|
|
|
|
static ::cppu::OImplementationId * pId = 0;
|
|
|
|
|
if (! pId)
|
|
|
|
|
{
|
|
|
|
|
::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
|
|
|
|
|
if (! pId)
|
|
|
|
|
{
|
|
|
|
|
static ::cppu::OImplementationId aId;
|
|
|
|
|
pId = &aId;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return pId->getImplementationId();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// com::sun::star::lang::XUnoTunnel
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
sal_Int64 ODbaseTable::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException)
|
|
|
|
|
{
|
|
|
|
|
if (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
|
|
|
|
|
return (sal_Int64)this;
|
|
|
|
|
|
|
|
|
|
return ODbaseTable_BASE::getSomething(rId);
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
sal_Bool ODbaseTable::seekRow(FilePosition eCursorPosition, sal_Int32 nOffset, sal_Int32& nCurPos)
|
|
|
|
|
{
|
|
|
|
|
// ----------------------------------------------------------
|
|
|
|
|
// Positionierung vorbereiten:
|
|
|
|
|
|
|
|
|
|
sal_uInt32 nNumberOfRecords = (sal_uInt32)m_aHeader.db_anz;
|
|
|
|
|
sal_uInt32 nTempPos = m_nFilePos;
|
|
|
|
|
m_nFilePos = nCurPos;
|
|
|
|
|
|
|
|
|
|
switch(eCursorPosition)
|
|
|
|
|
{
|
|
|
|
|
case FILE_NEXT:
|
|
|
|
|
m_nFilePos++;
|
|
|
|
|
break;
|
|
|
|
|
case FILE_PRIOR:
|
|
|
|
|
if (m_nFilePos > 0)
|
|
|
|
|
m_nFilePos--;
|
|
|
|
|
break;
|
|
|
|
|
case FILE_FIRST:
|
|
|
|
|
m_nFilePos = 1;
|
|
|
|
|
break;
|
|
|
|
|
case FILE_LAST:
|
|
|
|
|
m_nFilePos = nNumberOfRecords;
|
|
|
|
|
break;
|
|
|
|
|
case FILE_RELATIVE:
|
|
|
|
|
m_nFilePos = (((sal_Int32)m_nFilePos) + nOffset < 0) ? 0L
|
|
|
|
|
: (sal_uInt32)(((sal_Int32)m_nFilePos) + nOffset);
|
|
|
|
|
break;
|
|
|
|
|
case FILE_ABSOLUTE:
|
|
|
|
|
case FILE_BOOKMARK:
|
|
|
|
|
m_nFilePos = (sal_uInt32)nOffset;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_nFilePos > (sal_Int32)nNumberOfRecords)
|
|
|
|
|
m_nFilePos = (sal_Int32)nNumberOfRecords + 1;
|
|
|
|
|
|
|
|
|
|
if (m_nFilePos == 0 || m_nFilePos == (sal_Int32)nNumberOfRecords + 1)
|
|
|
|
|
goto Error;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sal_uInt16 nEntryLen = m_aHeader.db_slng;
|
|
|
|
|
|
|
|
|
|
OSL_ENSHURE(m_nFilePos >= 1,"SdbDBFCursor::FileFetchRow: ungueltige Record-Position");
|
|
|
|
|
sal_Int32 nPos = m_aHeader.db_kopf + (sal_Int32)(m_nFilePos-1) * nEntryLen;
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
ULONG nLen = m_pFileStream->Seek(nPos);
|
|
|
|
|
if (m_pFileStream->GetError() != ERRCODE_NONE)
|
2000-09-29 14:30:09 +00:00
|
|
|
|
goto Error;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
nLen = m_pFileStream->Read((char*)m_pBuffer, nEntryLen);
|
|
|
|
|
if (m_pFileStream->GetError() != ERRCODE_NONE)
|
2000-09-29 14:30:09 +00:00
|
|
|
|
goto Error;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
goto End;
|
|
|
|
|
|
|
|
|
|
Error:
|
|
|
|
|
switch(eCursorPosition)
|
|
|
|
|
{
|
|
|
|
|
case FILE_PRIOR:
|
|
|
|
|
case FILE_FIRST:
|
|
|
|
|
m_nFilePos = 0;
|
|
|
|
|
break;
|
|
|
|
|
case FILE_LAST:
|
|
|
|
|
case FILE_NEXT:
|
|
|
|
|
case FILE_ABSOLUTE:
|
|
|
|
|
case FILE_RELATIVE:
|
|
|
|
|
if (nOffset > 0)
|
|
|
|
|
m_nFilePos = nNumberOfRecords + 1;
|
|
|
|
|
else if (nOffset < 0)
|
|
|
|
|
m_nFilePos = 0;
|
|
|
|
|
break;
|
|
|
|
|
case FILE_BOOKMARK:
|
|
|
|
|
m_nFilePos = nTempPos; // vorherige Position
|
|
|
|
|
}
|
|
|
|
|
// aStatus.Set(SDB_STAT_NO_DATA_FOUND);
|
|
|
|
|
return sal_False;
|
|
|
|
|
|
|
|
|
|
End:
|
|
|
|
|
nCurPos = m_nFilePos;
|
|
|
|
|
return sal_True;
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
sal_Bool ODbaseTable::fetchRow(file::OValueRow _rRow,const OSQLColumns & _rCols, sal_Bool bRetrieveData)
|
|
|
|
|
{
|
|
|
|
|
// Einlesen der Daten
|
2000-09-29 14:30:09 +00:00
|
|
|
|
BOOL bIsCurRecordDeleted = ((char)m_pBuffer[0] == '*') ? TRUE : sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// only read the bookmark
|
|
|
|
|
|
|
|
|
|
// Satz als geloescht markieren
|
|
|
|
|
// rRow.setState(bIsCurRecordDeleted ? ROW_DELETED : ROW_CLEAN );
|
|
|
|
|
_rRow->setDeleted(bIsCurRecordDeleted);
|
|
|
|
|
(*_rRow)[0] = m_nFilePos;
|
|
|
|
|
|
|
|
|
|
if (!bRetrieveData)
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
sal_Int32 nByteOffset = 1;
|
|
|
|
|
// Felder:
|
|
|
|
|
OSQLColumns::const_iterator aIter = _rCols.begin();
|
|
|
|
|
for (sal_Int32 i = 1; aIter != _rCols.end();++aIter, i++)
|
|
|
|
|
{
|
|
|
|
|
// pVal = (*_rRow)[i].getBodyPtr();
|
2000-10-30 07:07:33 +00:00
|
|
|
|
Reference< XPropertySet> xColumn = *aIter;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Laengen je nach Datentyp:
|
|
|
|
|
// nyi: eine zentrale Funktion, die die Laenge liefert!
|
|
|
|
|
sal_Int32 nLen;
|
2000-10-30 07:07:33 +00:00
|
|
|
|
xColumn->getPropertyValue(PROPERTY_PRECISION) >>= nLen;
|
|
|
|
|
sal_Int32 nType = getINT32(xColumn->getPropertyValue(PROPERTY_TYPE));
|
2000-09-18 15:18:56 +00:00
|
|
|
|
switch(nType)
|
|
|
|
|
{
|
|
|
|
|
case DataType::DATE: nLen = 8; break;
|
|
|
|
|
case DataType::DECIMAL:
|
2000-10-30 07:07:33 +00:00
|
|
|
|
nLen = SvDbaseConverter::ConvertPrecisionToDbase(nLen,getINT32(xColumn->getPropertyValue(PROPERTY_SCALE)));
|
2000-09-18 15:18:56 +00:00
|
|
|
|
break; // das Vorzeichen und das Komma
|
|
|
|
|
case DataType::BIT: nLen = 1; break;
|
|
|
|
|
case DataType::LONGVARCHAR: nLen = 10; break;
|
|
|
|
|
case DataType::OTHER:
|
|
|
|
|
nByteOffset += nLen;
|
|
|
|
|
continue;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ist die Variable ueberhaupt gebunden?
|
|
|
|
|
if (!(*_rRow)[i].isBound())
|
|
|
|
|
{
|
|
|
|
|
// Nein - naechstes Feld.
|
|
|
|
|
nByteOffset += nLen;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *pData = (char *) (m_pBuffer + nByteOffset);
|
|
|
|
|
|
2000-09-29 14:30:09 +00:00
|
|
|
|
// (*_rRow)[i].setType(nType);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
if (nType == DataType::CHAR || nType == DataType::VARCHAR)
|
|
|
|
|
{
|
|
|
|
|
char cLast = pData[nLen];
|
|
|
|
|
pData[nLen] = 0;
|
2000-09-29 14:30:09 +00:00
|
|
|
|
String aStr(pData,getConnection()->getTextEncoding());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
aStr.EraseTrailingChars();
|
|
|
|
|
|
|
|
|
|
if (!aStr.Len()) // keine StringLaenge, dann NULL
|
|
|
|
|
(*_rRow)[i].setNull();
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
::rtl::OUString aStr2(aStr);
|
|
|
|
|
(*_rRow)[i] = aStr2;
|
|
|
|
|
}
|
|
|
|
|
pData[nLen] = cLast;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Falls Nul-Zeichen im String enthalten sind, in Blanks umwandeln!
|
|
|
|
|
for (sal_Int32 k = 0; k < nLen; k++)
|
|
|
|
|
{
|
|
|
|
|
if (pData[k] == '\0')
|
|
|
|
|
pData[k] = ' ';
|
|
|
|
|
}
|
|
|
|
|
|
2000-11-06 09:27:21 +00:00
|
|
|
|
String aStr(pData, nLen,getConnection()->getTextEncoding()); // Spaces am Anfang und am Ende entfernen:
|
2000-09-18 15:18:56 +00:00
|
|
|
|
aStr.EraseLeadingChars();
|
|
|
|
|
aStr.EraseTrailingChars();
|
|
|
|
|
|
|
|
|
|
if (!aStr.Len())
|
|
|
|
|
{
|
|
|
|
|
nByteOffset += nLen;
|
|
|
|
|
(*_rRow)[i].setNull(); // keine Werte -> fertig
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (nType)
|
|
|
|
|
{
|
|
|
|
|
case DataType::DATE:
|
|
|
|
|
{
|
|
|
|
|
if (aStr.Len() != nLen)
|
|
|
|
|
{
|
|
|
|
|
(*_rRow)[i].setNull();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
sal_Int32 nYear = aStr.Copy( 0, 4 ).ToInt32();
|
|
|
|
|
sal_Int32 nMonth = aStr.Copy( 4, 2 ).ToInt32();
|
|
|
|
|
sal_Int32 nDay = aStr.Copy( 6, 2 ).ToInt32();
|
|
|
|
|
|
|
|
|
|
::com::sun::star::util::Date aDate(nDay,nMonth,nYear);
|
|
|
|
|
(*_rRow)[i] = DateConversion::toDouble(aDate);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case DataType::DECIMAL:
|
|
|
|
|
(*_rRow)[i] = aStr.ToDouble();
|
|
|
|
|
// pVal->setDouble(SdbTools::ToDouble(aStr));
|
|
|
|
|
break;
|
|
|
|
|
case DataType::BIT:
|
|
|
|
|
{
|
|
|
|
|
BOOL b;
|
|
|
|
|
switch (* ((const char *)pData))
|
|
|
|
|
{
|
|
|
|
|
case 'T':
|
|
|
|
|
case 'Y':
|
|
|
|
|
case 'J': b = TRUE; break;
|
2000-09-29 14:30:09 +00:00
|
|
|
|
default: b = sal_False; break;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
(*_rRow)[i] = b;
|
|
|
|
|
// pVal->setDouble(b);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case DataType::LONGVARCHAR:
|
|
|
|
|
{
|
|
|
|
|
long nBlockNo = aStr.ToInt32(); // Blocknummer lesen
|
2000-11-16 09:47:23 +00:00
|
|
|
|
if (nBlockNo > 0 && m_pMemoStream) // Daten aus Memo-Datei lesen, nur wenn
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
if (!ReadMemo(nBlockNo, (*_rRow)[i]))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
(*_rRow)[i].setNull();
|
|
|
|
|
} break;
|
|
|
|
|
default:
|
|
|
|
|
OSL_ASSERT("Falscher Type");
|
|
|
|
|
}
|
2000-10-17 08:15:19 +00:00
|
|
|
|
(*_rRow)[i].setTypeKind(nType);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if (aStatus.IsError())
|
|
|
|
|
// break;
|
|
|
|
|
// Und weiter ...
|
|
|
|
|
nByteOffset += nLen;
|
|
|
|
|
}
|
|
|
|
|
return sal_True;
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------
|
2000-10-17 08:15:19 +00:00
|
|
|
|
BOOL ODbaseTable::ReadMemo(ULONG nBlockNo, ORowSetValue& aVariable)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
BOOL bIsText = TRUE;
|
|
|
|
|
// SdbConnection* pConnection = GetConnection();
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Seek(nBlockNo * m_aMemoHeader.db_size);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
switch (m_aMemoHeader.db_typ)
|
|
|
|
|
{
|
|
|
|
|
case MemodBaseIII: // dBase III-Memofeld, endet mit Ctrl-Z
|
|
|
|
|
{
|
|
|
|
|
const char cEOF = (char) 0x1a;
|
2000-10-17 08:15:19 +00:00
|
|
|
|
ByteString aBStr;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
static char aBuf[514];
|
|
|
|
|
aBuf[512] = 0; // sonst kann der Zufall uebel mitspielen
|
2000-09-29 14:30:09 +00:00
|
|
|
|
BOOL bReady = sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Read(&aBuf,512);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
USHORT i = 0;
|
|
|
|
|
while (aBuf[i] != cEOF && ++i < 512)
|
|
|
|
|
;
|
|
|
|
|
bReady = aBuf[i] == cEOF;
|
|
|
|
|
|
|
|
|
|
aBuf[i] = 0;
|
2000-10-17 08:15:19 +00:00
|
|
|
|
aBStr += aBuf;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
} while (!bReady && !m_pMemoStream->IsEof() && aBStr.Len() < STRING_MAXLEN);
|
2000-10-17 08:15:19 +00:00
|
|
|
|
|
|
|
|
|
::rtl::OUString aStr(aBStr.GetBuffer(), aBStr.Len(),getConnection()->getTextEncoding());
|
2000-11-06 10:50:02 +00:00
|
|
|
|
aVariable = Sequence<sal_Int8>(reinterpret_cast<const sal_Int8*>(aStr.getStr()),sizeof(sal_Unicode)*aStr.getLength());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
} break;
|
|
|
|
|
case MemoFoxPro:
|
|
|
|
|
case MemodBaseIV: // dBase IV-Memofeld mit Laengenangabe
|
|
|
|
|
{
|
|
|
|
|
char sHeader[4];
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Read(sHeader,4);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Foxpro stores text and binary data
|
|
|
|
|
if (m_aMemoHeader.db_typ == MemoFoxPro)
|
|
|
|
|
{
|
|
|
|
|
if (((BYTE)sHeader[0]) != 0 || ((BYTE)sHeader[1]) != 0 || ((BYTE)sHeader[2]) != 0)
|
|
|
|
|
{
|
|
|
|
|
// String aText = String(SdbResId(STR_STAT_FILE_INVALID));
|
2000-11-16 09:47:23 +00:00
|
|
|
|
// aText.SearchAndReplace(String::CreateFromAscii("%%d"),m_pMemoStream->GetFileName());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// aText.SearchAndReplace(String::CreateFromAscii("%%t"),aStatus.TypeToString(MEMO));
|
|
|
|
|
// aStatus.Set(SDB_STAT_ERROR,
|
|
|
|
|
// String::CreateFromAscii("01000"),
|
|
|
|
|
// aStatus.CreateErrorMessage(aText),
|
|
|
|
|
// 0, String() );
|
2000-09-29 14:30:09 +00:00
|
|
|
|
return sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bIsText = sHeader[3] != 0;
|
|
|
|
|
}
|
|
|
|
|
else if (((BYTE)sHeader[0]) != 0xFF || ((BYTE)sHeader[1]) != 0xFF || ((BYTE)sHeader[2]) != 0x08)
|
|
|
|
|
{
|
|
|
|
|
// String aText = String(SdbResId(STR_STAT_FILE_INVALID));
|
2000-11-16 09:47:23 +00:00
|
|
|
|
// aText.SearchAndReplace(String::CreateFromAscii("%%d"),m_pMemoStream->GetFileName());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// aText.SearchAndReplace(String::CreateFromAscii("%%t"),aStatus.TypeToString(MEMO));
|
|
|
|
|
// aStatus.Set(SDB_STAT_ERROR,
|
|
|
|
|
// String::CreateFromAscii("01000"),
|
|
|
|
|
// aStatus.CreateErrorMessage(aText),
|
|
|
|
|
// 0, String() );
|
2000-09-29 14:30:09 +00:00
|
|
|
|
return sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ULONG nLength;
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pMemoStream) >> nLength;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
if (m_aMemoHeader.db_typ == MemodBaseIV)
|
|
|
|
|
nLength -= 8;
|
|
|
|
|
|
|
|
|
|
// char cChar;
|
|
|
|
|
if (nLength < STRING_MAXLEN && bIsText)
|
|
|
|
|
{
|
2000-10-17 08:15:19 +00:00
|
|
|
|
ByteString aBStr;
|
|
|
|
|
aBStr.Expand(USHORT (nLength));
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Read(aBStr.AllocBuffer((USHORT)nLength),nLength);
|
2000-10-17 08:15:19 +00:00
|
|
|
|
aBStr.ReleaseBufferAccess();
|
|
|
|
|
::rtl::OUString aStr(aBStr.GetBuffer(),aBStr.Len(), getConnection()->getTextEncoding());
|
2000-11-06 10:50:02 +00:00
|
|
|
|
aVariable = Sequence<sal_Int8>(reinterpret_cast<const sal_Int8*>(aStr.getStr()),sizeof(sal_Unicode)*aStr.getLength());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2000-10-17 08:15:19 +00:00
|
|
|
|
Sequence<sal_Int8> aText(nLength);
|
|
|
|
|
sal_Int8* pData = aText.getArray();
|
|
|
|
|
sal_Char cChar;
|
|
|
|
|
for (ULONG i = 0; i < nLength; i++)
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Read(&cChar,1);
|
2000-10-17 08:15:19 +00:00
|
|
|
|
(*pData++) = cChar;
|
|
|
|
|
}
|
|
|
|
|
aVariable = aText;
|
|
|
|
|
// return sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return sal_True;
|
|
|
|
|
}
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
void ODbaseTable::FileClose()
|
|
|
|
|
{
|
2000-11-03 13:21:22 +00:00
|
|
|
|
::osl::MutexGuard aGuard(m_aMutex);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// falls noch nicht alles geschrieben wurde
|
2000-11-16 09:47:23 +00:00
|
|
|
|
if (m_pMemoStream && m_pMemoStream->IsWritable())
|
|
|
|
|
m_pMemoStream->Flush();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
delete m_pMemoStream;
|
|
|
|
|
m_pMemoStream = NULL;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-11-03 13:21:22 +00:00
|
|
|
|
ODbaseTable_BASE::FileClose();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
BOOL ODbaseTable::CreateImpl()
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
OSL_ENSHURE(!m_pFileStream, "SequenceError");
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
INetURLObject aURL;
|
|
|
|
|
aURL.SetSmartProtocol(INET_PROT_FILE);
|
2000-10-25 12:31:00 +00:00
|
|
|
|
String aName = getEntry();
|
|
|
|
|
if(!aName.Len())
|
|
|
|
|
{
|
|
|
|
|
::rtl::OUString aIdent = m_pConnection->getContent()->getIdentifier()->getContentIdentifier();
|
|
|
|
|
aIdent += m_Name;
|
|
|
|
|
aName = aIdent.getStr();
|
|
|
|
|
}
|
2000-11-16 09:47:23 +00:00
|
|
|
|
aURL.SetURL(aName);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
if(aURL.getExtension() != m_pConnection->getExtension())
|
|
|
|
|
aURL.setExtension(m_pConnection->getExtension());
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
Content aContent(aURL.GetURLNoPass(),Reference<XCommandEnvironment>());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
if (aContent.isDocument())
|
|
|
|
|
{
|
|
|
|
|
// Hack fuer Bug #30609 , nur wenn das File existiert und die Laenge > 0 gibt es einen Fehler
|
2000-11-16 09:47:23 +00:00
|
|
|
|
SvStream* pFileStream = ::utl::UcbStreamHelper::CreateStream( aURL.GetURLNoPass(),STREAM_READ);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
if (pFileStream && pFileStream->Seek(STREAM_SEEK_TO_END))
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
// aStatus.SetError(ERRCODE_IO_ALREADYEXISTS,TABLE,aFile.GetFull());
|
2000-09-29 14:30:09 +00:00
|
|
|
|
return sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
2000-11-16 09:47:23 +00:00
|
|
|
|
delete pFileStream;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-09-29 14:30:09 +00:00
|
|
|
|
BOOL bMemoFile = sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
sal_Bool bOk = CreateFile(aURL, bMemoFile);
|
|
|
|
|
|
|
|
|
|
FileClose();
|
|
|
|
|
|
|
|
|
|
if (!bOk)
|
|
|
|
|
{
|
|
|
|
|
aContent.executeCommand( rtl::OUString::createFromAscii( "delete" ),bool2any( sal_True ) );
|
2000-09-29 14:30:09 +00:00
|
|
|
|
return sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bMemoFile)
|
|
|
|
|
{
|
|
|
|
|
String aExt = aURL.getExtension();
|
|
|
|
|
aURL.setExtension(String::CreateFromAscii("dbt")); // extension for memo file
|
2000-11-16 09:47:23 +00:00
|
|
|
|
Content aMemo1Content(aURL.GetURLNoPass(),Reference<XCommandEnvironment>());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
if (aMemo1Content.isDocument())
|
|
|
|
|
{
|
|
|
|
|
// aStatus.SetError(ERRCODE_IO_ALREADYEXISTS,MEMO,aFile.GetFull());
|
|
|
|
|
aURL.setExtension(aExt); // kill dbf file
|
2000-11-16 09:47:23 +00:00
|
|
|
|
Content aMemoContent(aURL.GetURLNoPass(),Reference<XCommandEnvironment>());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
aMemoContent.executeCommand( rtl::OUString::createFromAscii( "delete" ),bool2any( sal_True ) );
|
2000-09-29 14:30:09 +00:00
|
|
|
|
return sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
if (!CreateMemoFile(aURL))
|
|
|
|
|
{
|
|
|
|
|
aURL.setExtension(aExt); // kill dbf file
|
2000-11-16 09:47:23 +00:00
|
|
|
|
Content aMemoContent(aURL.GetURLNoPass(),Reference<XCommandEnvironment>());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
aMemoContent.executeCommand( rtl::OUString::createFromAscii( "delete" ),bool2any( sal_True ) );
|
2000-09-29 14:30:09 +00:00
|
|
|
|
return sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
m_aHeader.db_typ = dBaseIIIMemo;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
m_aHeader.db_typ = dBaseIII;
|
|
|
|
|
|
|
|
|
|
// if (GetDBFConnection()->GetShowDeleted())
|
|
|
|
|
// nPrivileges = SDB_PR_READ | SDB_PR_INSERT | SDB_PR_UPDATE |
|
|
|
|
|
// SDB_PR_ALTER | SDB_PR_DROP;
|
|
|
|
|
// else
|
|
|
|
|
// nPrivileges = SDB_PR_READ | SDB_PR_INSERT | SDB_PR_UPDATE |
|
|
|
|
|
// SDB_PR_DELETE | SDB_PR_ALTER | SDB_PR_DROP;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
// erzeugt grunds<64>tzlich dBase IV Datei Format
|
|
|
|
|
BOOL ODbaseTable::CreateFile(const INetURLObject& aFile, BOOL& bCreateMemo)
|
|
|
|
|
{
|
2000-09-29 14:30:09 +00:00
|
|
|
|
bCreateMemo = sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
Date aDate; // aktuelles Datum
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream = ::utl::UcbStreamHelper::CreateStream( aFile.GetURLNoPass(),STREAM_READWRITE | STREAM_SHARE_DENYWRITE | STREAM_TRUNC);
|
|
|
|
|
|
|
|
|
|
if (!m_pFileStream)
|
2000-09-29 14:30:09 +00:00
|
|
|
|
return sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
char aBuffer[21]; // write buffer
|
|
|
|
|
memset(aBuffer,0,sizeof(aBuffer));
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->Seek(0L);
|
|
|
|
|
(*m_pFileStream) << (BYTE) dBaseIII; // dBase format
|
|
|
|
|
(*m_pFileStream) << (BYTE) (aDate.GetYear() % 100); // aktuelles Datum
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pFileStream) << (BYTE) aDate.GetMonth();
|
|
|
|
|
(*m_pFileStream) << (BYTE) aDate.GetDay();
|
|
|
|
|
(*m_pFileStream) << 0L; // Anzahl der Datens<6E>tze
|
|
|
|
|
(*m_pFileStream) << (USHORT)((m_pColumns->getCount()+1) * 32 + 1); // Kopfinformationen,
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// pColumns erh<72>lt immer eine Spalte mehr
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pFileStream) << (USHORT) 0; // Satzl<7A>nge wird sp<73>ter bestimmt
|
|
|
|
|
m_pFileStream->Write(aBuffer, 20);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
USHORT nRecLength = 1; // L<>nge 1 f<>r deleted flag
|
|
|
|
|
ULONG nMaxFieldLength = m_pConnection->getMetaData()->getMaxColumnNameLength();
|
|
|
|
|
Reference<XIndexAccess> xColumns(getColumns(),UNO_QUERY);
|
|
|
|
|
|
|
|
|
|
::rtl::OUString aName;
|
2000-10-30 07:07:33 +00:00
|
|
|
|
Reference<XPropertySet> xCol;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
for(sal_Int32 i=0;i<xColumns->getCount();++i)
|
|
|
|
|
{
|
|
|
|
|
xColumns->getByIndex(i) >>= xCol;
|
|
|
|
|
OSL_ENSHURE(xCol.is(),"This should be a column!");
|
|
|
|
|
|
|
|
|
|
char cTyp;
|
|
|
|
|
|
2000-10-30 07:07:33 +00:00
|
|
|
|
xCol->getPropertyValue(PROPERTY_NAME) >>= aName;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
if (aName.getLength() > nMaxFieldLength)
|
|
|
|
|
{
|
|
|
|
|
// String aText = String(SdbResId(STR_DBF_INVALIDFIELDNAMELENGTH));
|
|
|
|
|
// aText.SearchAndReplace(String::CreateFromAscii("#"),rColumn.GetName());
|
|
|
|
|
// aStatus.Set(SDB_STAT_ERROR,
|
|
|
|
|
// String::CreateFromAscii("01000"),
|
|
|
|
|
// aStatus.CreateErrorMessage(aText),
|
|
|
|
|
// 0, String() );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ByteString aCol(aName.getStr(),gsl_getSystemTextEncoding());
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pFileStream) << aCol.GetBuffer();
|
|
|
|
|
m_pFileStream->Write(aBuffer, 11 - aCol.Len());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-10-30 07:07:33 +00:00
|
|
|
|
switch (getINT32(xCol->getPropertyValue(PROPERTY_TYPE)))
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
case DataType::CHAR:
|
|
|
|
|
case DataType::VARCHAR:
|
|
|
|
|
cTyp = 'C';
|
|
|
|
|
break;
|
|
|
|
|
case DataType::TINYINT:
|
|
|
|
|
case DataType::SMALLINT:
|
|
|
|
|
case DataType::INTEGER:
|
|
|
|
|
case DataType::BIGINT:
|
|
|
|
|
case DataType::DECIMAL:
|
|
|
|
|
case DataType::NUMERIC:
|
|
|
|
|
case DataType::REAL:
|
|
|
|
|
case DataType::DOUBLE:
|
|
|
|
|
cTyp = 'N'; // nur dBase 3 format
|
|
|
|
|
break;
|
|
|
|
|
case DataType::DATE:
|
|
|
|
|
cTyp = 'D';
|
|
|
|
|
break;
|
|
|
|
|
case DataType::BIT:
|
|
|
|
|
cTyp = 'L';
|
|
|
|
|
break;
|
|
|
|
|
case DataType::LONGVARBINARY:
|
|
|
|
|
case DataType::LONGVARCHAR:
|
|
|
|
|
cTyp = 'M';
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
// aStatus.Set(SDB_STAT_ERROR,
|
|
|
|
|
// String::CreateFromAscii("01000"),
|
|
|
|
|
// aStatus.CreateErrorMessage(String(SdbResId(STR_DBF_INVALIDFORMAT))),
|
|
|
|
|
// 0, String() );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pFileStream) << cTyp;
|
|
|
|
|
m_pFileStream->Write(aBuffer, 4);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
sal_Int32 nPrecision = 0;
|
2000-10-30 07:07:33 +00:00
|
|
|
|
xCol->getPropertyValue(PROPERTY_PRECISION) >>= nPrecision;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
sal_Int32 nScale = 0;
|
2000-10-30 07:07:33 +00:00
|
|
|
|
xCol->getPropertyValue(PROPERTY_SCALE) >>= nScale;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
switch(cTyp)
|
|
|
|
|
{
|
|
|
|
|
case 'C':
|
|
|
|
|
OSL_ENSHURE(nPrecision < 255, "ODbaseTable::Create: Column zu lang!");
|
|
|
|
|
if (nPrecision > 254)
|
|
|
|
|
{
|
|
|
|
|
// String aText = String(SdbResId(STR_DBF_INVALIDFIELDLENGTH));
|
|
|
|
|
// aText.SearchAndReplace(String::CreateFromAscii("#"),rColumn.GetName());
|
|
|
|
|
// aStatus.Set(SDB_STAT_ERROR,
|
|
|
|
|
// String::CreateFromAscii("01000"),
|
|
|
|
|
// aStatus.CreateErrorMessage(aText),
|
|
|
|
|
// 0, String() );
|
|
|
|
|
// break;
|
|
|
|
|
}
|
2000-11-16 11:35:13 +00:00
|
|
|
|
(*m_pFileStream) << (BYTE) Min((ULONG)nPrecision, 255UL); //Feldl<64>nge
|
2000-11-14 10:55:54 +00:00
|
|
|
|
nRecLength += (USHORT)Min((ULONG)nPrecision, 255UL);
|
2000-11-16 11:35:13 +00:00
|
|
|
|
(*m_pFileStream) << (BYTE)0; //Nachkommastellen
|
2000-09-18 15:18:56 +00:00
|
|
|
|
break;
|
|
|
|
|
case 'F':
|
|
|
|
|
case 'N':
|
|
|
|
|
OSL_ENSHURE(nPrecision >= nScale,
|
|
|
|
|
"ODbaseTable::Create: Feldl<64>nge mu<6D> gr<67><72>er Nachkommastellen sein!");
|
|
|
|
|
if (nPrecision < nScale)
|
|
|
|
|
{
|
|
|
|
|
// aStatus.Set(SDB_STAT_ERROR,
|
|
|
|
|
// String::CreateFromAscii("01000"),
|
|
|
|
|
// aStatus.CreateErrorMessage(String(SdbResId(STR_DBF_INVALIDFORMAT))),
|
|
|
|
|
// 0, String() );
|
|
|
|
|
break;
|
|
|
|
|
}
|
2000-10-30 07:07:33 +00:00
|
|
|
|
if (getBOOL(xCol->getPropertyValue(PROPERTY_ISCURRENCY))) // Currency wird gesondert behandelt
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pFileStream) << (BYTE)10; // Standard Laenge
|
|
|
|
|
(*m_pFileStream) << (BYTE)4;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
nRecLength += 10;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UINT16 nPrec = SvDbaseConverter::ConvertPrecisionToDbase(nPrecision,nScale);
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pFileStream) << (BYTE)( nPrec);
|
|
|
|
|
(*m_pFileStream) << (BYTE)nScale;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
nRecLength += (USHORT)nPrec;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'L':
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pFileStream) << (BYTE)1;
|
|
|
|
|
(*m_pFileStream) << (BYTE)0;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
nRecLength++;
|
|
|
|
|
break;
|
|
|
|
|
case 'D':
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pFileStream) << (BYTE)8;
|
|
|
|
|
(*m_pFileStream) << (BYTE)0;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
nRecLength += 8;
|
|
|
|
|
break;
|
|
|
|
|
case 'M':
|
|
|
|
|
bCreateMemo = TRUE;
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pFileStream) << (BYTE)10;
|
|
|
|
|
(*m_pFileStream) << (BYTE)0;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
nRecLength += 10;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
// aStatus.Set(SDB_STAT_ERROR,
|
|
|
|
|
// String::CreateFromAscii("01000"),
|
|
|
|
|
// aStatus.CreateErrorMessage(String(SdbResId(STR_DBF_INVALIDFORMAT))),
|
|
|
|
|
// 0, String() );
|
|
|
|
|
break;
|
|
|
|
|
}
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->Write(aBuffer, 14);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if (aStatus.IsError())
|
2000-09-29 14:30:09 +00:00
|
|
|
|
// return sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pFileStream) << (BYTE)0x0d; // kopf ende
|
|
|
|
|
m_pFileStream->Seek(10L);
|
|
|
|
|
(*m_pFileStream) << nRecLength; // satzl<7A>nge nachtr<74>glich eintragen
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
if (bCreateMemo)
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->Seek(0L);
|
|
|
|
|
(*m_pFileStream) << (BYTE) dBaseIIIMemo;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
// erzeugt grunds<64>tzlich dBase III Datei Format
|
|
|
|
|
BOOL ODbaseTable::CreateMemoFile(const INetURLObject& aFile)
|
|
|
|
|
{
|
|
|
|
|
// Makro zum Filehandling f<>rs Erzeugen von Tabellen
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream = ::utl::UcbStreamHelper::CreateStream( aFile.GetURLNoPass(),STREAM_READWRITE | STREAM_SHARE_DENYWRITE);
|
|
|
|
|
|
|
|
|
|
if (!m_pMemoStream)
|
2000-09-29 14:30:09 +00:00
|
|
|
|
return sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
char aBuffer[512]; // write buffer
|
|
|
|
|
memset(aBuffer,0,sizeof(aBuffer));
|
|
|
|
|
|
|
|
|
|
#ifdef WIN
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Seek(0L);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
for (UINT16 i = 0; i < 512; i++)
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pMemoStream) << BYTE(0);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
#else
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->SetFiller('\0');
|
|
|
|
|
m_pMemoStream->SetStreamSize(512);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Seek(0L);
|
|
|
|
|
(*m_pMemoStream) << long(1); // Zeiger auf ersten freien Block
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Flush();
|
|
|
|
|
delete m_pMemoStream;
|
|
|
|
|
m_pMemoStream = NULL;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
BOOL ODbaseTable::DropImpl()
|
|
|
|
|
{
|
|
|
|
|
// NAMESPACE_VOS(OGuard) aGuard(m_pLock);
|
|
|
|
|
//
|
|
|
|
|
// if (InUse())
|
|
|
|
|
// {
|
|
|
|
|
// aStatus.SetError(ERRCODE_IO_LOCKVIOLATION,TABLE,aName);
|
2000-09-29 14:30:09 +00:00
|
|
|
|
// return sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
FileClose();
|
|
|
|
|
|
|
|
|
|
INetURLObject aURL;
|
2000-11-16 09:47:23 +00:00
|
|
|
|
aURL.SetURL(getEntry());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
Content aContent(aURL.GetURLNoPass(),Reference<XCommandEnvironment>());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
aContent.executeCommand( rtl::OUString::createFromAscii( "delete" ),
|
|
|
|
|
makeAny( sal_Bool( sal_True ) ) );
|
|
|
|
|
|
|
|
|
|
if (HasMemoFields())
|
|
|
|
|
{
|
|
|
|
|
aURL.setExtension(String::CreateFromAscii("dbt"));
|
2000-11-16 09:47:23 +00:00
|
|
|
|
Content aMemoContent(aURL.GetURLNoPass(),Reference<XCommandEnvironment>());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
aMemoContent.executeCommand( rtl::OUString::createFromAscii( "delete" ),bool2any( sal_True ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// jetzt noch die Indices loeschen
|
|
|
|
|
String aIndexName;
|
|
|
|
|
// aFile.SetExtension(String::CreateFromAscii("ndx"));
|
|
|
|
|
USHORT nCount = m_pIndexes->getCount(),
|
|
|
|
|
i = 0;
|
|
|
|
|
while (i < nCount)
|
|
|
|
|
{
|
|
|
|
|
m_pIndexes->dropByIndex(i);
|
|
|
|
|
}
|
|
|
|
|
// aFile.SetBase(m_Name);
|
|
|
|
|
aURL.setExtension(String::CreateFromAscii("inf"));
|
2000-11-16 09:47:23 +00:00
|
|
|
|
Content aInfContent(aURL.GetURLNoPass(),Reference<XCommandEnvironment>());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
aInfContent.executeCommand( rtl::OUString::createFromAscii( "delete" ),bool2any( sal_True ) );
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------
|
2000-09-29 14:30:09 +00:00
|
|
|
|
BOOL ODbaseTable::InsertRow(OValueVector& rRow, BOOL bFlush,const Reference<XIndexAccess>& _xCols)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
// Buffer mit Leerzeichen f<>llen
|
|
|
|
|
AllocBuffer();
|
|
|
|
|
memset(m_pBuffer, ' ', m_aHeader.db_slng);
|
|
|
|
|
|
|
|
|
|
// Gesamte neue Row uebernehmen:
|
|
|
|
|
// ... und am Ende als neuen Record hinzufuegen:
|
|
|
|
|
UINT32 nTempPos = m_nFilePos,
|
|
|
|
|
nFileSize,
|
|
|
|
|
nMemoFileSize;
|
|
|
|
|
|
|
|
|
|
m_nFilePos = (ULONG)m_aHeader.db_anz + 1;
|
2000-09-29 14:30:09 +00:00
|
|
|
|
if (!UpdateBuffer(rRow,NULL,_xCols))
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
m_nFilePos = nTempPos;
|
2000-09-29 14:30:09 +00:00
|
|
|
|
return sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->Seek(STREAM_SEEK_TO_END);
|
|
|
|
|
nFileSize = m_pFileStream->Tell();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
if (HasMemoFields() && m_pMemoStream)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Seek(STREAM_SEEK_TO_END);
|
|
|
|
|
nMemoFileSize = m_pMemoStream->Tell();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!WriteBuffer())
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->SetStreamSize(nFileSize); // alte Gr<47><72>e restaurieren
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
if (HasMemoFields() && m_pMemoStream)
|
|
|
|
|
m_pMemoStream->SetStreamSize(nMemoFileSize); // alte Gr<47><72>e restaurieren
|
2000-09-18 15:18:56 +00:00
|
|
|
|
m_nFilePos = nTempPos; // Fileposition restaurieren
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Anzahl Datensaetze im Header erhoehen:
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->Seek( 4L );
|
|
|
|
|
(*m_pFileStream) << (m_aHeader.db_anz + 1);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// beim AppendOnly kein Flush!
|
|
|
|
|
if (bFlush)
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->Flush();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// bei Erfolg # erh<72>hen
|
|
|
|
|
m_aHeader.db_anz++;
|
2000-09-29 14:30:09 +00:00
|
|
|
|
rRow[0] = m_nFilePos; // BOOKmark setzen
|
2000-09-18 15:18:56 +00:00
|
|
|
|
m_nFilePos = nTempPos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sal_True;;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
BOOL ODbaseTable::UpdateRow(file::OValueVector& rRow, OValueRow pOrgRow,const Reference<XIndexAccess>& _xCols)
|
|
|
|
|
{
|
|
|
|
|
// Buffer mit Leerzeichen f<>llen
|
|
|
|
|
AllocBuffer();
|
|
|
|
|
|
|
|
|
|
// Auf gewuenschten Record positionieren:
|
|
|
|
|
long nPos = m_aHeader.db_kopf + (long)(m_nFilePos-1) * m_aHeader.db_slng;
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->Seek(nPos);
|
|
|
|
|
m_pFileStream->Read((char*)m_pBuffer, m_aHeader.db_slng);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
UINT32 nMemoFileSize;
|
2000-11-16 09:47:23 +00:00
|
|
|
|
if (HasMemoFields() && m_pMemoStream)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Seek(STREAM_SEEK_TO_END);
|
|
|
|
|
nMemoFileSize = m_pMemoStream->Tell();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
if (!UpdateBuffer(rRow, pOrgRow,_xCols) || !WriteBuffer())
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
if (HasMemoFields() && m_pMemoStream)
|
|
|
|
|
m_pMemoStream->SetStreamSize(nMemoFileSize); // alte Gr<47><72>e restaurieren
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->Flush();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
return sal_True;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
BOOL ODbaseTable::DeleteRow(const OSQLColumns& _rCols)
|
|
|
|
|
{
|
|
|
|
|
// Einfach das Loesch-Flag setzen (egal, ob es schon gesetzt war
|
|
|
|
|
// oder nicht):
|
|
|
|
|
// Auf gewuenschten Record positionieren:
|
|
|
|
|
long nPos = m_aHeader.db_kopf + (long)(m_nFilePos-1) * m_aHeader.db_slng;
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->Seek(nPos);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
OValueRow aRow = new OValueVector(_rCols.size());
|
|
|
|
|
|
|
|
|
|
if (!fetchRow(aRow,_rCols,TRUE))
|
2000-09-29 14:30:09 +00:00
|
|
|
|
return sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-10-30 07:07:33 +00:00
|
|
|
|
Reference<XPropertySet> xCol;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
::rtl::OUString aColName;
|
2000-10-11 09:48:50 +00:00
|
|
|
|
::comphelper::UStringMixEqual aCase(isCaseSensitive());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
for (USHORT i = 0; i < m_pColumns->getCount(); i++)
|
|
|
|
|
{
|
|
|
|
|
m_pColumns->getByIndex(i) >>= xCol;
|
|
|
|
|
// const SdbFILEColumn *pColumn = (const SdbFILEColumn *)(*aOriginalColumns)[i];
|
|
|
|
|
|
2000-10-30 07:07:33 +00:00
|
|
|
|
xCol->getPropertyValue(PROPERTY_NAME) >>= aColName;
|
|
|
|
|
Reference<XPropertySet> xIndex = isUniqueByColumnName(aColName);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if (xIndex.is())
|
|
|
|
|
{
|
|
|
|
|
Reference<XUnoTunnel> xTunnel(xIndex,UNO_QUERY);
|
|
|
|
|
OSL_ENSHURE(xTunnel.is(),"No TunnelImplementation!");
|
|
|
|
|
ODbaseIndex* pIndex = (ODbaseIndex*)xTunnel->getSomething(ODbaseIndex::getUnoTunnelImplementationId());
|
|
|
|
|
OSL_ENSHURE(pIndex,"ODbaseTable::UpdateBuffer: No Index returned!");
|
|
|
|
|
|
|
|
|
|
OSQLColumns::const_iterator aIter = _rCols.begin();
|
|
|
|
|
// sal_Int32 nPos = 0;
|
|
|
|
|
for(;aIter != _rCols.end();++aIter,++nPos)
|
|
|
|
|
{
|
2000-10-30 07:07:33 +00:00
|
|
|
|
// Reference<XPropertySet> xFindCol;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// _xCols->getByIndex(nPos) >>= xFindCol;
|
2000-10-30 07:07:33 +00:00
|
|
|
|
if(aCase(getString((*aIter)->getPropertyValue(PROPERTY_REALNAME)),aColName))
|
2000-09-18 15:18:56 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (aIter == _rCols.end())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
pIndex->Delete(m_nFilePos,(*aRow)[nPos]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->Seek(nPos);
|
|
|
|
|
(*m_pFileStream) << (BYTE)'*';
|
|
|
|
|
m_pFileStream->Flush();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
return sal_True;;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
2000-10-17 08:15:19 +00:00
|
|
|
|
BOOL ODbaseTable::WriteMemo(ORowSetValue& aVariable, ULONG& rBlockNr)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
// wird die BlockNr 0 vorgegeben, wird der block ans Ende gehaengt
|
|
|
|
|
char cChar = 0;
|
|
|
|
|
BOOL bIsText = TRUE;
|
|
|
|
|
// SdbConnection* pConnection = GetConnection();
|
|
|
|
|
|
|
|
|
|
ULONG nSize = 0;
|
|
|
|
|
ULONG nStreamSize;
|
|
|
|
|
BYTE nHeader[4];
|
|
|
|
|
|
|
|
|
|
ByteString aStr;
|
|
|
|
|
// ::Sequence<sal_Int8>* pData = NULL;
|
|
|
|
|
// if (aVariable.getValueType() == ::getCppuType((const ::com::sun::star::uno::Sequence< sal_Int8 > *)0))
|
|
|
|
|
// {
|
|
|
|
|
// pData = (::Sequence<sal_Int8>*)aVariable.get();
|
|
|
|
|
// nSize = pData->getLength();
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
2000-09-29 14:30:09 +00:00
|
|
|
|
aStr = ByteString(aVariable.getString().getStr(), getConnection()->getTextEncoding());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
nSize = aStr.Len();
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// Anhaengen oder ueberschreiben
|
|
|
|
|
BOOL bAppend = rBlockNr == 0;
|
|
|
|
|
|
|
|
|
|
if (!bAppend)
|
|
|
|
|
{
|
|
|
|
|
switch (m_aMemoHeader.db_typ)
|
|
|
|
|
{
|
|
|
|
|
case MemodBaseIII: // dBase III-Memofeld, endet mit 2 * Ctrl-Z
|
|
|
|
|
bAppend = nSize > (512 - 2);
|
|
|
|
|
break;
|
|
|
|
|
case MemoFoxPro:
|
|
|
|
|
case MemodBaseIV: // dBase IV-Memofeld mit Laengenangabe
|
|
|
|
|
{
|
|
|
|
|
char sHeader[4];
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Seek(rBlockNr * m_aMemoHeader.db_size);
|
|
|
|
|
m_pMemoStream->SeekRel(4L);
|
|
|
|
|
m_pMemoStream->Read(sHeader,4);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
ULONG nOldSize;
|
|
|
|
|
if (m_aMemoHeader.db_typ == MemoFoxPro)
|
|
|
|
|
nOldSize = ((((unsigned char)sHeader[0]) * 256 +
|
|
|
|
|
(unsigned char)sHeader[1]) * 256 +
|
|
|
|
|
(unsigned char)sHeader[2]) * 256 +
|
|
|
|
|
(unsigned char)sHeader[3];
|
|
|
|
|
else
|
|
|
|
|
nOldSize = ((((unsigned char)sHeader[3]) * 256 +
|
|
|
|
|
(unsigned char)sHeader[2]) * 256 +
|
|
|
|
|
(unsigned char)sHeader[1]) * 256 +
|
|
|
|
|
(unsigned char)sHeader[0] - 8;
|
|
|
|
|
|
|
|
|
|
// passt die neue Laenge in die belegten Bloecke
|
|
|
|
|
ULONG nUsedBlocks = ((nSize + 8) / m_aMemoHeader.db_size) + (((nSize + 8) % m_aMemoHeader.db_size > 0) ? 1 : 0),
|
|
|
|
|
nOldUsedBlocks = ((nOldSize + 8) / m_aMemoHeader.db_size) + (((nOldSize + 8) % m_aMemoHeader.db_size > 0) ? 1 : 0);
|
|
|
|
|
bAppend = nUsedBlocks > nOldUsedBlocks;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bAppend)
|
|
|
|
|
{
|
|
|
|
|
ULONG nStreamSize;
|
2000-11-16 09:47:23 +00:00
|
|
|
|
nStreamSize = m_pMemoStream->Seek(STREAM_SEEK_TO_END);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// letzten block auffuellen
|
|
|
|
|
rBlockNr = (nStreamSize / m_aMemoHeader.db_size) + ((nStreamSize % m_aMemoHeader.db_size) > 0 ? 1 : 0);
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->SetStreamSize(rBlockNr * m_aMemoHeader.db_size);
|
|
|
|
|
m_pMemoStream->Seek(STREAM_SEEK_TO_END);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Seek(rBlockNr * m_aMemoHeader.db_size);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (m_aMemoHeader.db_typ)
|
|
|
|
|
{
|
|
|
|
|
case MemodBaseIII: // dBase III-Memofeld, endet mit Ctrl-Z
|
|
|
|
|
{
|
|
|
|
|
const char cEOF = (char) 0x1a;
|
|
|
|
|
nSize++;
|
|
|
|
|
|
|
|
|
|
// if (pData)
|
|
|
|
|
// {
|
2000-11-16 09:47:23 +00:00
|
|
|
|
// m_pMemoStream->Write((const char*) pData->getConstArray(), pData->getLength());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Write(aStr.GetBuffer(), aStr.Len());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// }
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pMemoStream) << cEOF << cEOF;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
} break;
|
|
|
|
|
case MemoFoxPro:
|
|
|
|
|
case MemodBaseIV: // dBase IV-Memofeld mit Laengenangabe
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pMemoStream) << (BYTE)0xFF
|
2000-09-18 15:18:56 +00:00
|
|
|
|
<< (BYTE)0xFF
|
|
|
|
|
<< (BYTE)0x08;
|
|
|
|
|
|
|
|
|
|
UINT32 nWriteSize = nSize;
|
|
|
|
|
if (m_aMemoHeader.db_typ == MemoFoxPro)
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pMemoStream) << (BYTE) 0x01; // ((pData = NULL) ? 0x01 : 0x00);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
for (int i = 4; i > 0; nWriteSize >>= 8)
|
|
|
|
|
nHeader[--i] = (BYTE) (nWriteSize % 256);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
(*m_pMemoStream) << (BYTE) 0x00;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
nWriteSize += 8;
|
|
|
|
|
for (int i = 0; i < 4; nWriteSize >>= 8)
|
|
|
|
|
nHeader[i++] = (BYTE) (nWriteSize % 256);
|
|
|
|
|
}
|
|
|
|
|
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Write(nHeader,4);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// if (pData)
|
|
|
|
|
// {
|
2000-11-16 09:47:23 +00:00
|
|
|
|
// m_pMemoStream->Write((const char*) pData->getConstArray(), pData->getLength());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Write(aStr.GetBuffer(), aStr.Len());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// }
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Flush();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Schreiben der neuen Blocknummer
|
|
|
|
|
if (bAppend)
|
|
|
|
|
{
|
2000-11-16 09:47:23 +00:00
|
|
|
|
nStreamSize = m_pMemoStream->Seek(STREAM_SEEK_TO_END);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
m_aMemoHeader.db_next = (nStreamSize / m_aMemoHeader.db_size) + ((nStreamSize % m_aMemoHeader.db_size) > 0 ? 1 : 0);
|
|
|
|
|
|
|
|
|
|
// Schreiben der neuen Blocknummer
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pMemoStream->Seek(0L);
|
|
|
|
|
(*m_pMemoStream) << m_aMemoHeader.db_next;
|
|
|
|
|
m_pMemoStream->Flush();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
return sal_True;
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ODbaseTable::AllocBuffer()
|
|
|
|
|
{
|
|
|
|
|
UINT16 nSize = m_aHeader.db_slng;
|
|
|
|
|
OSL_ENSHURE(nSize > 0, "Size too small");
|
|
|
|
|
|
|
|
|
|
if (m_nBufferSize != nSize)
|
|
|
|
|
{
|
|
|
|
|
delete m_pBuffer;
|
|
|
|
|
m_pBuffer = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Falls noch kein Puffer vorhanden: allozieren:
|
|
|
|
|
if (m_pBuffer == NULL && nSize)
|
|
|
|
|
{
|
|
|
|
|
m_nBufferSize = nSize;
|
|
|
|
|
m_pBuffer = new BYTE[m_nBufferSize+1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// -------------------------------------------------------------------------
|
2000-10-30 07:07:33 +00:00
|
|
|
|
Reference<XPropertySet> ODbaseTable::isUniqueByColumnName(const ::rtl::OUString& _rColName)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
if(!m_pIndexes)
|
|
|
|
|
refreshIndexes();
|
2000-10-30 07:07:33 +00:00
|
|
|
|
Reference<XPropertySet> xIndex;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
for(sal_Int32 i=0;i<m_pIndexes->getCount();++i)
|
|
|
|
|
{
|
|
|
|
|
m_pIndexes->getByIndex(i) >>= xIndex;
|
2000-10-30 07:07:33 +00:00
|
|
|
|
if(getBOOL(xIndex->getPropertyValue(PROPERTY_ISUNIQUE)))
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
Reference<XNameAccess> xCols(Reference<XColumnsSupplier>(xIndex,UNO_QUERY)->getColumns());
|
|
|
|
|
if(xCols->hasByName(_rColName))
|
|
|
|
|
return xIndex;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-10-30 07:07:33 +00:00
|
|
|
|
return Reference<XPropertySet>();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
double toDouble(const ByteString& rString)
|
|
|
|
|
{
|
|
|
|
|
static International aInter(LANGUAGE_ENGLISH);
|
|
|
|
|
static int nErrno=0;
|
2000-09-29 14:30:09 +00:00
|
|
|
|
BOOL bInitialized = sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if (!bInitialized)
|
|
|
|
|
{ // ensure that the two members we're interested in are really set
|
|
|
|
|
// (if the system doesn't know the locale en_US aIntl would be initialized with the
|
|
|
|
|
// system language which may be anything - which we don't want ...)
|
|
|
|
|
// 74342 - 21.03.00 - FS
|
|
|
|
|
aInter.SetNumThousandSep(',');
|
|
|
|
|
aInter.SetNumDecimalSep('.');
|
|
|
|
|
bInitialized = TRUE;
|
|
|
|
|
}
|
|
|
|
|
return SolarMath::StringToDouble(UniString(rString,gsl_getSystemTextEncoding()).GetBuffer(),aInter,nErrno);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
BOOL ODbaseTable::UpdateBuffer(OValueVector& rRow, OValueRow pOrgRow,const Reference<XIndexAccess>& _xCols)
|
|
|
|
|
{
|
|
|
|
|
USHORT nByteOffset = 1;
|
|
|
|
|
|
|
|
|
|
// Felder aktualisieren:
|
2000-10-30 07:07:33 +00:00
|
|
|
|
Reference<XPropertySet> xCol;
|
|
|
|
|
Reference<XPropertySet> xIndex;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
USHORT i;
|
|
|
|
|
::rtl::OUString aColName;
|
2000-10-30 07:07:33 +00:00
|
|
|
|
::std::vector< Reference<XPropertySet> > aIndexedCols(m_pColumns->getCount());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2000-10-11 09:48:50 +00:00
|
|
|
|
::comphelper::UStringMixEqual aCase(isCaseSensitive());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// first search a key that exist already in the table
|
|
|
|
|
for (i = 0; i < m_pColumns->getCount(); i++)
|
|
|
|
|
{
|
|
|
|
|
m_pColumns->getByIndex(i) >>= xCol;
|
2000-10-30 07:07:33 +00:00
|
|
|
|
xCol->getPropertyValue(PROPERTY_NAME) >>= aColName;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// const SdbFILEColumn *pColumn = (const SdbFILEColumn *)(*aOriginalColumns)[i];
|
|
|
|
|
sal_Int32 nPos = 0;
|
|
|
|
|
for(;nPos<_xCols->getCount();++nPos)
|
|
|
|
|
{
|
2000-10-30 07:07:33 +00:00
|
|
|
|
Reference<XPropertySet> xFindCol;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
_xCols->getByIndex(nPos) >>= xFindCol;
|
2000-10-30 07:07:33 +00:00
|
|
|
|
if(aCase(getString(xFindCol->getPropertyValue(PROPERTY_NAME)),aColName))
|
2000-09-18 15:18:56 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (nPos >= _xCols->getCount())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
++nPos;
|
|
|
|
|
xIndex = isUniqueByColumnName(aColName);
|
|
|
|
|
aIndexedCols[i] = xIndex;
|
|
|
|
|
if (xIndex.is())
|
|
|
|
|
{
|
2000-09-29 14:30:09 +00:00
|
|
|
|
// first check if the value is different to the old one and when if it conform to the index
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if(pOrgRow.isValid() && (rRow[nPos].isNull() || rRow[nPos] == (*pOrgRow)[nPos]))
|
|
|
|
|
continue;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// ODbVariantRef xVar = (pVal == NULL) ? new ODbVariant() : pVal;
|
|
|
|
|
Reference<XUnoTunnel> xTunnel(xIndex,UNO_QUERY);
|
|
|
|
|
OSL_ENSHURE(xTunnel.is(),"No TunnelImplementation!");
|
|
|
|
|
ODbaseIndex* pIndex = (ODbaseIndex*)xTunnel->getSomething(ODbaseIndex::getUnoTunnelImplementationId());
|
|
|
|
|
OSL_ENSHURE(pIndex,"ODbaseTable::UpdateBuffer: No Index returned!");
|
|
|
|
|
|
|
|
|
|
if (pIndex->Find(0,rRow[nPos]))
|
|
|
|
|
{
|
|
|
|
|
// es existiert kein eindeutiger Wert
|
|
|
|
|
// String aText = String(SdbResId(STR_VALUE_NOTUNIQUE));
|
|
|
|
|
// aText.SearchAndReplace(String::CreateFromAscii("#"),pColumn->GetName());
|
|
|
|
|
// String strDetailed = String(SdbResId(STR_DBF_DUPL_VALUE_INFO));
|
|
|
|
|
// strDetailed.SearchAndReplace(String::CreateFromAscii("$col$"),pColumn->GetName());
|
|
|
|
|
// aStatus.Set(SDB_STAT_ERROR,
|
|
|
|
|
// String::CreateFromAscii("01000"),
|
|
|
|
|
// aStatus.CreateErrorMessage(aText),
|
|
|
|
|
// 0, strDetailed );
|
2000-09-29 14:30:09 +00:00
|
|
|
|
return sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// when we are here there is no double key in the table
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < m_pColumns->getCount(); i++)
|
|
|
|
|
{
|
|
|
|
|
m_pColumns->getByIndex(i) >>= xCol;
|
2000-10-30 07:07:33 +00:00
|
|
|
|
xCol->getPropertyValue(PROPERTY_NAME) >>= aColName;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Laengen je nach Datentyp:
|
|
|
|
|
// nyi: eine zentrale Funktion, die die Laenge liefert!
|
2000-10-30 07:07:33 +00:00
|
|
|
|
USHORT nLen = (USHORT)getINT32(xCol->getPropertyValue(PROPERTY_PRECISION));
|
|
|
|
|
sal_Int32 nType = getINT32(xCol->getPropertyValue(PROPERTY_TYPE));
|
2000-09-18 15:18:56 +00:00
|
|
|
|
switch (nType)
|
|
|
|
|
{
|
|
|
|
|
case DataType::DATE: nLen = 8; break;
|
|
|
|
|
case DataType::DECIMAL:
|
2000-10-30 07:07:33 +00:00
|
|
|
|
nLen = SvDbaseConverter::ConvertPrecisionToDbase(nLen,getINT32(xCol->getPropertyValue(PROPERTY_SCALE)));
|
2000-09-18 15:18:56 +00:00
|
|
|
|
break; // das Vorzeichen und das Komma
|
|
|
|
|
case DataType::BIT: nLen = 1; break;
|
|
|
|
|
case DataType::LONGVARCHAR:nLen = 10; break;
|
|
|
|
|
default: break;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sal_Int32 nPos = 0;
|
|
|
|
|
for(;nPos<_xCols->getCount();++nPos)
|
|
|
|
|
{
|
2000-10-30 07:07:33 +00:00
|
|
|
|
Reference<XPropertySet> xFindCol;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
_xCols->getByIndex(nPos) >>= xFindCol;
|
2000-10-30 07:07:33 +00:00
|
|
|
|
if(aCase(getString(xFindCol->getPropertyValue(PROPERTY_NAME)),aColName))
|
2000-09-18 15:18:56 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nPos >= _xCols->getCount())
|
|
|
|
|
{
|
|
|
|
|
nByteOffset += nLen;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
++nPos; // the row values start at 1
|
|
|
|
|
if (aIndexedCols[i].is())
|
|
|
|
|
{
|
|
|
|
|
Reference<XUnoTunnel> xTunnel(aIndexedCols[i],UNO_QUERY);
|
|
|
|
|
OSL_ENSHURE(xTunnel.is(),"No TunnelImplementation!");
|
|
|
|
|
ODbaseIndex* pIndex = (ODbaseIndex*)xTunnel->getSomething(ODbaseIndex::getUnoTunnelImplementationId());
|
|
|
|
|
OSL_ENSHURE(pIndex,"ODbaseTable::UpdateBuffer: No Index returned!");
|
|
|
|
|
// Update !!
|
|
|
|
|
if (pOrgRow.isValid() && !rRow[nPos].isNull() )//&& pVal->isModified())
|
|
|
|
|
pIndex->Update(m_nFilePos,(*pOrgRow)[nPos],rRow[nPos]);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// ODbVariantRef xVar = (pVal == NULL) ? new ODbVariant() : pVal;
|
|
|
|
|
pIndex->Insert(m_nFilePos,rRow[nPos]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ist die Variable ueberhaupt gebunden?
|
2000-09-29 14:30:09 +00:00
|
|
|
|
if (!rRow[nPos].isBound() )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
// Nein - naechstes Feld.
|
|
|
|
|
nByteOffset += nLen;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char* pData = (char *)(m_pBuffer + nByteOffset);
|
|
|
|
|
if (rRow[nPos].isNull())
|
|
|
|
|
{
|
|
|
|
|
memset(pData,' ',nLen); // Zuruecksetzen auf NULL
|
|
|
|
|
nByteOffset += nLen;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
switch (nType)
|
|
|
|
|
{
|
|
|
|
|
case DataType::DATE:
|
|
|
|
|
{
|
|
|
|
|
::com::sun::star::util::Date aDate = DateConversion::toDate(rRow[nPos]);
|
|
|
|
|
char s[9];
|
|
|
|
|
sprintf(s,"%04d%02d%02d",
|
|
|
|
|
(int)aDate.Year,
|
|
|
|
|
(int)aDate.Month,
|
|
|
|
|
(int)aDate.Day);
|
|
|
|
|
|
|
|
|
|
// Genau 8 Byte kopieren:
|
|
|
|
|
strncpy(pData,s,sizeof s - 1);
|
|
|
|
|
} break;
|
|
|
|
|
case DataType::DECIMAL:
|
|
|
|
|
{
|
|
|
|
|
memset(pData,' ',nLen); // Zuruecksetzen auf NULL
|
|
|
|
|
|
|
|
|
|
double n = rRow[nPos];
|
|
|
|
|
|
2000-10-30 07:07:33 +00:00
|
|
|
|
int nPrecision = (int)getINT32(xCol->getPropertyValue(PROPERTY_PRECISION));
|
|
|
|
|
int nScale = (int)getINT32(xCol->getPropertyValue(PROPERTY_SCALE));
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// ein const_cast, da GetFormatPrecision am SvNumberFormat nicht const ist, obwohl es das eigentlich
|
|
|
|
|
// sein koennte und muesste
|
|
|
|
|
|
|
|
|
|
String aString;
|
|
|
|
|
SolarMath::DoubleToString(aString,n,'F',nScale,'.');
|
|
|
|
|
ByteString aDefaultValue(aString,gsl_getSystemTextEncoding());
|
2000-09-29 14:30:09 +00:00
|
|
|
|
BOOL bValidLength = sal_False;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if (aDefaultValue.Len() <= nLen)
|
|
|
|
|
{
|
|
|
|
|
strncpy(pData,aDefaultValue.GetBuffer(),nLen);
|
|
|
|
|
// write the resulting double back
|
|
|
|
|
rRow[nPos] = toDouble(aDefaultValue);
|
|
|
|
|
bValidLength = TRUE;
|
|
|
|
|
}
|
|
|
|
|
if (!bValidLength)
|
|
|
|
|
{
|
|
|
|
|
// String strError(SdbResId(STR_DBF_INVALID_FIELD_VALUE));
|
|
|
|
|
// strError.SearchAndReplace(String::CreateFromAscii("$name$"), pColumn->GetName());
|
|
|
|
|
//
|
|
|
|
|
// String strDetailedInformation(SdbResId(STR_DBF_INVALID_FIELD_VALUE_DECIMAL));
|
|
|
|
|
// strDetailedInformation.SearchAndReplace(String::CreateFromAscii("$name$"), pColumn->GetName());
|
|
|
|
|
// strDetailedInformation.SearchAndReplace(String::CreateFromAscii("#length#"), nPrecision);
|
|
|
|
|
// strDetailedInformation.SearchAndReplace(String::CreateFromAscii("#scale#"), nScale);
|
|
|
|
|
// aStatus.Set(SDB_STAT_ERROR, String::CreateFromAscii("S1000"), aStatus.CreateErrorMessage(strError), 0, strDetailedInformation);
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case DataType::BIT:
|
|
|
|
|
*pData = rRow[nPos].getBool() ? 'T' : 'F';
|
|
|
|
|
break;
|
|
|
|
|
case DataType::LONGVARCHAR:
|
|
|
|
|
{
|
|
|
|
|
char cNext = pData[nLen]; // merken und temporaer durch 0 ersetzen
|
|
|
|
|
pData[nLen] = '\0'; // das geht, da der Puffer immer ein Zeichen groesser ist ...
|
|
|
|
|
|
|
|
|
|
ULONG nBlockNo = strtol((const char *)pData,NULL,10); // Blocknummer lesen
|
|
|
|
|
|
|
|
|
|
// Naechstes Anfangszeichen wieder restaurieren:
|
|
|
|
|
pData[nLen] = cNext;
|
2000-11-16 09:47:23 +00:00
|
|
|
|
if (!m_pMemoStream || !WriteMemo(rRow[nPos], nBlockNo))
|
2000-09-18 15:18:56 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ByteString aStr;
|
|
|
|
|
ByteString aBlock(ByteString::CreateFromInt32(nBlockNo));
|
|
|
|
|
aStr.Expand(nLen - aBlock.Len(), '0');
|
|
|
|
|
aStr += aBlock;
|
2000-09-29 14:30:09 +00:00
|
|
|
|
aStr.Convert(gsl_getSystemTextEncoding(),getConnection()->getTextEncoding());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Zeichen kopieren:
|
|
|
|
|
memset(pData,' ',nLen); // Zuruecksetzen auf NULL
|
|
|
|
|
memcpy(pData, aStr.GetBuffer(), nLen);
|
|
|
|
|
} break;
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
memset(pData,' ',nLen); // Zuruecksetzen auf NULL
|
2000-09-29 14:30:09 +00:00
|
|
|
|
ByteString aStr(rRow[nPos].getString().getStr(),getConnection()->getTextEncoding());
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Zeichen kopieren:
|
|
|
|
|
memcpy(pData, aStr.GetBuffer(), min(nLen,aStr.Len()));
|
|
|
|
|
} break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch ( ... )
|
|
|
|
|
{
|
|
|
|
|
// String strError(SdbResId(STR_DBF_INVALID_FIELD_VALUE));
|
|
|
|
|
// strError.SearchAndReplace(String::CreateFromAscii("$name$"), pColumn->GetName());
|
|
|
|
|
// aStatus.Set(SDB_STAT_ERROR, String::CreateFromAscii("S1000"), aStatus.CreateErrorMessage(strError), 0, String());
|
|
|
|
|
}
|
|
|
|
|
// if (aStatus.IsError())
|
|
|
|
|
// break;
|
|
|
|
|
// Und weiter ...
|
|
|
|
|
nByteOffset += nLen;
|
|
|
|
|
}
|
|
|
|
|
return sal_True;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
BOOL ODbaseTable::WriteBuffer()
|
|
|
|
|
{
|
|
|
|
|
OSL_ENSHURE(m_nFilePos >= 1,"SdbDBFCursor::FileFetchRow: ungueltige Record-Position");
|
|
|
|
|
|
|
|
|
|
// Auf gewuenschten Record positionieren:
|
|
|
|
|
long nPos = m_aHeader.db_kopf + (long)(m_nFilePos-1) * m_aHeader.db_slng;
|
2000-11-16 09:47:23 +00:00
|
|
|
|
m_pFileStream->Seek(nPos);
|
|
|
|
|
return m_pFileStream->Write((char*) m_pBuffer, m_aHeader.db_slng) > 0;
|
2000-10-11 09:48:50 +00:00
|
|
|
|
}
|
2000-10-30 07:07:33 +00:00
|
|
|
|
// -----------------------------------------------------------------------------
|