2000-09-18 15:18:56 +00:00
/*************************************************************************
*
* $ RCSfile : DTable . cxx , v $
*
2001-10-12 14:21:00 +00:00
* $ Revision : 1.66 $
2000-09-18 15:18:56 +00:00
*
2001-10-12 14:21:00 +00:00
* last change : $ Author : hr $ $ Date : 2001 - 10 - 12 15 : 21 : 00 $
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 _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
2001-03-15 07:47:25 +00:00
# ifndef _COMPHELPER_EXTRACT_HXX_
# include <comphelper/extract.hxx>
2000-09-18 15:18:56 +00:00
# endif
2000-12-10 18:25:56 +00:00
# ifndef _DBHELPER_DBEXCEPTION_HXX_
# include <connectivity/dbexception.hxx>
# endif
2000-12-06 11:07:47 +00:00
# ifndef _DBHELPER_DBCONVERSION_HXX_
2000-12-10 18:25:56 +00:00
# include <connectivity/dbconversion.hxx>
2000-12-06 11:07:47 +00:00
# endif
2001-03-28 10:32:43 +00:00
# ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
# include <com/sun/star/lang/DisposedException.hpp>
# endif
# ifndef _COMPHELPER_PROPERTY_HXX_
# include <comphelper/property.hxx>
# endif
# ifndef _UNOTOOLS_TEMPFILE_HXX
# include <unotools/tempfile.hxx>
# endif
2001-05-28 12:03:37 +00:00
# ifndef _UNOTOOLS_UCBHELPER_HXX
# include <unotools/ucbhelper.hxx>
# endif
2001-03-28 10:32:43 +00:00
# ifndef _COMPHELPER_TYPES_HXX_
# include <comphelper/types.hxx>
# endif
2001-05-28 12:03:37 +00:00
# ifndef _CONNECTIVITY_SDBCX_COLUMN_HXX_
# include "connectivity/PColumn.hxx"
# endif
2000-09-18 15:18:56 +00:00
2001-10-12 14:21:00 +00:00
# include <algorithm>
2001-05-18 07:51:34 +00:00
using namespace : : comphelper ;
2000-09-18 15:18:56 +00:00
using namespace connectivity ;
2001-03-30 11:46:36 +00:00
using namespace connectivity : : sdbcx ;
2000-09-18 15:18:56 +00:00
using namespace connectivity : : dbase ;
using namespace connectivity : : file ;
2000-12-10 18:25:56 +00:00
using namespace : : ucb ;
2001-03-28 10:32:43 +00:00
using namespace : : utl ;
2000-12-10 18:25:56 +00:00
using namespace : : cppu ;
using namespace : : dbtools ;
2000-09-18 15:18:56 +00:00
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 ( )
{
2001-09-19 10:03:04 +00:00
OSL_ENSURE ( m_pFileStream , " No Stream available! " ) ;
if ( ! m_pFileStream )
return ;
2001-08-02 06:59:15 +00:00
sal_Bool bError = sal_False ;
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
2001-08-02 06:59:15 +00:00
BYTE nType = 0 ;
2000-12-10 18:25:56 +00:00
( * m_pFileStream ) > > nType ;
2001-08-02 06:59:15 +00:00
if ( ERRCODE_NONE ! = m_pFileStream - > GetErrorCode ( ) )
throwInvalidDbaseFormat ( ) ;
2000-12-10 18:25:56 +00:00
m_pFileStream - > Read ( ( char * ) ( & m_aHeader . db_aedat ) , 3 * sizeof ( BYTE ) ) ;
2001-08-02 06:59:15 +00:00
if ( ERRCODE_NONE ! = m_pFileStream - > GetErrorCode ( ) )
throwInvalidDbaseFormat ( ) ;
2000-11-16 09:47:23 +00:00
( * m_pFileStream ) > > m_aHeader . db_anz ;
2001-08-02 06:59:15 +00:00
if ( ERRCODE_NONE ! = m_pFileStream - > GetErrorCode ( ) )
throwInvalidDbaseFormat ( ) ;
2000-11-16 09:47:23 +00:00
( * m_pFileStream ) > > m_aHeader . db_kopf ;
2001-08-02 06:59:15 +00:00
if ( ERRCODE_NONE ! = m_pFileStream - > GetErrorCode ( ) )
throwInvalidDbaseFormat ( ) ;
2000-11-16 09:47:23 +00:00
( * m_pFileStream ) > > m_aHeader . db_slng ;
2001-08-02 06:59:15 +00:00
if ( ERRCODE_NONE ! = m_pFileStream - > GetErrorCode ( ) )
throwInvalidDbaseFormat ( ) ;
2000-12-10 18:25:56 +00:00
m_pFileStream - > Read ( ( char * ) ( & m_aHeader . db_frei ) , 20 * sizeof ( BYTE ) ) ;
2001-08-02 06:59:15 +00:00
if ( ERRCODE_NONE ! = m_pFileStream - > GetErrorCode ( ) )
throwInvalidDbaseFormat ( ) ;
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
{
2000-12-10 18:25:56 +00:00
// no dbase file
2001-08-02 06:59:15 +00:00
throwInvalidDbaseFormat ( ) ;
2000-09-18 15:18:56 +00:00
}
else
{
// Konsistenzpruefung des Header:
2000-12-10 18:25:56 +00:00
m_aHeader . db_typ = ( DBFType ) nType ;
2000-09-18 15:18:56 +00:00
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 :
2000-12-10 18:25:56 +00:00
{
2001-08-02 06:59:15 +00:00
throwInvalidDbaseFormat ( ) ;
2000-09-18 15:18:56 +00:00
}
}
}
}
// -------------------------------------------------------------------------
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
2001-05-30 09:44:16 +00:00
if ( ! m_aColumns . isValid ( ) )
m_aColumns = new OSQLColumns ( ) ;
else
m_aColumns - > clear ( ) ;
2001-03-28 10:32:43 +00:00
m_aTypes . clear ( ) ;
m_aPrecisions . clear ( ) ;
m_aScales . clear ( ) ;
2000-09-18 15:18:56 +00:00
// Anzahl Felder:
2000-12-08 11:55:13 +00:00
sal_Int32 nFieldCount = ( m_aHeader . db_kopf - 1 ) / 32 - 1 ;
2001-08-24 05:05:37 +00:00
m_aColumns - > reserve ( nFieldCount ) ;
m_aTypes . reserve ( nFieldCount ) ;
m_aPrecisions . reserve ( nFieldCount ) ;
m_aScales . reserve ( nFieldCount ) ;
2000-09-18 15:18:56 +00:00
String aStrFieldName ; aStrFieldName . AssignAscii ( " Column " ) ;
sal_Int32 nFieldCnt = 0 ;
: : rtl : : OUString aTypeName ;
2001-08-24 05:05:37 +00:00
static const : : rtl : : OUString sVARCHAR = : : rtl : : OUString : : createFromAscii ( " VARCHAR " ) ;
sal_Bool bCase = getConnection ( ) - > getMetaData ( ) - > storesMixedCaseQuotedIdentifiers ( ) ;
2000-09-18 15:18:56 +00:00
2000-12-08 11:55:13 +00:00
for ( sal_Int32 i = 0 ; i < nFieldCount ; i + + )
2000-09-18 15:18:56 +00:00
{
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
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
sal_Int32 nPrecision = aDBFColumn . db_flng ;
sal_Int32 eType ;
switch ( aDBFColumn . db_typ )
{
case ' C ' :
eType = DataType : : VARCHAR ;
2001-08-24 05:05:37 +00:00
aTypeName = sVARCHAR ;
2000-09-18 15:18:56 +00:00
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 ;
}
2001-08-24 05:05:37 +00:00
// 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;
//
// }
sdbcx : : OColumn * pColumn = new sdbcx : : OColumn ( aColumnName ,
aTypeName ,
: : rtl : : OUString ( ) ,
ColumnValue : : NULLABLE ,
nPrecision ,
aDBFColumn . db_dez ,
eType ,
sal_False ,
sal_False ,
sal_False ,
bCase ) ;
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 ) ;
2000-11-27 07:00:26 +00:00
m_aTypes . push_back ( eType ) ;
m_aPrecisions . push_back ( nPrecision ) ;
m_aScales . push_back ( aDBFColumn . db_dez ) ;
2000-09-18 15:18:56 +00:00
}
}
// -------------------------------------------------------------------------
2001-09-25 12:12:51 +00:00
ODbaseTable : : ODbaseTable ( sdbcx : : OCollection * _pTables , ODbaseConnection * _pConnection )
: ODbaseTable_BASE ( _pTables , _pConnection )
2000-12-10 18:25:56 +00:00
, m_pMemoStream ( NULL )
, m_bWriteableMemo ( sal_False )
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
}
// -------------------------------------------------------------------------
2001-09-25 12:12:51 +00:00
ODbaseTable : : ODbaseTable ( sdbcx : : OCollection * _pTables , ODbaseConnection * _pConnection ,
2000-09-18 15:18:56 +00:00
const : : rtl : : OUString & _Name ,
const : : rtl : : OUString & _Type ,
const : : rtl : : OUString & _Description ,
const : : rtl : : OUString & _SchemaName ,
const : : rtl : : OUString & _CatalogName
2001-09-25 12:12:51 +00:00
) : ODbaseTable_BASE ( _pTables , _pConnection , _Name ,
2000-09-18 15:18:56 +00:00
_Type ,
_Description ,
_SchemaName ,
_CatalogName )
2000-11-17 06:37:01 +00:00
, m_pMemoStream ( NULL )
2000-12-08 11:55:13 +00:00
, m_bWriteableMemo ( sal_False )
2001-02-22 12:53:00 +00:00
{
}
2001-07-17 11:37:19 +00:00
2001-02-22 12:53:00 +00:00
// -----------------------------------------------------------------------------
void ODbaseTable : : construct ( )
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 ;
2001-08-10 10:05:34 +00:00
String sFileName ( getEntry ( m_pConnection , m_Name ) ) ;
2000-09-18 15:18:56 +00:00
2000-12-10 18:25:56 +00:00
INetURLObject aURL ;
aURL . SetURL ( sFileName ) ;
2000-09-18 15:18:56 +00:00
2000-12-10 18:25:56 +00:00
OSL_ENSURE ( aURL . getExtension ( ) = = m_pConnection - > getExtension ( ) ,
" ODbaseTable::ODbaseTable: invalid extension! " ) ;
// getEntry is expected to ensure the corect file name
2000-11-16 09:47:23 +00:00
2001-07-17 11:37:19 +00:00
m_pFileStream = createStream_simpleError ( sFileName , STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE ) ;
2000-09-18 15:18:56 +00:00
2000-12-10 18:25:56 +00:00
if ( ! ( m_bWriteable = ( NULL ! = m_pFileStream ) ) )
2001-07-17 11:37:19 +00:00
m_pFileStream = createStream_simpleError ( sFileName , 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 ( ) ;
2001-03-01 09:56:00 +00:00
if ( HasMemoFields ( ) )
2000-09-18 15:18:56 +00:00
{
2001-03-01 09:56:00 +00:00
// Memo-Dateinamen bilden (.DBT):
// nyi: Unschoen fuer Unix und Mac!
2000-09-18 15:18:56 +00:00
2001-03-01 09:56:00 +00:00
if ( m_aHeader . db_typ = = FoxProMemo ) // foxpro uses another extension
aURL . SetExtension ( String : : CreateFromAscii ( " fpt " ) ) ;
else
aURL . SetExtension ( String : : CreateFromAscii ( " dbt " ) ) ;
2000-12-08 11:55:13 +00:00
2001-03-01 09:56:00 +00:00
// Wenn die Memodatei nicht gefunden wird, werden die Daten trotzdem angezeigt
// allerdings koennen keine Updates durchgefuehrt werden
// jedoch die Operation wird ausgefuehrt
2001-07-17 11:37:19 +00:00
m_pMemoStream = createStream_simpleError ( aURL . GetMainURL ( INetURLObject : : NO_DECODE ) , STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE ) ;
2001-03-01 09:56:00 +00:00
if ( ! ( m_bWriteableMemo = ( NULL ! = m_pMemoStream ) ) )
2001-07-17 11:37:19 +00:00
m_pMemoStream = createStream_simpleError ( aURL . GetMainURL ( INetURLObject : : NO_DECODE ) , STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYNONE ) ;
2001-03-01 09:56:00 +00:00
if ( m_pMemoStream )
ReadMemoHeader ( ) ;
}
2001-05-30 09:44:16 +00:00
// if(!m_pColumns && (!m_aColumns.isValid() || !m_aColumns->size()))
fillColumns ( ) ;
2000-09-18 15:18:56 +00:00
2001-03-01 09:56:00 +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
2001-03-01 09:56:00 +00:00
// Buffersize abhaengig von der Filegroesse
m_pFileStream - > SetBufferSize ( nFileSize > 1000000 ? 32768 :
nFileSize > 100000 ? 16384 :
nFileSize > 10000 ? 4096 : 1024 ) ;
2000-12-08 11:55:13 +00:00
2001-03-01 09:56:00 +00:00
if ( m_pMemoStream )
{
// Puffer genau auf Laenge eines Satzes stellen
m_pMemoStream - > Seek ( STREAM_SEEK_TO_END ) ;
nFileSize = m_pMemoStream - > Tell ( ) ;
m_pMemoStream - > Seek ( STREAM_SEEK_TO_BEGIN ) ;
2000-12-08 11:55:13 +00:00
2001-03-01 09:56:00 +00:00
// Buffersize abhaengig von der Filegroesse
m_pMemoStream - > SetBufferSize ( nFileSize > 1000000 ? 32768 :
nFileSize > 100000 ? 16384 :
nFileSize > 10000 ? 4096 :
m_aMemoHeader . db_size ) ;
}
2000-09-18 15:18:56 +00:00
2001-03-01 09:56:00 +00:00
AllocBuffer ( ) ;
2000-09-18 15:18:56 +00:00
}
}
//------------------------------------------------------------------
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 ;
}
// -------------------------------------------------------------------------
2001-08-10 10:05:34 +00:00
String ODbaseTable : : getEntry ( OConnection * _pConnection , const : : rtl : : OUString & _sName )
2000-09-18 15:18:56 +00:00
{
: : rtl : : OUString aURL ;
2001-03-30 11:07:07 +00:00
try
2000-09-18 15:18:56 +00:00
{
2001-08-10 10:05:34 +00:00
Reference < XResultSet > xDir = _pConnection - > getDir ( ) - > getStaticResultSet ( ) ;
2001-03-30 11:07:07 +00:00
Reference < XRow > xRow ( xDir , UNO_QUERY ) ;
: : rtl : : OUString sName ;
: : rtl : : OUString sExt ;
2001-08-10 10:05:34 +00:00
: : rtl : : OUString sNeededExt ( _pConnection - > getExtension ( ) ) ;
2001-03-30 11:07:07 +00:00
sal_Int32 nExtLen = sNeededExt . getLength ( ) ;
sal_Int32 nExtLenWithSep = nExtLen + 1 ;
xDir - > beforeFirst ( ) ;
while ( xDir - > next ( ) )
{
sName = xRow - > getString ( 1 ) ;
2000-12-10 18:25:56 +00:00
2001-03-30 11:07:07 +00:00
// cut the extension
sExt = sName . copy ( sName . getLength ( ) - nExtLen ) ;
sName = sName . copy ( 0 , sName . getLength ( ) - nExtLenWithSep ) ;
2000-12-10 18:25:56 +00:00
2001-03-30 11:07:07 +00:00
// name and extension have to coincide
2001-08-10 10:05:34 +00:00
if ( ( sName = = _sName ) & & ( sExt = = sNeededExt ) )
2001-03-30 11:07:07 +00:00
{
Reference < XContentAccess > xContentAccess ( xDir , UNO_QUERY ) ;
aURL = xContentAccess - > queryContentIdentifierString ( ) ;
break ;
}
2000-09-18 15:18:56 +00:00
}
2001-03-30 11:07:07 +00:00
xDir - > beforeFirst ( ) ; // move back to before first record
}
catch ( Exception & )
{
OSL_ASSERT ( 0 ) ;
2000-09-18 15:18:56 +00:00
}
2001-03-30 11:07:07 +00:00
return aURL ;
2000-09-18 15:18:56 +00:00
}
// -------------------------------------------------------------------------
void ODbaseTable : : refreshColumns ( )
{
: : osl : : MutexGuard aGuard ( m_aMutex ) ;
2001-05-02 11:57:37 +00:00
TStringVector aVector ;
2001-08-24 05:05:37 +00:00
aVector . reserve ( m_aColumns - > size ( ) ) ;
2000-09-18 15:18:56 +00:00
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 )
2001-05-07 09:37:54 +00:00
m_pColumns - > reFill ( aVector ) ;
else
m_pColumns = new ODbaseColumns ( this , m_aMutex , aVector ) ;
2000-09-18 15:18:56 +00:00
}
// -------------------------------------------------------------------------
void ODbaseTable : : refreshIndexes ( )
{
2001-05-02 11:57:37 +00:00
TStringVector aVector ;
2001-07-16 08:58:40 +00:00
if ( m_pFileStream & & ( ! m_pIndexes | | m_pIndexes - > getCount ( ) = = 0 ) )
2000-09-18 15:18:56 +00:00
{
2000-11-16 09:47:23 +00:00
INetURLObject aURL ;
2001-08-10 10:05:34 +00:00
aURL . SetURL ( getEntry ( m_pConnection , m_Name ) ) ;
2000-11-16 09:47:23 +00:00
aURL . setExtension ( String : : CreateFromAscii ( " inf " ) ) ;
2001-03-08 08:18:58 +00:00
Config aInfFile ( aURL . getFSysPath ( INetURLObject : : FSYS_DETECT ) ) ;
2000-11-16 09:47:23 +00:00
aInfFile . SetGroup ( dBASE_III_GROUP ) ;
2001-03-01 09:51:00 +00:00
USHORT nKeyCnt = aInfFile . GetKeyCount ( ) ;
2000-11-16 09:47:23 +00:00
ByteString aKeyName ;
ByteString aIndexName ;
2001-03-01 09:51:00 +00:00
for ( USHORT 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 ( ) ) ) ;
2000-12-08 11:55:13 +00:00
try
{
2001-07-16 08:58:40 +00:00
Content aCnt ( aURL . GetMainURL ( INetURLObject : : NO_DECODE ) , Reference < XCommandEnvironment > ( ) ) ;
2000-12-08 11:55:13 +00:00
if ( aCnt . isDocument ( ) )
{
aVector . push_back ( aURL . getBase ( ) ) ;
}
}
catch ( Exception & ) // a execption is thrown when no file exists
2000-11-16 09:47:23 +00:00
{
}
2000-09-18 15:18:56 +00:00
}
}
}
if ( m_pIndexes )
2001-05-30 09:44:16 +00:00
m_pIndexes - > reFill ( aVector ) ;
else
m_pIndexes = new ODbaseIndexes ( this , m_aMutex , aVector ) ;
2000-09-18 15:18:56 +00:00
}
// -------------------------------------------------------------------------
void SAL_CALL ODbaseTable : : disposing ( void )
{
OFileTable : : disposing ( ) ;
: : osl : : MutexGuard aGuard ( m_aMutex ) ;
2001-05-07 09:37:54 +00:00
m_aColumns = NULL ;
2000-09-18 15:18:56 +00:00
}
// -------------------------------------------------------------------------
Sequence < Type > SAL_CALL ODbaseTable : : getTypes ( ) throw ( RuntimeException )
{
Sequence < Type > aTypes = OTable_TYPEDEF : : getTypes ( ) ;
2001-07-20 11:21:43 +00:00
Sequence < Type > aRet ( aTypes . getLength ( ) ) ;
2000-09-18 15:18:56 +00:00
const Type * pBegin = aTypes . getConstArray ( ) ;
const Type * pEnd = pBegin + aTypes . getLength ( ) ;
sal_Int32 i = 0 ;
2001-05-31 05:11:58 +00:00
for ( ; pBegin ! = pEnd ; + + pBegin )
2000-09-18 15:18:56 +00:00
{
2001-03-28 10:32:43 +00:00
if ( ! ( * pBegin = = : : getCppuType ( ( const Reference < XKeysSupplier > * ) 0 ) | |
2001-05-30 09:44:16 +00:00
// *pBegin == ::getCppuType((const Reference<XAlterTable>*)0) ||
2000-09-18 15:18:56 +00:00
* pBegin = = : : getCppuType ( ( const Reference < XDataDescriptorFactory > * ) 0 ) ) )
{
2001-05-31 05:11:58 +00:00
aRet . getArray ( ) [ i + + ] = * pBegin ;
2000-09-18 15:18:56 +00:00
}
}
aRet . getArray ( ) [ i ] = : : getCppuType ( ( const Reference < : : com : : sun : : star : : lang : : XUnoTunnel > * ) 0 ) ;
return aRet ;
}
// -------------------------------------------------------------------------
Any SAL_CALL ODbaseTable : : queryInterface ( const Type & rType ) throw ( RuntimeException )
{
2001-03-28 10:32:43 +00:00
if ( rType = = : : getCppuType ( ( const Reference < XKeysSupplier > * ) 0 ) | |
2000-09-18 15:18:56 +00:00
rType = = : : getCppuType ( ( const Reference < XDataDescriptorFactory > * ) 0 ) )
return Any ( ) ;
2001-08-24 05:05:37 +00:00
Any aRet = OTable_TYPEDEF : : queryInterface ( rType ) ;
return aRet . hasValue ( ) ? aRet : : : cppu : : queryInterface ( rType , static_cast < : : com : : sun : : star : : lang : : XUnoTunnel * > ( this ) ) ;
2000-09-18 15:18:56 +00:00
}
//--------------------------------------------------------------------------
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 )
{
2001-08-24 05:05:37 +00:00
return ( rId . getLength ( ) = = 16 & & 0 = = rtl_compareMemory ( getUnoTunnelImplementationId ( ) . getConstArray ( ) , rId . getConstArray ( ) , 16 ) )
?
( sal_Int64 ) this
:
ODbaseTable_BASE : : getSomething ( rId ) ;
2000-09-18 15:18:56 +00:00
}
//------------------------------------------------------------------
2001-03-28 10:32:43 +00:00
sal_Bool ODbaseTable : : fetchRow ( OValueRow _rRow , const OSQLColumns & _rCols , sal_Bool _bUseTableDefs , sal_Bool bRetrieveData )
2000-09-18 15:18:56 +00:00
{
// 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 + + )
{
// Laengen je nach Datentyp:
sal_Int32 nLen ;
2000-11-27 07:00:26 +00:00
sal_Int32 nType ;
if ( _bUseTableDefs )
{
2000-12-13 14:21:14 +00:00
nLen = m_aPrecisions [ i - 1 ] ;
nType = m_aTypes [ i - 1 ] ;
2000-11-27 07:00:26 +00:00
}
else
{
2001-08-24 05:05:37 +00:00
( * aIter ) - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_PRECISION ) ) > > = nLen ;
( * aIter ) - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_TYPE ) ) > > = nType ;
2000-11-27 07:00:26 +00:00
}
2000-09-18 15:18:56 +00:00
switch ( nType )
{
case DataType : : DATE : nLen = 8 ; break ;
case DataType : : DECIMAL :
2000-11-27 07:00:26 +00:00
if ( _bUseTableDefs )
2000-12-13 14:21:14 +00:00
nLen = SvDbaseConverter : : ConvertPrecisionToDbase ( nLen , m_aScales [ i - 1 ] ) ;
2000-11-27 07:00:26 +00:00
else
2001-08-24 05:05:37 +00:00
nLen = SvDbaseConverter : : ConvertPrecisionToDbase ( nLen , getINT32 ( ( * aIter ) - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_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 ;
}
// 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 ;
2001-03-01 09:51:00 +00:00
String aStr ( pData , ( xub_StrLen ) nLen , getConnection ( ) - > getTextEncoding ( ) ) ;
2000-09-18 15:18:56 +00:00
aStr . EraseTrailingChars ( ) ;
if ( ! aStr . Len ( ) ) // keine StringLaenge, dann NULL
( * _rRow ) [ i ] . setNull ( ) ;
else
2001-08-24 05:05:37 +00:00
( * _rRow ) [ i ] = aStr ;
2000-09-18 15:18:56 +00:00
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 ] = ' ' ;
}
2001-03-01 09:51:00 +00:00
String aStr ( pData , ( xub_StrLen ) 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 ;
}
2001-03-01 09:51:00 +00:00
sal_uInt16 nYear = ( sal_uInt16 ) aStr . Copy ( 0 , 4 ) . ToInt32 ( ) ;
sal_uInt16 nMonth = ( sal_uInt16 ) aStr . Copy ( 4 , 2 ) . ToInt32 ( ) ;
sal_uInt16 nDay = ( sal_uInt16 ) aStr . Copy ( 6 , 2 ) . ToInt32 ( ) ;
2000-09-18 15:18:56 +00:00
: : com : : sun : : star : : util : : Date aDate ( nDay , nMonth , nYear ) ;
2000-12-06 11:07:47 +00:00
( * _rRow ) [ i ] = aDate ;
2000-09-18 15:18:56 +00:00
}
break ;
case DataType : : DECIMAL :
2001-05-03 06:15:56 +00:00
( * _rRow ) [ i ] = aStr ;
2000-09-18 15:18:56 +00:00
// 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 ;
}
//------------------------------------------------------------------
// -------------------------------------------------------------------------
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 ( )
{
2001-02-14 06:22:50 +00:00
OSL_ENSURE ( ! m_pFileStream , " SequenceError " ) ;
2000-09-18 15:18:56 +00:00
INetURLObject aURL ;
aURL . SetSmartProtocol ( INET_PROT_FILE ) ;
2001-08-10 10:05:34 +00:00
String aName = getEntry ( m_pConnection , m_Name ) ;
2000-10-25 12:31:00 +00:00
if ( ! aName . Len ( ) )
{
: : rtl : : OUString aIdent = m_pConnection - > getContent ( ) - > getIdentifier ( ) - > getContentIdentifier ( ) ;
2001-02-22 12:53:00 +00:00
aIdent + = : : rtl : : OUString : : createFromAscii ( " / " ) ;
2000-10-25 12:31:00 +00:00
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 ( ) ) ;
2001-07-16 08:58:40 +00:00
Content aContent ( aURL . GetMainURL ( INetURLObject : : NO_DECODE ) , Reference < XCommandEnvironment > ( ) ) ;
2000-12-08 11:55:13 +00:00
try
2000-09-18 15:18:56 +00:00
{
2000-12-08 11:55:13 +00:00
if ( aContent . isDocument ( ) )
2000-09-18 15:18:56 +00:00
{
2000-12-08 11:55:13 +00:00
// Hack fuer Bug #30609 , nur wenn das File existiert und die Laenge > 0 gibt es einen Fehler
2001-07-17 11:37:19 +00:00
SvStream * pFileStream = createStream_simpleError ( aURL . GetMainURL ( INetURLObject : : NO_DECODE ) , STREAM_READ ) ;
2000-12-08 11:55:13 +00:00
if ( pFileStream & & pFileStream - > Seek ( STREAM_SEEK_TO_END ) )
{
// aStatus.SetError(ERRCODE_IO_ALREADYEXISTS,TABLE,aFile.GetFull());
return sal_False ;
}
delete pFileStream ;
2000-09-18 15:18:56 +00:00
}
2000-12-08 11:55:13 +00:00
}
catch ( Exception & ) // a execption is thrown when no file exists
{
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
2001-07-16 08:58:40 +00:00
Content aMemo1Content ( aURL . GetMainURL ( INetURLObject : : NO_DECODE ) , Reference < XCommandEnvironment > ( ) ) ;
2000-09-18 15:18:56 +00:00
2001-03-02 12:29:11 +00:00
sal_Bool bMemoAlreadyExists = sal_False ;
try
{
bMemoAlreadyExists = aMemo1Content . isDocument ( ) ;
}
catch ( Exception & ) // a execption is thrown when no file exists
{
}
if ( bMemoAlreadyExists )
2000-09-18 15:18:56 +00:00
{
// aStatus.SetError(ERRCODE_IO_ALREADYEXISTS,MEMO,aFile.GetFull());
aURL . setExtension ( aExt ) ; // kill dbf file
2001-05-28 12:03:37 +00:00
try
{
2001-07-16 08:58:40 +00:00
Content aMemoContent ( aURL . GetMainURL ( INetURLObject : : NO_DECODE ) , Reference < XCommandEnvironment > ( ) ) ;
2001-05-28 12:03:37 +00:00
aMemoContent . executeCommand ( rtl : : OUString : : createFromAscii ( " delete " ) , bool2any ( sal_True ) ) ;
}
catch ( const Exception & )
{
: : rtl : : OUString sMessage = : : rtl : : OUString : : createFromAscii ( " [StarOffice Base dbase] The memo file ' " ) ;
sMessage + = aName ;
sMessage + = : : rtl : : OUString : : createFromAscii ( " already exists. " ) ;
throwGenericSQLException ( sMessage , static_cast < XNamed * > ( this ) ) ;
}
2000-09-18 15:18:56 +00:00
}
if ( ! CreateMemoFile ( aURL ) )
{
aURL . setExtension ( aExt ) ; // kill dbf file
2001-07-16 08:58:40 +00:00
Content aMemoContent ( aURL . GetMainURL ( INetURLObject : : NO_DECODE ) , 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
2001-07-17 11:37:19 +00:00
m_pFileStream = createStream_simpleError ( aFile . GetMainURL ( INetURLObject : : NO_DECODE ) , STREAM_READWRITE | STREAM_SHARE_DENYWRITE | STREAM_TRUNC ) ;
2000-11-16 09:47:23 +00:00
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
2001-03-01 09:51:00 +00:00
sal_Int32 nMaxFieldLength = m_pConnection - > getMetaData ( ) - > getMaxColumnNameLength ( ) ;
2000-09-18 15:18:56 +00:00
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 )
{
2001-02-14 06:22:50 +00:00
: : cppu : : extractInterface ( xCol , xColumns - > getByIndex ( i ) ) ;
OSL_ENSURE ( xCol . is ( ) , " This should be a column! " ) ;
2000-09-18 15:18:56 +00:00
char cTyp ;
2001-05-14 10:42:44 +00:00
xCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_NAME ) ) > > = aName ;
2000-09-18 15:18:56 +00:00
if ( aName . getLength ( ) > nMaxFieldLength )
{
2001-02-22 12:53:00 +00:00
: : rtl : : OUString sMsg = : : rtl : : OUString : : createFromAscii ( " Invalid column name length for column: " ) ;
sMsg + = aName ;
sMsg + = : : rtl : : OUString : : createFromAscii ( " ! " ) ;
2001-05-14 10:42:44 +00:00
throw SQLException ( sMsg , * this , OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_HY0000 ) , 1000 , Any ( ) ) ;
2000-09-18 15:18:56 +00:00
}
2001-02-28 08:15:30 +00:00
ByteString aCol ( aName . getStr ( ) , getConnection ( ) - > getTextEncoding ( ) ) ;
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
2001-05-14 10:42:44 +00:00
switch ( getINT32 ( xCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_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 :
{
2001-02-22 12:53:00 +00:00
: : rtl : : OUString sMsg = : : rtl : : OUString : : createFromAscii ( " Invalid column type for column: " ) ;
sMsg + = aName ;
sMsg + = : : rtl : : OUString : : createFromAscii ( " ! " ) ;
2001-05-14 10:42:44 +00:00
throw SQLException ( sMsg , * this , OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_HY0000 ) , 1000 , Any ( ) ) ;
2000-09-18 15:18:56 +00:00
}
}
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 ;
2001-05-14 10:42:44 +00:00
xCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_PRECISION ) ) > > = nPrecision ;
2000-09-18 15:18:56 +00:00
sal_Int32 nScale = 0 ;
2001-05-14 10:42:44 +00:00
xCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_SCALE ) ) > > = nScale ;
2000-09-18 15:18:56 +00:00
switch ( cTyp )
{
case ' C ' :
2001-02-14 06:22:50 +00:00
OSL_ENSURE ( nPrecision < 255 , " ODbaseTable::Create: Column zu lang! " ) ;
2000-09-18 15:18:56 +00:00
if ( nPrecision > 254 )
{
2001-02-22 12:53:00 +00:00
: : rtl : : OUString sMsg = : : rtl : : OUString : : createFromAscii ( " Invalid precision for column: " ) ;
sMsg + = aName ;
sMsg + = : : rtl : : OUString : : createFromAscii ( " ! " ) ;
2001-05-14 10:42:44 +00:00
throw SQLException ( sMsg , * this , OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_HY0000 ) , 1000 , Any ( ) ) ;
2000-09-18 15:18:56 +00:00
}
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 ' :
2001-02-14 06:22:50 +00:00
OSL_ENSURE ( nPrecision > = nScale ,
2000-09-18 15:18:56 +00:00
" ODbaseTable::Create: Feldl<64> nge mu<6D> gr<67> <72> er Nachkommastellen sein! " ) ;
if ( nPrecision < nScale )
{
2001-02-22 12:53:00 +00:00
: : rtl : : OUString sMsg = : : rtl : : OUString : : createFromAscii ( " Precision is less than scale for column: " ) ;
sMsg + = aName ;
sMsg + = : : rtl : : OUString : : createFromAscii ( " ! " ) ;
2001-05-14 10:42:44 +00:00
throw SQLException ( sMsg , * this , OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_HY0000 ) , 1000 , Any ( ) ) ;
2000-09-18 15:18:56 +00:00
break ;
}
2001-05-14 10:42:44 +00:00
if ( getBOOL ( xCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_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
{
2001-03-01 09:51:00 +00:00
sal_Int32 nPrec = SvDbaseConverter : : ConvertPrecisionToDbase ( nPrecision , nScale ) ;
2000-09-18 15:18:56 +00:00
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 :
2001-02-22 12:53:00 +00:00
{
: : rtl : : OUString sMsg = : : rtl : : OUString : : createFromAscii ( " Invalid column type for column: " ) ;
sMsg + = aName ;
sMsg + = : : rtl : : OUString : : createFromAscii ( " ! " ) ;
2001-05-14 10:42:44 +00:00
throw SQLException ( sMsg , * this , OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_HY0000 ) , 1000 , Any ( ) ) ;
2001-02-22 12:53:00 +00:00
}
2000-09-18 15:18:56 +00:00
}
2000-11-16 09:47:23 +00:00
m_pFileStream - > Write ( aBuffer , 14 ) ;
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
2001-07-17 11:37:19 +00:00
m_pMemoStream = createStream_simpleError ( aFile . GetMainURL ( INetURLObject : : NO_DECODE ) , STREAM_READWRITE | STREAM_SHARE_DENYWRITE ) ;
2000-11-16 09:47:23 +00:00
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 ;
}
//------------------------------------------------------------------
2001-08-10 10:05:34 +00:00
BOOL ODbaseTable : : Drop_Static ( const : : rtl : : OUString & _sUrl , sal_Bool _bHasMemoFields , OCollection * _pIndexes )
2000-09-18 15:18:56 +00:00
{
INetURLObject aURL ;
2001-08-10 10:05:34 +00:00
aURL . SetURL ( _sUrl ) ;
2000-09-18 15:18:56 +00:00
2001-06-29 07:29:14 +00:00
BOOL bDropped = FALSE ;
2000-09-18 15:18:56 +00:00
2001-07-16 08:58:40 +00:00
if ( bDropped = : : utl : : UCBContentHelper : : Kill ( aURL . GetMainURL ( INetURLObject : : NO_DECODE ) ) )
2000-09-18 15:18:56 +00:00
{
2001-08-10 10:05:34 +00:00
if ( _bHasMemoFields )
2001-06-29 07:29:14 +00:00
{ // delete the memo fields
aURL . setExtension ( String : : CreateFromAscii ( " dbt " ) ) ;
2001-07-16 08:58:40 +00:00
bDropped = : : utl : : UCBContentHelper : : Kill ( aURL . GetMainURL ( INetURLObject : : NO_DECODE ) ) ;
2001-06-29 07:29:14 +00:00
}
2000-09-18 15:18:56 +00:00
2001-06-29 07:29:14 +00:00
if ( bDropped )
2001-03-28 10:32:43 +00:00
{
2001-08-10 10:05:34 +00:00
if ( _pIndexes )
2001-06-29 07:29:14 +00:00
{
2001-08-10 10:05:34 +00:00
sal_Int32 nCount = _pIndexes - > getCount ( ) ,
2001-06-29 07:29:14 +00:00
i = 0 ;
while ( i < nCount )
{
2001-08-10 10:05:34 +00:00
_pIndexes - > dropByIndex ( i ) ;
2001-06-29 07:29:14 +00:00
}
}
// aFile.SetBase(m_Name);
aURL . setExtension ( String : : CreateFromAscii ( " inf " ) ) ;
2001-07-16 14:13:25 +00:00
// as the inf file does not necessarily exist, we aren't allowed to use UCBContentHelper::Kill
// 89711 - 16.07.2001 - frank.schoenheit@sun.com
try
{
: : ucb : : Content aDeleteContent ( aURL . GetMainURL ( INetURLObject : : NO_DECODE ) , Reference < : : com : : sun : : star : : ucb : : XCommandEnvironment > ( ) ) ;
aDeleteContent . executeCommand ( : : rtl : : OUString : : createFromAscii ( " delete " ) , makeAny ( sal_Bool ( sal_True ) ) ) ;
}
catch ( Exception & )
{
// silently ignore this ....
}
2001-03-28 10:32:43 +00:00
}
2000-09-18 15:18:56 +00:00
}
2001-08-10 10:05:34 +00:00
return bDropped ;
}
// -----------------------------------------------------------------------------
BOOL ODbaseTable : : DropImpl ( )
{
FileClose ( ) ;
refreshIndexes ( ) ; // look for indexes which must be deleted as well
BOOL bDropped = Drop_Static ( getEntry ( m_pConnection , m_Name ) , HasMemoFields ( ) , m_pIndexes ) ;
2001-06-29 07:29:14 +00:00
if ( ! bDropped )
{ // we couldn't drop the table so we have to reopen it
construct ( ) ;
if ( m_pColumns )
m_pColumns - > refresh ( ) ;
}
return bDropped ;
2000-09-18 15:18:56 +00:00
}
//------------------------------------------------------------------
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 ;
2001-06-29 07:29:14 +00:00
BOOL bInsertRow ;
2000-09-18 15:18:56 +00:00
m_nFilePos = ( ULONG ) m_aHeader . db_anz + 1 ;
2001-06-29 07:29:14 +00:00
if ( bInsertRow = UpdateBuffer ( rRow , NULL , _xCols ) )
2000-09-18 15:18:56 +00:00
{
2001-06-29 07:29:14 +00:00
m_pFileStream - > Seek ( STREAM_SEEK_TO_END ) ;
nFileSize = m_pFileStream - > Tell ( ) ;
2000-09-18 15:18:56 +00:00
2001-06-29 07:29:14 +00:00
if ( HasMemoFields ( ) & & m_pMemoStream )
{
m_pMemoStream - > Seek ( STREAM_SEEK_TO_END ) ;
nMemoFileSize = m_pMemoStream - > Tell ( ) ;
}
2000-09-18 15:18:56 +00:00
2001-06-29 07:29:14 +00:00
if ( ! WriteBuffer ( ) )
{
m_pFileStream - > SetStreamSize ( nFileSize ) ; // alte Gr<47> <72> e restaurieren
2000-09-18 15:18:56 +00:00
2001-06-29 07:29:14 +00:00
if ( HasMemoFields ( ) & & m_pMemoStream )
m_pMemoStream - > SetStreamSize ( nMemoFileSize ) ; // alte Gr<47> <72> e restaurieren
m_nFilePos = nTempPos ; // Fileposition restaurieren
}
else
{
// Anzahl Datensaetze im Header erhoehen:
m_pFileStream - > Seek ( 4L ) ;
( * m_pFileStream ) < < ( m_aHeader . db_anz + 1 ) ;
// beim AppendOnly kein Flush!
if ( bFlush )
m_pFileStream - > Flush ( ) ;
// bei Erfolg # erh<72> hen
m_aHeader . db_anz + + ;
rRow [ 0 ] = m_nFilePos ; // BOOKmark setzen
m_nFilePos = nTempPos ;
}
2000-09-18 15:18:56 +00:00
}
else
m_nFilePos = nTempPos ;
2001-06-29 07:29:14 +00:00
return bInsertRow ; ;
2000-09-18 15:18:56 +00:00
}
//------------------------------------------------------------------
2001-03-28 10:32:43 +00:00
BOOL ODbaseTable : : UpdateRow ( OValueVector & rRow , OValueRow pOrgRow , const Reference < XIndexAccess > & _xCols )
2000-09-18 15:18:56 +00:00
{
// 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:
2001-08-24 05:05:37 +00:00
long nFilePos = m_aHeader . db_kopf + ( long ) ( m_nFilePos - 1 ) * m_aHeader . db_slng ;
m_pFileStream - > Seek ( nFilePos ) ;
2000-09-18 15:18:56 +00:00
OValueRow aRow = new OValueVector ( _rCols . size ( ) ) ;
2000-11-27 07:00:26 +00:00
if ( ! fetchRow ( aRow , _rCols , TRUE , 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 + + )
{
2001-08-24 05:05:37 +00:00
Reference < XPropertySet > xIndex = isUniqueByColumnName ( i ) ;
if ( xIndex . is ( ) )
2000-09-18 15:18:56 +00:00
{
2001-08-24 05:05:37 +00:00
: : cppu : : extractInterface ( xCol , m_pColumns - > getByIndex ( i ) ) ;
OSL_ENSURE ( xCol . is ( ) , " ODbaseTable::DeleteRow column is null! " ) ;
if ( xCol . is ( ) )
2000-09-18 15:18:56 +00:00
{
2001-08-24 05:05:37 +00:00
xCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_NAME ) ) > > = aColName ;
2001-06-29 07:29:14 +00:00
Reference < XUnoTunnel > xTunnel ( xIndex , UNO_QUERY ) ;
OSL_ENSURE ( xTunnel . is ( ) , " No TunnelImplementation! " ) ;
ODbaseIndex * pIndex = ( ODbaseIndex * ) xTunnel - > getSomething ( ODbaseIndex : : getUnoTunnelImplementationId ( ) ) ;
OSL_ENSURE ( pIndex , " ODbaseTable::DeleteRow: No Index returned! " ) ;
OSQLColumns : : const_iterator aIter = _rCols . begin ( ) ;
2001-08-24 05:05:37 +00:00
sal_Int32 nPos = 1 ;
2001-06-29 07:29:14 +00:00
for ( ; aIter ! = _rCols . end ( ) ; + + aIter , + + nPos )
{
if ( aCase ( getString ( ( * aIter ) - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_REALNAME ) ) ) , aColName ) )
break ;
}
if ( aIter = = _rCols . end ( ) )
continue ;
2000-09-18 15:18:56 +00:00
2001-06-29 07:29:14 +00:00
pIndex - > Delete ( m_nFilePos , ( * aRow ) [ nPos ] ) ;
}
2000-09-18 15:18:56 +00:00
}
}
2001-08-24 05:05:37 +00:00
m_pFileStream - > Seek ( nFilePos ) ;
2001-06-29 07:29:14 +00:00
( * m_pFileStream ) < < ( BYTE ) ' * ' ; // mark the row in the table as deleted
2000-11-16 09:47:23 +00:00
m_pFileStream - > Flush ( ) ;
2001-08-24 05:05:37 +00:00
return sal_True ;
2000-09-18 15:18:56 +00:00
}
// -------------------------------------------------------------------------
2001-08-24 05:05:37 +00:00
Reference < XPropertySet > ODbaseTable : : isUniqueByColumnName ( sal_Int32 _nColumnPos )
2000-09-18 15:18:56 +00:00
{
if ( ! m_pIndexes )
refreshIndexes ( ) ;
2001-08-24 05:05:37 +00:00
if ( m_pIndexes - > hasElements ( ) )
2000-09-18 15:18:56 +00:00
{
2001-08-24 05:05:37 +00:00
Reference < XPropertySet > xCol ;
m_pColumns - > getByIndex ( _nColumnPos ) > > = xCol ;
OSL_ENSURE ( xCol . is ( ) , " ODbaseTable::UpdateBuffer column is null! " ) ;
: : rtl : : OUString sColName ;
xCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_NAME ) ) > > = sColName ;
Reference < XPropertySet > xIndex ;
for ( sal_Int32 i = 0 ; i < m_pIndexes - > getCount ( ) ; + + i )
2000-09-18 15:18:56 +00:00
{
2001-08-24 05:05:37 +00:00
: : cppu : : extractInterface ( xIndex , m_pIndexes - > getByIndex ( i ) ) ;
if ( xIndex . is ( ) & & getBOOL ( xIndex - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_ISUNIQUE ) ) ) )
{
Reference < XNameAccess > xCols ( Reference < XColumnsSupplier > ( xIndex , UNO_QUERY ) - > getColumns ( ) ) ;
if ( xCols - > hasByName ( sColName ) )
return xIndex ;
2000-09-18 15:18:56 +00:00
2001-08-24 05:05:37 +00:00
}
2000-09-18 15:18:56 +00:00
}
}
2000-10-30 07:07:33 +00:00
return Reference < XPropertySet > ( ) ;
2000-09-18 15:18:56 +00:00
}
//------------------------------------------------------------------
double toDouble ( const ByteString & rString )
{
2001-07-30 07:53:02 +00:00
int nErrno ;
return SolarMath : : StringToDouble ( UniString ( rString , gsl_getSystemTextEncoding ( ) ) . GetBuffer ( ) , ' , ' , ' . ' , nErrno ) ;
2000-09-18 15:18:56 +00:00
}
//------------------------------------------------------------------
BOOL ODbaseTable : : UpdateBuffer ( OValueVector & rRow , OValueRow pOrgRow , const Reference < XIndexAccess > & _xCols )
{
2001-03-01 09:51:00 +00:00
sal_Int32 nByteOffset = 1 ;
2000-09-18 15:18:56 +00:00
// 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 ;
2001-08-24 05:05:37 +00:00
sal_Int32 nColumnCount = m_pColumns - > getCount ( ) ;
: : std : : vector < Reference < XPropertySet > > aIndexedCols ( nColumnCount ) ;
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
2001-08-24 05:05:37 +00:00
Reference < XIndexAccess > xColumns = m_pColumns ;
2000-09-18 15:18:56 +00:00
// first search a key that exist already in the table
2001-08-24 05:05:37 +00:00
for ( i = 0 ; i < nColumnCount ; + + i )
2000-09-18 15:18:56 +00:00
{
2001-08-24 05:05:37 +00:00
sal_Int32 nPos = i ;
if ( _xCols ! = xColumns )
2000-09-18 15:18:56 +00:00
{
2001-08-24 05:05:37 +00:00
m_pColumns - > getByIndex ( i ) > > = xCol ;
OSL_ENSURE ( xCol . is ( ) , " ODbaseTable::UpdateBuffer column is null! " ) ;
xCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_NAME ) ) > > = aColName ;
for ( nPos = 0 ; nPos < _xCols - > getCount ( ) ; + + nPos )
{
Reference < XPropertySet > xFindCol ;
: : cppu : : extractInterface ( xFindCol , _xCols - > getByIndex ( nPos ) ) ;
OSL_ENSURE ( xFindCol . is ( ) , " ODbaseTable::UpdateBuffer column is null! " ) ;
if ( aCase ( getString ( xFindCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_NAME ) ) ) , aColName ) )
break ;
}
if ( nPos > = _xCols - > getCount ( ) )
continue ;
2000-09-18 15:18:56 +00:00
}
+ + nPos ;
2001-08-24 05:05:37 +00:00
xIndex = isUniqueByColumnName ( i ) ;
2000-09-18 15:18:56 +00:00
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 ) ;
2001-02-14 06:22:50 +00:00
OSL_ENSURE ( xTunnel . is ( ) , " No TunnelImplementation! " ) ;
2000-09-18 15:18:56 +00:00
ODbaseIndex * pIndex = ( ODbaseIndex * ) xTunnel - > getSomething ( ODbaseIndex : : getUnoTunnelImplementationId ( ) ) ;
2001-02-14 06:22:50 +00:00
OSL_ENSURE ( pIndex , " ODbaseTable::UpdateBuffer: No Index returned! " ) ;
2000-09-18 15:18:56 +00:00
if ( pIndex - > Find ( 0 , rRow [ nPos ] ) )
{
// es existiert kein eindeutiger Wert
2001-08-06 06:41:14 +00:00
: : rtl : : OUString sMessage = : : rtl : : OUString : : createFromAscii ( " Duplicate value found in column \" " ) ;
sMessage + = aColName ;
sMessage + = : : rtl : : OUString : : createFromAscii ( " \" ! " ) ;
throw SQLException ( sMessage , * this , OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_HY0000 ) , 1000 , Any ( ) ) ;
2000-09-18 15:18:56 +00:00
}
}
}
}
// when we are here there is no double key in the table
2001-08-24 05:05:37 +00:00
for ( i = 0 ; i < nColumnCount ; + + i )
2000-09-18 15:18:56 +00:00
{
// Laengen je nach Datentyp:
2001-08-24 05:05:37 +00:00
sal_Int32 nLen = m_aPrecisions [ i ] ;
sal_Int32 nType = m_aTypes [ i ] ;
2001-07-30 07:53:02 +00:00
2000-09-18 15:18:56 +00:00
switch ( nType )
{
case DataType : : DATE : nLen = 8 ; break ;
case DataType : : DECIMAL :
2001-07-30 07:53:02 +00:00
nLen = SvDbaseConverter : : ConvertPrecisionToDbase ( nLen , m_aScales [ i ] ) ;
2000-09-18 15:18:56 +00:00
break ; // das Vorzeichen und das Komma
2001-06-29 07:29:14 +00:00
case DataType : : BIT : nLen = 1 ; break ;
case DataType : : LONGVARCHAR : nLen = 10 ; break ;
2000-09-18 15:18:56 +00:00
default : break ;
}
2001-08-24 05:05:37 +00:00
sal_Int32 nPos = i ;
if ( _xCols ! = xColumns )
2000-09-18 15:18:56 +00:00
{
2001-08-24 05:05:37 +00:00
m_pColumns - > getByIndex ( i ) > > = xCol ;
OSL_ENSURE ( xCol . is ( ) , " ODbaseTable::UpdateBuffer column is null! " ) ;
xCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_NAME ) ) > > = aColName ;
for ( nPos = 0 ; nPos < _xCols - > getCount ( ) ; + + nPos )
{
Reference < XPropertySet > xFindCol ;
: : cppu : : extractInterface ( xFindCol , _xCols - > getByIndex ( nPos ) ) ;
if ( aCase ( getString ( xFindCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_NAME ) ) ) , aColName ) )
break ;
}
if ( nPos > = _xCols - > getCount ( ) )
{
nByteOffset + = nLen ;
continue ;
}
2000-09-18 15:18:56 +00:00
}
2001-08-24 05:05:37 +00:00
2000-09-18 15:18:56 +00:00
+ + nPos ; // the row values start at 1
2001-05-11 05:14:11 +00:00
// Ist die Variable ueberhaupt gebunden?
if ( ! rRow [ nPos ] . isBound ( ) )
{
// Nein - naechstes Feld.
nByteOffset + = nLen ;
continue ;
}
2000-09-18 15:18:56 +00:00
if ( aIndexedCols [ i ] . is ( ) )
{
Reference < XUnoTunnel > xTunnel ( aIndexedCols [ i ] , UNO_QUERY ) ;
2001-02-14 06:22:50 +00:00
OSL_ENSURE ( xTunnel . is ( ) , " No TunnelImplementation! " ) ;
2000-09-18 15:18:56 +00:00
ODbaseIndex * pIndex = ( ODbaseIndex * ) xTunnel - > getSomething ( ODbaseIndex : : getUnoTunnelImplementationId ( ) ) ;
2001-02-14 06:22:50 +00:00
OSL_ENSURE ( pIndex , " ODbaseTable::UpdateBuffer: No Index returned! " ) ;
2000-09-18 15:18:56 +00:00
// Update !!
if ( pOrgRow . isValid ( ) & & ! rRow [ nPos ] . isNull ( ) ) //&& pVal->isModified())
pIndex - > Update ( m_nFilePos , ( * pOrgRow ) [ nPos ] , rRow [ nPos ] ) ;
else
pIndex - > Insert ( m_nFilePos , rRow [ nPos ] ) ;
}
2001-05-11 05:14:11 +00:00
2000-09-18 15:18:56 +00:00
char * pData = ( char * ) ( m_pBuffer + nByteOffset ) ;
if ( rRow [ nPos ] . isNull ( ) )
{
memset ( pData , ' ' , nLen ) ; // Zuruecksetzen auf NULL
nByteOffset + = nLen ;
continue ;
}
2001-08-28 07:58:03 +00:00
sal_Bool bHadError = sal_False ;
Any aSQLError ;
2000-09-18 15:18:56 +00:00
try
{
switch ( nType )
{
case DataType : : DATE :
{
2000-12-06 11:07:47 +00:00
: : com : : sun : : star : : util : : Date aDate ;
if ( rRow [ nPos ] . getTypeKind ( ) = = DataType : : DOUBLE )
aDate = : : dbtools : : DBTypeConversion : : toDate ( rRow [ nPos ] . getDouble ( ) ) ;
else
aDate = rRow [ nPos ] ;
2000-09-18 15:18:56 +00:00
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 ] ;
2001-08-24 05:05:37 +00:00
m_pColumns - > getByIndex ( i ) > > = xCol ;
OSL_ENSURE ( xCol . is ( ) , " ODbaseTable::UpdateBuffer column is null! " ) ;
xCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_NAME ) ) > > = aColName ;
2001-07-30 07:53:02 +00:00
int nPrecision = ( int ) m_aPrecisions [ i ] ;
2001-05-14 10:42:44 +00:00
int nScale = ( int ) getINT32 ( xCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_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 , ' . ' ) ;
2001-02-28 08:15:30 +00:00
ByteString aDefaultValue ( aString , getConnection ( ) - > getTextEncoding ( ) ) ;
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 )
{
2001-02-28 08:15:30 +00:00
String sError ;
sError . AppendAscii ( " The " ) ;
sError + = aColName . getStr ( ) ;
sError . AppendAscii ( " column has been defined as a \" Decimal \" type, the max. length is " ) ;
sError + = String : : CreateFromInt32 ( nPrecision ) ;
sError . AppendAscii ( " characters (with " ) ;
sError + = String : : CreateFromInt32 ( nScale ) ;
sError . AppendAscii ( " decimal places). \n \n The specified value is longer than the number of digits allowed. " ) ;
throwGenericSQLException ( sError , static_cast < XNamed * > ( this ) ) ;
2000-09-18 15:18:56 +00:00
}
} 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:
2001-10-12 14:21:00 +00:00
memcpy ( pData , aStr . GetBuffer ( ) , std : : min ( nLen , ( sal_Int32 ) aStr . Len ( ) ) ) ;
2000-09-18 15:18:56 +00:00
} break ;
}
}
2001-08-28 07:58:03 +00:00
catch ( SQLException & e ) { aSQLError < < = e ; bHadError = sal_True ; }
catch ( Exception & ) { bHadError = sal_True ; }
if ( bHadError )
2000-09-18 15:18:56 +00:00
{
2001-08-24 05:05:37 +00:00
m_pColumns - > getByIndex ( i ) > > = xCol ;
OSL_ENSURE ( xCol . is ( ) , " ODbaseTable::UpdateBuffer column is null! " ) ;
xCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_NAME ) ) > > = aColName ;
2001-02-22 12:53:00 +00:00
: : rtl : : OUString sMsg = : : rtl : : OUString : : createFromAscii ( " Invalid value for column: " ) ;
sMsg + = aColName ;
sMsg + = : : rtl : : OUString : : createFromAscii ( " ! " ) ;
2001-08-28 07:58:03 +00:00
throw SQLException (
sMsg ,
* this ,
OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_HY0000 ) ,
1000 ,
aSQLError
) ;
2000-09-18 15:18:56 +00:00
}
// Und weiter ...
nByteOffset + = nLen ;
}
return sal_True ;
}
2000-10-30 07:07:33 +00:00
// -----------------------------------------------------------------------------
2001-03-28 10:32:43 +00:00
// XAlterTable
void SAL_CALL ODbaseTable : : alterColumnByName ( const : : rtl : : OUString & colName , const Reference < XPropertySet > & descriptor ) throw ( SQLException , NoSuchElementException , RuntimeException )
{
: : osl : : MutexGuard aGuard ( m_aMutex ) ;
2001-05-17 05:46:55 +00:00
checkDisposed ( OTableDescriptor_BASE : : rBHelper . bDisposed ) ;
2001-03-28 10:32:43 +00:00
Reference < XDataDescriptorFactory > xOldColumn ;
m_pColumns - > getByName ( colName ) > > = xOldColumn ;
2001-05-30 09:44:16 +00:00
alterColumn ( m_pColumns - > findColumn ( colName ) - 1 , descriptor , xOldColumn ) ;
2001-03-28 10:32:43 +00:00
}
// -------------------------------------------------------------------------
void SAL_CALL ODbaseTable : : alterColumnByIndex ( sal_Int32 index , const Reference < XPropertySet > & descriptor ) throw ( SQLException , : : com : : sun : : star : : lang : : IndexOutOfBoundsException , RuntimeException )
{
: : osl : : MutexGuard aGuard ( m_aMutex ) ;
2001-05-17 05:46:55 +00:00
checkDisposed ( OTableDescriptor_BASE : : rBHelper . bDisposed ) ;
2001-03-28 10:32:43 +00:00
if ( index < 0 | | index > = m_pColumns - > getCount ( ) )
2001-03-30 11:07:07 +00:00
throw IndexOutOfBoundsException ( : : rtl : : OUString : : valueOf ( index ) , * this ) ;
2001-03-28 10:32:43 +00:00
Reference < XDataDescriptorFactory > xOldColumn ;
m_pColumns - > getByIndex ( index ) > > = xOldColumn ;
alterColumn ( index , descriptor , xOldColumn ) ;
}
// -----------------------------------------------------------------------------
void ODbaseTable : : alterColumn ( sal_Int32 index ,
const Reference < XPropertySet > & descriptor ,
const Reference < XDataDescriptorFactory > & xOldColumn )
{
if ( index < 0 | | index > = m_pColumns - > getCount ( ) )
2001-03-30 11:07:07 +00:00
throw IndexOutOfBoundsException ( : : rtl : : OUString : : valueOf ( index ) , * this ) ;
2001-03-28 10:32:43 +00:00
2001-06-29 07:29:14 +00:00
ODbaseTable * pNewTable = NULL ;
try
{
OSL_ENSURE ( descriptor . is ( ) , " ODbaseTable::alterColumn: descriptor can not be null! " ) ;
// creates a copy of the the original column and copy all properties from descriptor in xCopyColumn
Reference < XPropertySet > xCopyColumn ;
if ( xOldColumn . is ( ) )
xCopyColumn = xOldColumn - > createDataDescriptor ( ) ;
else
xCopyColumn = new OColumn ( getConnection ( ) - > getMetaData ( ) - > storesMixedCaseQuotedIdentifiers ( ) ) ;
2001-03-28 10:32:43 +00:00
2001-06-29 07:29:14 +00:00
: : comphelper : : copyProperties ( descriptor , xCopyColumn ) ;
2001-03-28 10:32:43 +00:00
2001-06-29 07:29:14 +00:00
// creates a temp file
2001-03-28 10:32:43 +00:00
2001-06-29 07:29:14 +00:00
String sTempName = createTempFile ( ) ;
2001-09-25 12:12:51 +00:00
pNewTable = new ODbaseTable ( m_pTables , static_cast < ODbaseConnection * > ( m_pConnection ) ) ;
2001-06-29 07:29:14 +00:00
Reference < XPropertySet > xHoldTable = pNewTable ;
pNewTable - > setPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_NAME ) , makeAny ( : : rtl : : OUString ( sTempName ) ) ) ;
Reference < XAppend > xAppend ( pNewTable - > getColumns ( ) , UNO_QUERY ) ;
OSL_ENSURE ( xAppend . is ( ) , " ODbaseTable::alterColumn: No XAppend interface! " ) ;
// copy the structure
sal_Int32 i = 0 ;
for ( ; i < index ; + + i )
2001-05-28 12:03:37 +00:00
{
2001-06-29 07:29:14 +00:00
Reference < XPropertySet > xProp ;
m_pColumns - > getByIndex ( i ) > > = xProp ;
Reference < XDataDescriptorFactory > xColumn ( xProp , UNO_QUERY ) ;
Reference < XPropertySet > xCpy ;
if ( xColumn . is ( ) )
xCpy = xColumn - > createDataDescriptor ( ) ;
else
{
xCpy = new OColumn ( getConnection ( ) - > getMetaData ( ) - > storesMixedCaseQuotedIdentifiers ( ) ) ;
: : comphelper : : copyProperties ( xProp , xCpy ) ;
}
xAppend - > appendByDescriptor ( xCpy ) ;
2001-05-28 12:03:37 +00:00
}
2001-06-29 07:29:14 +00:00
+ + i ; // now insert our new column
xAppend - > appendByDescriptor ( xCopyColumn ) ;
2001-03-28 10:32:43 +00:00
2001-06-29 07:29:14 +00:00
for ( ; i < m_pColumns - > getCount ( ) ; + + i )
2001-05-28 12:03:37 +00:00
{
2001-06-29 07:29:14 +00:00
Reference < XPropertySet > xProp ;
m_pColumns - > getByIndex ( i ) > > = xProp ;
Reference < XDataDescriptorFactory > xColumn ( xProp , UNO_QUERY ) ;
Reference < XPropertySet > xCpy ;
if ( xColumn . is ( ) )
xCpy = xColumn - > createDataDescriptor ( ) ;
else
{
xCpy = new OColumn ( getConnection ( ) - > getMetaData ( ) - > storesMixedCaseQuotedIdentifiers ( ) ) ;
: : comphelper : : copyProperties ( xProp , xCpy ) ;
}
xAppend - > appendByDescriptor ( xCpy ) ;
2001-05-28 12:03:37 +00:00
}
2001-03-28 10:32:43 +00:00
2001-06-29 07:29:14 +00:00
// construct the new table
if ( ! pNewTable - > CreateImpl ( ) )
{
delete pNewTable ;
return ;
}
pNewTable - > construct ( ) ;
2001-03-28 10:32:43 +00:00
2001-06-29 07:29:14 +00:00
// copy the data
copyData ( pNewTable , 0 ) ;
2001-03-28 10:32:43 +00:00
2001-06-29 07:29:14 +00:00
// now drop the old one
if ( DropImpl ( ) )
{
// rename the new one to the old one
2001-10-12 11:02:56 +00:00
pNewTable - > renameImpl ( m_Name ) ;
2001-06-29 07:29:14 +00:00
// release the temp file
pNewTable = NULL ;
: : comphelper : : disposeComponent ( xHoldTable ) ;
}
else
2001-10-12 11:02:56 +00:00
{
2001-06-29 07:29:14 +00:00
delete pNewTable ;
2001-10-12 11:02:56 +00:00
pNewTable = NULL ;
}
2001-06-29 07:29:14 +00:00
FileClose ( ) ;
construct ( ) ;
if ( m_pColumns )
m_pColumns - > refresh ( ) ;
2001-03-28 10:32:43 +00:00
2001-06-29 07:29:14 +00:00
}
catch ( const SQLException & )
{
delete pNewTable ;
throw ;
}
catch ( const Exception & )
{
OSL_ENSURE ( 0 , " ODbaseTable::alterColumn: Exception occured! " ) ;
delete pNewTable ;
throw ;
}
2001-03-28 10:32:43 +00:00
}
// -------------------------------------------------------------------------
void SAL_CALL ODbaseTable : : rename ( const : : rtl : : OUString & newName ) throw ( : : com : : sun : : star : : sdbc : : SQLException , : : com : : sun : : star : : container : : ElementExistException , : : com : : sun : : star : : uno : : RuntimeException )
{
: : osl : : MutexGuard aGuard ( m_aMutex ) ;
2001-05-17 05:46:55 +00:00
checkDisposed ( OTableDescriptor_BASE : : rBHelper . bDisposed ) ;
2001-09-25 12:12:51 +00:00
if ( m_pTables & & m_pTables - > hasByName ( newName ) )
throw ElementExistException ( newName , * this ) ;
2001-05-17 05:46:55 +00:00
2001-03-28 10:32:43 +00:00
2001-10-12 11:02:56 +00:00
renameImpl ( newName ) ;
}
// -------------------------------------------------------------------------
void SAL_CALL ODbaseTable : : renameImpl ( const : : rtl : : OUString & newName ) throw ( : : com : : sun : : star : : sdbc : : SQLException , : : com : : sun : : star : : container : : ElementExistException , : : com : : sun : : star : : uno : : RuntimeException )
{
: : osl : : MutexGuard aGuard ( m_aMutex ) ;
2001-03-28 10:32:43 +00:00
FileClose ( ) ;
2001-08-10 10:05:34 +00:00
String aName = getEntry ( m_pConnection , m_Name ) ;
2001-03-28 10:32:43 +00:00
if ( ! aName . Len ( ) )
{
: : rtl : : OUString aIdent = m_pConnection - > getContent ( ) - > getIdentifier ( ) - > getContentIdentifier ( ) ;
aIdent + = : : rtl : : OUString : : createFromAscii ( " / " ) ;
aIdent + = m_Name ;
aName = aIdent ;
}
INetURLObject aURL ;
aURL . SetURL ( aName ) ;
if ( aURL . getExtension ( ) ! = m_pConnection - > getExtension ( ) )
aURL . setExtension ( m_pConnection - > getExtension ( ) ) ;
String sNewName ( newName ) ;
sNewName . AppendAscii ( " . " ) ;
sNewName + = m_pConnection - > getExtension ( ) ;
try
{
2001-07-16 08:58:40 +00:00
String sOldName = aURL . GetMainURL ( INetURLObject : : NO_DECODE ) ;
2001-05-28 12:03:37 +00:00
// ::utl::UCBContentHelper::MoveTo(sOldName,sNewName);
2001-07-16 08:58:40 +00:00
Content aContent ( aURL . GetMainURL ( INetURLObject : : NO_DECODE ) , Reference < XCommandEnvironment > ( ) ) ;
2001-09-25 12:12:51 +00:00
Sequence < PropertyValue > aProps ( 1 ) ;
aProps [ 0 ] . Name = : : rtl : : OUString : : createFromAscii ( " Title " ) ;
aProps [ 0 ] . Handle = - 1 ; // n/a
aProps [ 0 ] . Value = makeAny ( : : rtl : : OUString ( sNewName ) ) ;
Sequence < Any > aValues ;
aContent . executeCommand ( rtl : : OUString : : createFromAscii ( " setPropertyValues " ) , makeAny ( aProps ) ) > > = aValues ;
if ( aValues . getLength ( ) & & aValues [ 0 ] . hasValue ( ) )
throw Exception ( ) ;
// aContent.setPropertyValue( rtl::OUString::createFromAscii( "Title" ),makeAny( ::rtl::OUString(sNewName) ) );
2001-03-28 10:32:43 +00:00
}
catch ( Exception & )
{
2001-09-25 12:12:51 +00:00
throw ElementExistException ( newName , * this ) ;
2001-03-28 10:32:43 +00:00
}
2001-09-25 12:12:51 +00:00
ODbaseTable_BASE : : rename ( newName ) ;
2001-03-28 10:32:43 +00:00
construct ( ) ;
2001-05-30 09:44:16 +00:00
if ( m_pColumns )
m_pColumns - > refresh ( ) ;
2001-09-25 12:12:51 +00:00
2001-03-28 10:32:43 +00:00
}
// -----------------------------------------------------------------------------
void ODbaseTable : : addColumn ( const Reference < XPropertySet > & _xNewColumn )
{
String sTempName = createTempFile ( ) ;
2001-09-25 12:12:51 +00:00
ODbaseTable * pNewTable = new ODbaseTable ( m_pTables , static_cast < ODbaseConnection * > ( m_pConnection ) ) ;
2001-05-28 12:03:37 +00:00
pNewTable - > acquire ( ) ;
2001-05-14 10:42:44 +00:00
pNewTable - > setPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_NAME ) , makeAny ( : : rtl : : OUString ( sTempName ) ) ) ;
2001-03-28 10:32:43 +00:00
{
Reference < XAppend > xAppend ( pNewTable - > getColumns ( ) , UNO_QUERY ) ;
2001-05-30 09:44:16 +00:00
sal_Bool bCase = getConnection ( ) - > getMetaData ( ) - > storesMixedCaseQuotedIdentifiers ( ) ;
2001-03-28 10:32:43 +00:00
// copy the structure
for ( sal_Int32 i = 0 ; i < m_pColumns - > getCount ( ) ; + + i )
{
2001-05-28 12:03:37 +00:00
Reference < XPropertySet > xProp ;
m_pColumns - > getByIndex ( i ) > > = xProp ;
Reference < XDataDescriptorFactory > xColumn ( xProp , UNO_QUERY ) ;
Reference < XPropertySet > xCpy ;
if ( xColumn . is ( ) )
xCpy = xColumn - > createDataDescriptor ( ) ;
else
{
2001-05-30 09:44:16 +00:00
xCpy = new OColumn ( bCase ) ;
2001-05-28 12:03:37 +00:00
: : comphelper : : copyProperties ( xProp , xCpy ) ;
}
2001-03-28 10:32:43 +00:00
xAppend - > appendByDescriptor ( xCpy ) ;
}
2001-05-30 09:44:16 +00:00
Reference < XPropertySet > xCpy = new OColumn ( bCase ) ;
: : comphelper : : copyProperties ( _xNewColumn , xCpy ) ;
xAppend - > appendByDescriptor ( xCpy ) ;
2001-03-28 10:32:43 +00:00
}
// construct the new table
if ( ! pNewTable - > CreateImpl ( ) )
{
2001-06-29 07:29:14 +00:00
delete pNewTable ;
throw SQLException ( ) ;
2001-03-28 10:32:43 +00:00
}
2001-06-29 07:29:14 +00:00
BOOL bAlreadyDroped = FALSE ;
try
{
pNewTable - > construct ( ) ;
// copy the data
copyData ( pNewTable , pNewTable - > m_pColumns - > getCount ( ) ) ;
// drop the old table
if ( DropImpl ( ) )
{
bAlreadyDroped = TRUE ;
2001-10-12 11:02:56 +00:00
pNewTable - > renameImpl ( m_Name ) ;
2001-06-29 07:29:14 +00:00
// release the temp file
pNewTable - > release ( ) ;
}
else
delete pNewTable ;
2001-05-28 12:03:37 +00:00
2001-06-29 07:29:14 +00:00
FileClose ( ) ;
construct ( ) ;
if ( m_pColumns )
m_pColumns - > refresh ( ) ;
}
catch ( const SQLException & )
{
// here we know that the old table wasn't droped before
if ( ! bAlreadyDroped )
delete pNewTable ;
2001-05-28 12:03:37 +00:00
2001-06-29 07:29:14 +00:00
throw ;
}
2001-05-30 09:44:16 +00:00
}
// -----------------------------------------------------------------------------
void ODbaseTable : : dropColumn ( sal_Int32 _nPos )
{
String sTempName = createTempFile ( ) ;
2001-09-25 12:12:51 +00:00
ODbaseTable * pNewTable = new ODbaseTable ( m_pTables , static_cast < ODbaseConnection * > ( m_pConnection ) ) ;
2001-05-30 09:44:16 +00:00
pNewTable - > acquire ( ) ;
pNewTable - > setPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_NAME ) , makeAny ( : : rtl : : OUString ( sTempName ) ) ) ;
{
Reference < XAppend > xAppend ( pNewTable - > getColumns ( ) , UNO_QUERY ) ;
sal_Bool bCase = getConnection ( ) - > getMetaData ( ) - > storesMixedCaseQuotedIdentifiers ( ) ;
// copy the structure
for ( sal_Int32 i = 0 ; i < m_pColumns - > getCount ( ) ; + + i )
{
if ( _nPos ! = i )
{
Reference < XPropertySet > xProp ;
m_pColumns - > getByIndex ( i ) > > = xProp ;
Reference < XDataDescriptorFactory > xColumn ( xProp , UNO_QUERY ) ;
Reference < XPropertySet > xCpy ;
if ( xColumn . is ( ) )
xCpy = xColumn - > createDataDescriptor ( ) ;
else
{
xCpy = new OColumn ( bCase ) ;
: : comphelper : : copyProperties ( xProp , xCpy ) ;
}
xAppend - > appendByDescriptor ( xCpy ) ;
}
}
}
// construct the new table
if ( ! pNewTable - > CreateImpl ( ) )
{
2001-06-29 07:29:14 +00:00
delete pNewTable ;
throw SQLException ( ) ;
2001-05-30 09:44:16 +00:00
}
2001-06-14 14:16:41 +00:00
pNewTable - > construct ( ) ;
2001-05-30 09:44:16 +00:00
// copy the data
2001-06-29 07:29:14 +00:00
copyData ( pNewTable , _nPos ) ;
2001-05-30 09:44:16 +00:00
// drop the old table
2001-06-29 07:29:14 +00:00
if ( DropImpl ( ) )
{
2001-10-12 11:02:56 +00:00
pNewTable - > renameImpl ( m_Name ) ;
2001-06-29 07:29:14 +00:00
// release the temp file
pNewTable - > release ( ) ;
}
else
delete pNewTable ;
2001-05-30 09:44:16 +00:00
FileClose ( ) ;
construct ( ) ;
if ( m_pColumns )
m_pColumns - > refresh ( ) ;
2001-03-28 10:32:43 +00:00
}
// -----------------------------------------------------------------------------
String ODbaseTable : : createTempFile ( )
{
: : rtl : : OUString aIdent = m_pConnection - > getContent ( ) - > getIdentifier ( ) - > getContentIdentifier ( ) ;
aIdent + = : : rtl : : OUString : : createFromAscii ( " / " ) ;
String sTempName ( aIdent ) ;
String sExt ;
sExt . AssignAscii ( " . " ) ;
sExt + = m_pConnection - > getExtension ( ) ;
2001-03-30 09:16:42 +00:00
String sName ( m_Name ) ;
TempFile aTempFile ( sName , & sExt , & sTempName ) ;
2001-03-28 10:32:43 +00:00
if ( ! aTempFile . IsValid ( ) )
2001-05-14 10:42:44 +00:00
throw SQLException ( : : rtl : : OUString : : createFromAscii ( " Error while alter table! " ) , NULL , OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_HY0000 ) , 1000 , Any ( ) ) ;
2001-03-28 10:32:43 +00:00
INetURLObject aURL ;
aURL . SetSmartProtocol ( INET_PROT_FILE ) ;
aURL . SetURL ( aTempFile . GetURL ( ) ) ;
2001-05-30 09:44:16 +00:00
2001-03-28 10:32:43 +00:00
String sNewName ( aURL . getName ( ) ) ;
sNewName . Erase ( sNewName . Len ( ) - sExt . Len ( ) ) ;
return sNewName ;
}
// -----------------------------------------------------------------------------
2001-06-29 07:29:14 +00:00
void ODbaseTable : : copyData ( ODbaseTable * _pNewTable , sal_Int32 _nPos )
2001-03-28 10:32:43 +00:00
{
2001-06-29 07:29:14 +00:00
sal_Int32 nPos = _nPos + 1 ; // +1 because we always have the bookmark clumn as well
2001-03-28 10:32:43 +00:00
OValueRow aRow = new OValueVector ( m_pColumns - > getCount ( ) ) ;
2001-06-29 07:29:14 +00:00
OValueRow aInsertRow ;
if ( nPos )
{
aInsertRow = new OValueVector ( _pNewTable - > m_pColumns - > getCount ( ) ) ;
2001-08-24 05:05:37 +00:00
: : std : : for_each ( aInsertRow - > begin ( ) , aInsertRow - > end ( ) , TSetBound ( sal_True ) ) ;
2001-06-29 07:29:14 +00:00
}
else
aInsertRow = aRow ;
// we only have to bind the values which we need to copy into the new table
2001-08-24 05:05:37 +00:00
: : std : : for_each ( aRow - > begin ( ) , aRow - > end ( ) , TSetBound ( sal_True ) ) ;
2001-07-17 11:37:19 +00:00
if ( nPos & & ( nPos < ( sal_Int32 ) aRow - > size ( ) ) )
2001-06-29 07:29:14 +00:00
( * aRow ) [ nPos ] . setBound ( sal_False ) ;
2001-03-28 10:32:43 +00:00
sal_Bool bOk = sal_True ;
sal_Int32 nCurPos ;
2001-08-24 05:05:37 +00:00
OValueVector : : iterator aIter ;
2001-03-28 10:32:43 +00:00
for ( sal_uInt32 nRowPos = 0 ; nRowPos < m_aHeader . db_anz ; + + nRowPos )
{
2001-06-14 14:16:41 +00:00
if ( bOk = seekRow ( FILE_BOOKMARK , nRowPos + 1 , nCurPos ) )
2001-03-28 10:32:43 +00:00
{
if ( bOk = fetchRow ( aRow , m_aColumns . getBody ( ) , sal_True , sal_True ) )
{
2001-06-29 07:29:14 +00:00
// special handling when pos == 0 then we don't have to distinguish between the two rows
if ( nPos )
{
aIter = aRow - > begin ( ) + 1 ;
sal_Int32 nCount = 1 ;
for ( OValueVector : : iterator aInsertIter = aInsertRow - > begin ( ) + 1 ; aIter ! = aRow - > end ( ) & & aInsertIter ! = aInsertRow - > end ( ) ; + + aIter , + + nCount )
{
if ( nPos ! = nCount )
{
* aInsertIter = * aIter ;
+ + aInsertIter ;
}
}
}
bOk = _pNewTable - > InsertRow ( * aInsertRow , sal_True , _pNewTable - > m_pColumns ) ;
2001-03-28 10:32:43 +00:00
OSL_ENSURE ( bOk , " Row could not be inserted! " ) ;
}
else
OSL_ENSURE ( bOk , " Row could not be fetched! " ) ;
}
else
{
OSL_ASSERT ( 0 ) ;
}
}
}
// -----------------------------------------------------------------------------
2001-08-02 06:59:15 +00:00
void ODbaseTable : : throwInvalidDbaseFormat ( )
{
2001-08-10 10:05:34 +00:00
FileClose ( ) ;
2001-08-02 06:59:15 +00:00
// no dbase file
: : rtl : : OUString sMessage = : : rtl : : OUString : : createFromAscii ( " [StarOffice Base dbase] The file ' " ) ;
2001-08-10 10:05:34 +00:00
sMessage + = getEntry ( m_pConnection , m_Name ) ;
2001-08-02 06:59:15 +00:00
sMessage + = : : rtl : : OUString : : createFromAscii ( " is an invalid (or unrecognized) dBase file. " ) ;
throwGenericSQLException ( sMessage , static_cast < XNamed * > ( this ) ) ;
}
// -----------------------------------------------------------------------------
2001-09-19 10:03:04 +00:00
void ODbaseTable : : refreshHeader ( )
{
readHeader ( ) ;
}
2001-10-12 14:21:00 +00:00
// -----------------------------------------------------------------------------