2000-09-18 15:18:56 +00:00
/*************************************************************************
*
2005-09-08 04:38:11 +00:00
* OpenOffice . org - a multi - platform office productivity suite
2000-09-18 15:18:56 +00:00
*
2005-09-08 04:38:11 +00:00
* $ RCSfile : DIndex . cxx , v $
2000-09-18 15:18:56 +00:00
*
2007-06-05 13:21:18 +00:00
* $ Revision : 1.42 $
2000-09-18 15:18:56 +00:00
*
2007-06-05 13:21:18 +00:00
* last change : $ Author : ihi $ $ Date : 2007 - 06 - 05 14 : 21 : 18 $
2000-09-18 15:18:56 +00:00
*
2005-09-08 04:38:11 +00:00
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1 .
2000-09-18 15:18:56 +00:00
*
*
2005-09-08 04:38:11 +00:00
* GNU Lesser General Public License Version 2.1
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* Copyright 2005 by Sun Microsystems , Inc .
* 901 San Antonio Road , Palo Alto , CA 94303 , USA
2000-09-18 15:18:56 +00:00
*
2005-09-08 04:38:11 +00:00
* 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 .
2000-09-18 15:18:56 +00:00
*
2005-09-08 04:38:11 +00:00
* 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 .
2000-09-18 15:18:56 +00:00
*
2005-09-08 04:38:11 +00:00
* 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
2000-09-18 15:18:56 +00:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-17 01:22:00 +00:00
// MARKER(update_precomp.py): autogen include statement, do not remove
# include "precompiled_connectivity.hxx"
2000-09-18 15:18:56 +00:00
# ifndef _CONNECTIVITY_DBASE_INDEX_HXX_
# include "dbase/DIndex.hxx"
# endif
# ifndef _CONNECTIVITY_DBASE_INDEXCOLUMNS_HXX_
# include "dbase/DIndexColumns.hxx"
# endif
# ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
# include <com/sun/star/lang/DisposedException.hpp>
# endif
# ifndef _CONNECTIVITY_SDBCX_COLUMN_HXX_
# include "connectivity/sdbcx/VColumn.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_DBASE_TABLE_HXX_
# include "dbase/DTable.hxx"
# endif
# ifndef _CONNECTIVITY_DBASE_INDEXITER_HXX_
# include "dbase/DIndexIter.hxx"
# endif
2004-01-06 16:04:32 +00:00
# ifndef _CONFIG_HXX
# include <tools/config.hxx>
2000-09-18 15:18:56 +00:00
# endif
# ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
# include "connectivity/CommonTools.hxx"
# endif
# ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATA_HPP_
# include <com/sun/star/sdbc/XResultSetMetaData.hpp>
# endif
# ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
# include <com/sun/star/sdbc/XResultSet.hpp>
# endif
2001-05-08 12:26:37 +00:00
# ifndef _COM_SUN_STAR_SDBCX_XROWLOCATE_HPP_
# include <com/sun/star/sdbcx/XRowLocate.hpp>
# endif
2000-09-18 15:18:56 +00:00
# ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
# include <com/sun/star/sdbc/XRow.hpp>
# 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
2001-03-30 13:01:50 +00:00
# ifndef _UNOTOOLS_LOCALFILEHELPER_HXX
# include <unotools/localfilehelper.hxx>
# endif
# ifndef _UNOTOOLS_UCBHELPER_HXX
# include <unotools/ucbhelper.hxx>
# endif
# ifndef _COMPHELPER_TYPES_HXX_
# include <comphelper/types.hxx>
# endif
# ifndef _DBHELPER_DBEXCEPTION_HXX_
# include <connectivity/dbexception.hxx>
# endif
2001-05-10 13:31:14 +00:00
# ifndef _CONNECTIVITY_DBASE_DRESULTSET_HXX_
# include "dbase/DResultSet.hxx"
# endif
2006-06-20 00:19:57 +00:00
# ifndef CONNECTIVITY_DIAGNOSE_EX_H
# include "diagnose_ex.h"
# endif
2001-05-18 07:51:34 +00:00
# ifndef _COMPHELPER_TYPES_HXX_
# include <comphelper/types.hxx>
# endif
using namespace : : comphelper ;
2000-09-18 15:18:56 +00:00
// -------------------------------------------------------------------------
using namespace connectivity ;
2001-03-30 13:01:50 +00:00
using namespace utl ;
2001-05-18 07:51:34 +00:00
using namespace : : cppu ;
2000-09-18 15:18:56 +00:00
using namespace connectivity : : file ;
using namespace connectivity : : sdbcx ;
using namespace connectivity : : dbase ;
using namespace com : : sun : : star : : sdbc ;
2001-05-08 12:26:37 +00:00
using namespace com : : sun : : star : : sdbcx ;
2000-09-18 15:18:56 +00:00
using namespace com : : sun : : star : : uno ;
using namespace com : : sun : : star : : beans ;
2007-06-05 13:21:18 +00:00
using namespace com : : sun : : star : : lang ;
2000-09-18 15:18:56 +00:00
IMPLEMENT_SERVICE_INFO ( ODbaseIndex , " com.sun.star.sdbcx.driver.dbase.Index " , " com.sun.star.sdbcx.Index " ) ;
// -------------------------------------------------------------------------
ODbaseIndex : : ODbaseIndex ( ODbaseTable * _pTable ) : OIndex ( _pTable - > getConnection ( ) - > getMetaData ( ) - > storesMixedCaseQuotedIdentifiers ( ) )
2001-03-30 13:01:50 +00:00
, m_pFileStream ( NULL )
2001-04-30 12:38:23 +00:00
, m_nCurNode ( NODE_NOTFOUND )
2006-06-20 00:19:57 +00:00
, m_pTable ( _pTable )
2000-09-18 15:18:56 +00:00
{
2001-05-08 12:26:37 +00:00
m_aHeader . db_pagecount = m_aHeader . db_rootpage = m_aHeader . db_keytype = m_aHeader . db_maxkeys = m_aHeader . db_keylen = 0 ;
2001-03-30 13:01:50 +00:00
m_aHeader . db_name [ 0 ] = ' \0 ' ;
2000-09-18 15:18:56 +00:00
construct ( ) ;
}
// -------------------------------------------------------------------------
ODbaseIndex : : ODbaseIndex ( ODbaseTable * _pTable ,
const NDXHeader & _rHeader ,
const : : rtl : : OUString & _rName )
2006-06-20 00:19:57 +00:00
: OIndex ( _rName , : : rtl : : OUString ( ) , _rHeader . db_unique , sal_False , sal_False , _pTable - > getConnection ( ) - > getMetaData ( ) - > storesMixedCaseQuotedIdentifiers ( ) )
2001-03-30 13:01:50 +00:00
, m_pFileStream ( NULL )
2006-06-20 00:19:57 +00:00
, m_aHeader ( _rHeader )
2001-04-30 12:38:23 +00:00
, m_nCurNode ( NODE_NOTFOUND )
2006-06-20 00:19:57 +00:00
, m_pTable ( _pTable )
2000-09-18 15:18:56 +00:00
{
construct ( ) ;
}
2001-03-30 13:01:50 +00:00
// -----------------------------------------------------------------------------
ODbaseIndex : : ~ ODbaseIndex ( )
{
closeImpl ( ) ;
}
2000-09-18 15:18:56 +00:00
// -------------------------------------------------------------------------
void ODbaseIndex : : refreshColumns ( )
{
: : osl : : MutexGuard aGuard ( m_aMutex ) ;
2001-05-02 11:57:37 +00:00
TStringVector aVector ;
2001-03-30 13:01:50 +00:00
if ( ! isNew ( ) )
{
OSL_ENSURE ( m_pFileStream , " FileStream is not opened! " ) ;
OSL_ENSURE ( m_aHeader . db_name [ 0 ] ! = ' \0 ' , " Invalid name for the column! " ) ;
aVector . push_back ( : : rtl : : OUString : : createFromAscii ( m_aHeader . db_name ) ) ;
}
2000-09-18 15:18:56 +00:00
if ( m_pColumns )
2001-05-04 08:58:45 +00:00
m_pColumns - > reFill ( aVector ) ;
else
m_pColumns = new ODbaseIndexColumns ( this , m_aMutex , aVector ) ;
2000-09-18 15:18:56 +00:00
}
//--------------------------------------------------------------------------
Sequence < sal_Int8 > ODbaseIndex : : 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 ( ) ;
}
2007-06-05 13:21:18 +00:00
// XUnoTunnel
2000-09-18 15:18:56 +00:00
//------------------------------------------------------------------
sal_Int64 ODbaseIndex : : 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 ) )
2006-06-20 00:19:57 +00:00
? reinterpret_cast < sal_Int64 > ( this )
: ODbaseIndex_BASE : : getSomething ( rId ) ;
2000-09-18 15:18:56 +00:00
}
//------------------------------------------------------------------
ONDXPagePtr ODbaseIndex : : getRoot ( )
{
openIndexFile ( ) ;
if ( ! m_aRoot . Is ( ) )
{
m_nRootPage = m_aHeader . db_rootpage ;
m_nPageCount = m_aHeader . db_pagecount ;
m_aRoot = CreatePage ( m_nRootPage , NULL , TRUE ) ;
}
return m_aRoot ;
}
//------------------------------------------------------------------
sal_Bool ODbaseIndex : : openIndexFile ( )
{
2001-03-30 13:01:50 +00:00
if ( ! m_pFileStream )
2000-09-18 15:18:56 +00:00
{
2001-03-30 13:01:50 +00:00
: : rtl : : OUString sFile = getCompletePath ( ) ;
if ( UCBContentHelper : : Exists ( sFile ) )
{
2001-07-17 11:37:19 +00:00
m_pFileStream = OFileTable : : createStream_simpleError ( sFile , STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE ) ;
if ( ! m_pFileStream )
m_pFileStream = OFileTable : : createStream_simpleError ( sFile , STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYNONE ) ;
2001-03-30 13:01:50 +00:00
if ( m_pFileStream )
{
m_pFileStream - > SetNumberFormatInt ( NUMBERFORMAT_INT_LITTLEENDIAN ) ;
m_pFileStream - > SetBufferSize ( 512 ) ;
( * m_pFileStream ) > > * this ;
}
}
if ( ! m_pFileStream )
{
: : rtl : : OUString sErrMsg = : : rtl : : OUString : : createFromAscii ( " Could not open index: " ) ;
sErrMsg + = sFile ;
2006-07-10 13:25:09 +00:00
: : dbtools : : throwGenericSQLException ( sErrMsg , * this ) ;
2001-03-30 13:01:50 +00:00
}
2000-09-18 15:18:56 +00:00
}
2001-03-30 13:01:50 +00:00
return m_pFileStream ! = NULL ;
2000-09-18 15:18:56 +00:00
}
//------------------------------------------------------------------
OIndexIterator * ODbaseIndex : : createIterator ( OBoolOperator * pOp ,
2001-03-30 13:01:50 +00:00
const OOperand * pOperand )
2000-09-18 15:18:56 +00:00
{
openIndexFile ( ) ;
return new OIndexIterator ( this , pOp , pOperand ) ;
}
//------------------------------------------------------------------
2000-10-17 08:15:19 +00:00
BOOL ODbaseIndex : : ConvertToKey ( ONDXKey * rKey , sal_uInt32 nRec , const ORowSetValue & rValue )
2000-09-18 15:18:56 +00:00
{
2001-03-30 13:01:50 +00:00
OSL_ENSURE ( m_pFileStream , " FileStream is not opened! " ) ;
2000-09-18 15:18:56 +00:00
// Sucht ein bestimmten Wert im Index
// Wenn der Index Unique ist, interssiert der Key nicht, sonst ja
try
{
if ( m_aHeader . db_keytype = = 0 )
{
* rKey = ONDXKey ( rValue . getString ( ) , nRec ) ;
}
else
{
if ( rValue . isNull ( ) )
* rKey = ONDXKey ( rValue . getDouble ( ) , DataType : : DOUBLE , nRec ) ;
else
* rKey = ONDXKey ( rValue . getDouble ( ) , nRec ) ;
}
}
2001-03-30 13:01:50 +00:00
catch ( Exception & )
2000-09-18 15:18:56 +00:00
{
2001-03-30 13:01:50 +00:00
OSL_ASSERT ( 0 ) ;
2000-09-18 15:18:56 +00:00
return FALSE ;
}
return TRUE ;
}
//------------------------------------------------------------------
2000-10-17 08:15:19 +00:00
BOOL ODbaseIndex : : Find ( sal_uInt32 nRec , const ORowSetValue & rValue )
2000-09-18 15:18:56 +00:00
{
openIndexFile ( ) ;
2001-03-30 13:01:50 +00:00
OSL_ENSURE ( m_pFileStream , " FileStream is not opened! " ) ;
2000-09-18 15:18:56 +00:00
// Sucht ein bestimmten Wert im Index
// Wenn der Index Unique ist, interssiert der Key nicht, sonst ja
ONDXKey aKey ;
return ConvertToKey ( & aKey , nRec , rValue ) & & getRoot ( ) - > Find ( aKey ) ;
}
//------------------------------------------------------------------
2000-10-17 08:15:19 +00:00
BOOL ODbaseIndex : : Insert ( sal_uInt32 nRec , const ORowSetValue & rValue )
2000-09-18 15:18:56 +00:00
{
openIndexFile ( ) ;
2001-03-30 13:01:50 +00:00
OSL_ENSURE ( m_pFileStream , " FileStream is not opened! " ) ;
2000-09-18 15:18:56 +00:00
ONDXKey aKey ;
// Existiert der Wert bereits
// Find immer verwenden um das aktuelle Blatt zu bestimmen
if ( ! ConvertToKey ( & aKey , nRec , rValue ) | | ( getRoot ( ) - > Find ( aKey ) & & isUnique ( ) ) )
return FALSE ;
ONDXNode aNewNode ( aKey ) ;
// einfuegen in das aktuelle Blatt
if ( ! m_aCurLeaf . Is ( ) )
return FALSE ;
BOOL bResult = m_aCurLeaf - > Insert ( aNewNode ) ;
Release ( bResult ) ;
return bResult ;
}
//------------------------------------------------------------------
2000-10-17 08:15:19 +00:00
BOOL ODbaseIndex : : Update ( sal_uInt32 nRec , const ORowSetValue & rOldValue ,
const ORowSetValue & rNewValue )
2000-09-18 15:18:56 +00:00
{
openIndexFile ( ) ;
2001-03-30 13:01:50 +00:00
OSL_ENSURE ( m_pFileStream , " FileStream is not opened! " ) ;
2000-09-18 15:18:56 +00:00
ONDXKey aKey ;
if ( ! ConvertToKey ( & aKey , nRec , rNewValue ) | | ( isUnique ( ) & & getRoot ( ) - > Find ( aKey ) ) )
return FALSE ;
else
return Delete ( nRec , rOldValue ) & & Insert ( nRec , rNewValue ) ;
}
//------------------------------------------------------------------
2000-10-17 08:15:19 +00:00
BOOL ODbaseIndex : : Delete ( sal_uInt32 nRec , const ORowSetValue & rValue )
2000-09-18 15:18:56 +00:00
{
openIndexFile ( ) ;
2001-03-30 13:01:50 +00:00
OSL_ENSURE ( m_pFileStream , " FileStream is not opened! " ) ;
2000-09-18 15:18:56 +00:00
// Existiert der Wert bereits
// Find immer verwenden um das aktuelle Blatt zu bestimmen
ONDXKey aKey ;
if ( ! ConvertToKey ( & aKey , nRec , rValue ) | | ! getRoot ( ) - > Find ( aKey ) )
return FALSE ;
ONDXNode aNewNode ( aKey ) ;
// einfuegen in das aktuelle Blatt
if ( ! m_aCurLeaf . Is ( ) )
return FALSE ;
2003-04-15 16:36:37 +00:00
# if OSL_DEBUG_LEVEL > 1
2000-09-18 15:18:56 +00:00
m_aRoot - > PrintPage ( ) ;
# endif
return m_aCurLeaf - > Delete ( m_nCurNode ) ;
}
//------------------------------------------------------------------
void ODbaseIndex : : Collect ( ONDXPage * pPage )
{
if ( pPage )
m_aCollector . push_back ( pPage ) ;
}
//------------------------------------------------------------------
void ODbaseIndex : : Release ( BOOL bSave )
{
// Freigeben der Indexressourcen
m_bUseCollector = FALSE ;
if ( m_aCurLeaf . Is ( ) )
{
m_aCurLeaf - > Release ( bSave ) ;
m_aCurLeaf . Clear ( ) ;
}
// Wurzel freigeben
if ( m_aRoot . Is ( ) )
{
m_aRoot - > Release ( bSave ) ;
m_aRoot . Clear ( ) ;
}
// alle Referenzen freigeben, bevor der FileStream geschlossen wird
for ( ULONG i = 0 ; i < m_aCollector . size ( ) ; i + + )
m_aCollector [ i ] - > QueryDelete ( ) ;
m_aCollector . clear ( ) ;
// Header modifiziert ?
if ( bSave & & ( m_aHeader . db_rootpage ! = m_nRootPage | |
m_aHeader . db_pagecount ! = m_nPageCount ) )
{
m_aHeader . db_rootpage = m_nRootPage ;
m_aHeader . db_pagecount = m_nPageCount ;
2001-03-30 13:01:50 +00:00
( * m_pFileStream ) < < * this ;
2000-09-18 15:18:56 +00:00
}
m_nRootPage = m_nPageCount = 0 ;
m_nCurNode = NODE_NOTFOUND ;
2001-03-30 13:01:50 +00:00
closeImpl ( ) ;
}
// -----------------------------------------------------------------------------
void ODbaseIndex : : closeImpl ( )
{
if ( m_pFileStream )
{
delete m_pFileStream ;
m_pFileStream = NULL ;
}
2000-09-18 15:18:56 +00:00
}
//------------------------------------------------------------------
ONDXPage * ODbaseIndex : : CreatePage ( sal_uInt32 nPagePos , ONDXPage * pParent , BOOL bLoad )
{
2001-03-30 13:01:50 +00:00
OSL_ENSURE ( m_pFileStream , " FileStream is not opened! " ) ;
2000-09-18 15:18:56 +00:00
ONDXPage * pPage ;
if ( m_aCollector . size ( ) )
{
pPage = * ( m_aCollector . end ( ) - 1 ) ;
m_aCollector . pop_back ( ) ;
pPage - > SetPagePos ( nPagePos ) ;
pPage - > SetParent ( pParent ) ;
}
else
pPage = new ONDXPage ( * this , nPagePos , pParent ) ;
if ( bLoad )
2001-03-30 13:01:50 +00:00
( * m_pFileStream ) > > * pPage ;
2000-09-18 15:18:56 +00:00
return pPage ;
}
//------------------------------------------------------------------
SvStream & connectivity : : dbase : : operator > > ( SvStream & rStream , ODbaseIndex & rIndex )
{
rStream . Seek ( 0 ) ;
rStream . Read ( & rIndex . m_aHeader , 512 ) ;
2003-03-19 15:38:50 +00:00
/* OJ: no longer needed
2000-09-18 15:18:56 +00:00
// Text convertierung
ByteString aText ( rIndex . m_aHeader . db_name ) ;
2001-02-05 11:26:42 +00:00
// aText.Convert(rIndex.m_pTable->getConnection()->GetCharacterSet(), m_pTable->getConnection()->getTextEncoding());
// aText.Convert(rIndex.m_pTable->getConnection()->GetCharacterSet(), m_pTable->getConnection()->getTextEncoding());
2000-09-18 15:18:56 +00:00
strcpy ( rIndex . m_aHeader . db_name , aText . GetBuffer ( ) ) ;
2003-03-19 15:38:50 +00:00
*/
2000-09-18 15:18:56 +00:00
rIndex . m_nRootPage = rIndex . m_aHeader . db_rootpage ;
rIndex . m_nPageCount = rIndex . m_aHeader . db_pagecount ;
return rStream ;
}
//------------------------------------------------------------------
SvStream & connectivity : : dbase : : operator < < ( SvStream & rStream , ODbaseIndex & rIndex )
{
rStream . Seek ( 0 ) ;
2003-03-19 15:38:50 +00:00
/* OJ: no longer needed
2000-09-18 15:18:56 +00:00
ByteString aText ( rIndex . m_aHeader . db_name ) ;
2001-02-05 11:26:42 +00:00
// aText.Convert(m_pTable->getConnection()->getTextEncoding(), rIndex.m_pTable->getConnection()->GetCharacterSet());
2000-09-18 15:18:56 +00:00
strcpy ( rIndex . m_aHeader . db_name , aText . GetBuffer ( ) ) ;
2003-03-19 15:38:50 +00:00
*/
2006-06-20 00:19:57 +00:00
OSL_VERIFY_EQUALS ( rStream . Write ( & rIndex . m_aHeader , 512 ) , 512 , " Write not successful: Wrong header size for dbase index! " ) ;
2000-09-18 15:18:56 +00:00
return rStream ;
}
// -------------------------------------------------------------------------
2001-03-30 13:01:50 +00:00
: : rtl : : OUString ODbaseIndex : : getCompletePath ( )
2000-09-18 15:18:56 +00:00
{
2001-03-30 13:01:50 +00:00
: : rtl : : OUString sDir = m_pTable - > getConnection ( ) - > getURL ( ) ;
2001-05-14 10:55:19 +00:00
sDir + = OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_DELIMITER ) ;
2001-03-30 13:01:50 +00:00
sDir + = m_Name ;
sDir + = : : rtl : : OUString : : createFromAscii ( " .ndx " ) ;
return sDir ;
2000-09-18 15:18:56 +00:00
}
//------------------------------------------------------------------
void ODbaseIndex : : createINFEntry ( )
{
// inf Datei abgleichen
2001-03-30 13:01:50 +00:00
String sEntry = m_Name ;
sEntry + = String : : CreateFromAscii ( " .ndx " ) ;
2000-09-18 15:18:56 +00:00
2001-03-30 13:01:50 +00:00
: : rtl : : OUString sCfgFile ( m_pTable - > getConnection ( ) - > getURL ( ) ) ;
2001-05-14 10:55:19 +00:00
sCfgFile + = OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_DELIMITER ) ;
2001-03-30 13:01:50 +00:00
sCfgFile + = m_pTable - > getName ( ) ;
sCfgFile + = : : rtl : : OUString : : createFromAscii ( " .inf " ) ;
2000-09-18 15:18:56 +00:00
2001-03-30 13:01:50 +00:00
String sPhysicalPath ;
LocalFileHelper : : ConvertURLToPhysicalName ( sCfgFile , sPhysicalPath ) ;
Config aInfFile ( sPhysicalPath ) ;
2000-09-18 15:18:56 +00:00
aInfFile . SetGroup ( dBASE_III_GROUP ) ;
USHORT nSuffix = aInfFile . GetKeyCount ( ) ;
ByteString aNewEntry , aKeyName ;
BOOL bCase = isCaseSensitive ( ) ;
while ( ! aNewEntry . Len ( ) )
{
aNewEntry = " NDX " ;
aNewEntry + = ByteString : : CreateFromInt32 ( + + nSuffix ) ;
for ( USHORT i = 0 ; i < aInfFile . GetKeyCount ( ) ; i + + )
{
aKeyName = aInfFile . GetKeyName ( i ) ;
if ( bCase ? aKeyName = = aNewEntry : aKeyName . EqualsIgnoreCaseAscii ( aNewEntry ) )
{
aNewEntry . Erase ( ) ;
break ;
}
}
}
2001-03-30 13:01:50 +00:00
aInfFile . WriteKey ( aNewEntry , ByteString ( sEntry , m_pTable - > getConnection ( ) - > getTextEncoding ( ) ) ) ;
2000-09-18 15:18:56 +00:00
}
// -------------------------------------------------------------------------
BOOL ODbaseIndex : : DropImpl ( )
{
2001-03-30 13:01:50 +00:00
closeImpl ( ) ;
2000-09-18 15:18:56 +00:00
2001-03-30 13:01:50 +00:00
: : rtl : : OUString sPath = getCompletePath ( ) ;
if ( UCBContentHelper : : Exists ( sPath ) )
2000-12-01 10:36:20 +00:00
{
2001-03-30 13:01:50 +00:00
if ( ! UCBContentHelper : : Kill ( sPath ) )
2006-07-10 13:25:09 +00:00
: : dbtools : : throwGenericSQLException (
2001-05-23 13:49:13 +00:00
: : rtl : : OUString : : createFromAscii ( " The index could not be deleted. An unknown error while accessing the file system occured. " ) ,
2006-07-10 13:25:09 +00:00
// TODO: resource
* m_pTable
2001-05-23 13:49:13 +00:00
) ;
2000-12-01 10:36:20 +00:00
}
2000-09-18 15:18:56 +00:00
// InfDatei abgleichen
2001-03-30 13:01:50 +00:00
: : rtl : : OUString sCfgFile ( m_pTable - > getConnection ( ) - > getURL ( ) ) ;
2001-07-16 08:58:40 +00:00
sCfgFile + = OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_DELIMITER ) ;
2001-03-30 13:01:50 +00:00
sCfgFile + = m_pTable - > getName ( ) ;
sCfgFile + = : : rtl : : OUString : : createFromAscii ( " .inf " ) ;
String sPhysicalPath ;
String sNDX ( sCfgFile ) ;
2006-06-20 00:19:57 +00:00
OSL_VERIFY_RES ( LocalFileHelper : : ConvertURLToPhysicalName ( sNDX , sPhysicalPath ) , " Can not convert Config Filename into Physical Name! " ) ;
2001-03-30 13:01:50 +00:00
Config aInfFile ( sPhysicalPath ) ;
2000-09-18 15:18:56 +00:00
aInfFile . SetGroup ( dBASE_III_GROUP ) ;
USHORT nKeyCnt = aInfFile . GetKeyCount ( ) ;
ByteString aKeyName ;
2001-03-30 13:01:50 +00:00
String sEntry = m_Name ;
sEntry + = String : : CreateFromAscii ( " .ndx " ) ;
2000-09-18 15:18:56 +00:00
2001-03-30 13:01:50 +00:00
// delete entries from the inf file
2000-09-18 15:18:56 +00:00
for ( USHORT nKey = 0 ; nKey < nKeyCnt ; nKey + + )
{
// Verweist der Key auf ein Indexfile?...
aKeyName = aInfFile . GetKeyName ( nKey ) ;
2001-04-30 12:22:34 +00:00
if ( aKeyName . Copy ( 0 , 3 ) = = " NDX " )
2000-09-18 15:18:56 +00:00
{
2001-03-30 13:01:50 +00:00
if ( sEntry = = String ( aInfFile . ReadKey ( aKeyName ) , m_pTable - > getConnection ( ) - > getTextEncoding ( ) ) )
2000-09-18 15:18:56 +00:00
{
aInfFile . DeleteKey ( aKeyName ) ;
break ;
}
}
}
return TRUE ;
}
// -------------------------------------------------------------------------
//------------------------------------------------------------------
BOOL ODbaseIndex : : CreateImpl ( )
{
// Anlegen des Index
2001-03-30 13:01:50 +00:00
: : rtl : : OUString sFile = getCompletePath ( ) ;
if ( UCBContentHelper : : Exists ( sFile ) )
2001-05-23 13:49:13 +00:00
throw SQLException (
: : rtl : : OUString : : createFromAscii ( " The index name can't be used, as it is already used for another table. " ) ,
* this ,
OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_ERRORMSG_SEQUENCE ) ,
1000 ,
Any ( )
) ;
2000-09-18 15:18:56 +00:00
// Index ist nur einstufig
2001-03-30 13:01:50 +00:00
if ( m_pColumns - > getCount ( ) > 1 )
2001-05-14 10:55:19 +00:00
throw SQLException ( : : rtl : : OUString : : createFromAscii ( " Not capable! Only one column per index. " ) , * this , OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_ERRORMSG_SEQUENCE ) , 1000 , Any ( ) ) ;
2000-09-18 15:18:56 +00:00
2000-11-03 13:21:22 +00:00
Reference < XFastPropertySet > xCol ;
2001-03-30 13:01:50 +00:00
: : cppu : : extractInterface ( xCol , m_pColumns - > getByIndex ( 0 ) ) ;
2000-09-18 15:18:56 +00:00
// ist die Spalte schon indiziert ?
if ( ! xCol . is ( ) )
2001-04-19 06:14:49 +00:00
: : dbtools : : throwFunctionSequenceException ( * this ) ;
2000-09-18 15:18:56 +00:00
// else if (pColumn && pColumn->IsIndexed())
// {
// String aText = String(OResId(STR_STAT_INDEX_COLUMN_ALREADY_INDEXED));
// aText.SearchAndReplace(String::CreateFromAscii("#"),pColumn->GetName());
// aStatus.Set(SDB_STAT_ERROR,
// String::CreateFromAscii("01000"),
// aStatus.CreateErrorMessage(aText),
// 0, String() );
// return FALSE;
// }
2001-03-30 13:01:50 +00:00
// create the index file
2001-07-17 11:37:19 +00:00
m_pFileStream = OFileTable : : createStream_simpleError ( sFile , STREAM_READWRITE | STREAM_SHARE_DENYWRITE | STREAM_TRUNC ) ;
2001-03-30 13:01:50 +00:00
if ( ! m_pFileStream )
2001-05-14 10:55:19 +00:00
throw SQLException ( : : rtl : : OUString : : createFromAscii ( " Could not access index file! " ) , * this , OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_ERRORMSG_SEQUENCE ) , 1000 , Any ( ) ) ;
2000-09-18 15:18:56 +00:00
2001-03-30 13:01:50 +00:00
m_pFileStream - > SetNumberFormatInt ( NUMBERFORMAT_INT_LITTLEENDIAN ) ;
m_pFileStream - > SetBufferSize ( 512 ) ;
2001-05-08 12:26:37 +00:00
m_pFileStream - > SetFiller ( ' \0 ' ) ;
2000-09-18 15:18:56 +00:00
2005-02-16 16:23:45 +00:00
// Zunaechst muss das Ergebnis sortiert sein
2001-03-30 13:01:50 +00:00
Reference < XStatement > xStmt ;
Reference < XResultSet > xSet ;
String aName ;
try
2000-09-18 15:18:56 +00:00
{
2001-03-30 13:01:50 +00:00
xStmt = m_pTable - > getConnection ( ) - > createStatement ( ) ;
aName = getString ( xCol - > getFastPropertyValue ( PROPERTY_ID_NAME ) ) ;
String aQuote ( m_pTable - > getConnection ( ) - > getMetaData ( ) - > getIdentifierQuoteString ( ) ) ;
String aStatement ;
aStatement . AssignAscii ( " SELECT " ) ;
2000-09-18 15:18:56 +00:00
aStatement + = aQuote ;
2001-03-30 13:01:50 +00:00
aStatement + = aName ;
2000-09-18 15:18:56 +00:00
aStatement + = aQuote ;
2001-03-30 13:01:50 +00:00
aStatement . AppendAscii ( " FROM " ) ;
aStatement + = aQuote ;
aStatement + = m_pTable - > getName ( ) . getStr ( ) ;
aStatement + = aQuote ;
aStatement . AppendAscii ( " ORDER BY " ) ;
aStatement + = aQuote ;
aStatement + = aName ;
aStatement + = aQuote ;
// if (!m_IsUnique) // zusaetzlich sortierung mit der bookmarkspalte
// {
// aStatement.AppendAscii(" ,");
// aStatement += aQuote;
// aStatement.AppendAscii("[BOOKMARK]"); // this is a special column
// aStatement += aQuote;
// }
2000-09-18 15:18:56 +00:00
2001-03-30 13:01:50 +00:00
xSet = xStmt - > executeQuery ( aStatement ) ;
}
catch ( Exception & e )
{
2000-09-18 15:18:56 +00:00
2001-03-30 13:01:50 +00:00
closeImpl ( ) ;
if ( UCBContentHelper : : Exists ( sFile ) )
UCBContentHelper : : Kill ( sFile ) ;
2001-05-14 10:55:19 +00:00
throw SQLException ( : : rtl : : OUString : : createFromAscii ( " Could not create index! " ) , * this , OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_ERRORMSG_SEQUENCE ) , 1000 , makeAny ( e ) ) ;
2001-03-30 13:01:50 +00:00
}
2000-09-18 15:18:56 +00:00
if ( ! xSet . is ( ) )
{
2001-03-30 13:01:50 +00:00
closeImpl ( ) ;
if ( UCBContentHelper : : Exists ( sFile ) )
UCBContentHelper : : Kill ( sFile ) ;
2001-05-14 10:55:19 +00:00
throw SQLException ( : : rtl : : OUString : : createFromAscii ( " Could not create index! " ) , * this , OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_ERRORMSG_SEQUENCE ) , 1000 , Any ( ) ) ;
2000-09-18 15:18:56 +00:00
}
// Setzen der Headerinfo
memset ( & m_aHeader , 0 , sizeof ( m_aHeader ) ) ;
2001-03-30 13:01:50 +00:00
m_pFileStream - > SetStreamSize ( 512 ) ;
2000-09-18 15:18:56 +00:00
sal_Int32 nType = 0 ;
2001-03-30 13:01:50 +00:00
: : vos : : ORef < OSQLColumns > aCols = m_pTable - > getTableColumns ( ) ;
Reference < XPropertySet > xTableCol ( * find ( aCols - > begin ( ) , aCols - > end ( ) , aName , : : comphelper : : UStringMixEqual ( isCaseSensitive ( ) ) ) ) ;
2001-05-14 10:55:19 +00:00
xTableCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_TYPE ) ) > > = nType ;
2000-09-18 15:18:56 +00:00
m_aHeader . db_keytype = ( nType = = DataType : : VARCHAR | | nType = = DataType : : CHAR ) ? 0 : 1 ;
2001-05-14 10:55:19 +00:00
m_aHeader . db_keylen = ( m_aHeader . db_keytype ) ? 8 : ( USHORT ) getINT32 ( xTableCol - > getPropertyValue ( OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_PRECISION ) ) ) ;
2000-09-18 15:18:56 +00:00
m_aHeader . db_maxkeys = ( 512 - 8 ) / ( 8 + m_aHeader . db_keylen ) ;
2001-03-30 13:01:50 +00:00
2001-02-05 11:26:42 +00:00
ByteString aCol ( aName , m_pTable - > getConnection ( ) - > getTextEncoding ( ) ) ;
2003-03-19 15:38:50 +00:00
strncpy ( m_aHeader . db_name , aCol . GetBuffer ( ) , std : : min ( ( USHORT ) sizeof ( m_aHeader . db_name ) , aCol . Len ( ) ) ) ;
2000-09-18 15:18:56 +00:00
m_aHeader . db_unique = m_IsUnique ? 1 : 0 ;
m_aHeader . db_keyrec = m_aHeader . db_keylen + 8 ;
// modifizierung am Header werden ueber Unterschiede zw. HeaderInfo und nRootPage
// bzw. nPageCout erkannt
m_nRootPage = 1 ;
m_nPageCount = 2 ;
// ODatabaseType eType = m_aHeader.db_keytype == 0 ? DataType::VARCHAR : DataType::DOUBLE;
m_aCurLeaf = m_aRoot = CreatePage ( m_nRootPage ) ;
m_aRoot - > SetModified ( TRUE ) ;
m_bUseCollector = TRUE ;
// ULONG nRowsLeft = pCursor->RowCount();
2001-05-08 12:26:37 +00:00
sal_Int32 nRowsLeft = 0 ;
2000-09-18 15:18:56 +00:00
Reference < XRow > xRow ( xSet , UNO_QUERY ) ;
2001-03-30 13:01:50 +00:00
if ( xSet - > last ( ) )
2000-09-18 15:18:56 +00:00
{
2007-06-05 13:21:18 +00:00
Reference < XUnoTunnel > xTunnel ( xSet , UNO_QUERY ) ;
2001-05-10 13:31:14 +00:00
ODbaseResultSet * pDbaseRes = NULL ;
if ( xTunnel . is ( ) )
2006-06-20 00:19:57 +00:00
pDbaseRes = reinterpret_cast < ODbaseResultSet * > ( xTunnel - > getSomething ( ODbaseResultSet : : getUnoTunnelImplementationId ( ) ) ) ;
2001-05-10 13:31:14 +00:00
OSL_ENSURE ( pDbaseRes , " No dbase resultset found? What's going on here! " ) ;
2001-05-08 12:26:37 +00:00
Reference < XRowLocate > xRowLocate ( xSet , UNO_QUERY ) ;
nRowsLeft = xSet - > getRow ( ) ;
2001-03-30 13:01:50 +00:00
2001-05-08 12:26:37 +00:00
xSet - > beforeFirst ( ) ;
2001-05-11 08:18:49 +00:00
ORowSetValue atmpValue = ORowSetValue ( ) ;
ONDXKey aKey ( atmpValue , nType , 0 ) ;
ONDXKey aInsertKey ( atmpValue , nType , 0 ) ;
2001-03-30 13:01:50 +00:00
// Erzeugen der Indexstruktur
while ( xSet - > next ( ) )
2000-09-18 15:18:56 +00:00
{
2001-03-30 13:01:50 +00:00
// ODbRow& rRow = *pCursor->GetRow();
2001-05-07 11:23:42 +00:00
ORowSetValue aValue ( m_aHeader . db_keytype ? ORowSetValue ( xRow - > getDouble ( 1 ) ) : ORowSetValue ( xRow - > getString ( 1 ) ) ) ;
2001-03-30 13:01:50 +00:00
// ueberpruefen auf doppelten eintrag
if ( m_IsUnique & & m_nCurNode ! = NODE_NOTFOUND )
2000-09-18 15:18:56 +00:00
{
2001-05-07 11:23:42 +00:00
aKey . setValue ( aValue ) ;
2001-03-30 13:01:50 +00:00
if ( aKey = = ( * m_aCurLeaf ) [ m_nCurNode ] . GetKey ( ) )
{
2001-05-08 12:26:37 +00:00
: : comphelper : : disposeComponent ( xSet ) ;
: : comphelper : : disposeComponent ( xStmt ) ;
2001-03-30 13:01:50 +00:00
closeImpl ( ) ;
if ( UCBContentHelper : : Exists ( sFile ) )
UCBContentHelper : : Kill ( sFile ) ;
2006-07-10 13:25:09 +00:00
: : dbtools : : throwGenericSQLException (
: : rtl : : OUString : : createFromAscii ( " Can not create index. Values are not unique! " ) ,
* this
) ;
2001-03-30 13:01:50 +00:00
}
2000-09-18 15:18:56 +00:00
}
2001-05-07 11:23:42 +00:00
aInsertKey . setValue ( aValue ) ;
2001-05-10 13:31:14 +00:00
aInsertKey . setRecord ( pDbaseRes - > getCurrentFilePos ( ) ) ;
2001-05-07 11:23:42 +00:00
ONDXNode aNewNode ( aInsertKey ) ;
2001-03-30 13:01:50 +00:00
if ( ! m_aCurLeaf - > Insert ( aNewNode , - - nRowsLeft ) )
break ;
2000-09-18 15:18:56 +00:00
}
}
2001-03-30 13:01:50 +00:00
xRow = NULL ;
: : comphelper : : disposeComponent ( xSet ) ;
: : comphelper : : disposeComponent ( xStmt ) ;
2000-09-18 15:18:56 +00:00
2001-05-08 12:26:37 +00:00
if ( nRowsLeft )
{
closeImpl ( ) ;
if ( UCBContentHelper : : Exists ( sFile ) )
UCBContentHelper : : Kill ( sFile ) ;
2001-05-14 10:55:19 +00:00
throw SQLException ( : : rtl : : OUString : : createFromAscii ( " Could not create index! " ) , * this , OMetaConnection : : getPropMap ( ) . getNameByIndex ( PROPERTY_ID_ERRORMSG_SEQUENCE ) , 1000 , Any ( ) ) ;
2001-05-08 12:26:37 +00:00
}
2001-03-30 13:01:50 +00:00
Release ( ) ;
createINFEntry ( ) ;
2000-09-18 15:18:56 +00:00
return sal_True ;
}
2001-03-30 13:01:50 +00:00
// -----------------------------------------------------------------------------
2001-04-30 09:16:19 +00:00
// -----------------------------------------------------------------------------
2001-10-18 08:41:25 +00:00
void SAL_CALL ODbaseIndex : : acquire ( ) throw ( )
2001-04-30 09:16:19 +00:00
{
ODbaseIndex_BASE : : acquire ( ) ;
}
// -----------------------------------------------------------------------------
2001-10-18 08:41:25 +00:00
void SAL_CALL ODbaseIndex : : release ( ) throw ( )
2001-04-30 09:16:19 +00:00
{
ODbaseIndex_BASE : : release ( ) ;
}
// -----------------------------------------------------------------------------
2000-09-18 15:18:56 +00:00