LCOV - code coverage report
Current view: top level - connectivity/source/drivers/dbase - DIndex.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 290 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 31 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "dbase/DIndex.hxx"
      21             : #include "dbase/DIndexColumns.hxx"
      22             : #include <com/sun/star/lang/DisposedException.hpp>
      23             : #include <connectivity/sdbcx/VColumn.hxx>
      24             : #include <comphelper/sequence.hxx>
      25             : #include "dbase/DTable.hxx"
      26             : #include "dbase/DIndexIter.hxx"
      27             : #include <tools/config.hxx>
      28             : #include <connectivity/CommonTools.hxx>
      29             : #include <com/sun/star/sdbc/XResultSetMetaData.hpp>
      30             : #include <com/sun/star/sdbc/XResultSet.hpp>
      31             : #include <com/sun/star/sdbcx/XRowLocate.hpp>
      32             : #include <com/sun/star/sdbc/XRow.hpp>
      33             : #include <comphelper/extract.hxx>
      34             : #include <unotools/localfilehelper.hxx>
      35             : #include <unotools/ucbhelper.hxx>
      36             : #include <comphelper/types.hxx>
      37             : #include <connectivity/dbexception.hxx>
      38             : #include "dbase/DResultSet.hxx"
      39             : #include "diagnose_ex.h"
      40             : #include "resource/dbase_res.hrc"
      41             : #include <unotools/sharedunocomponent.hxx>
      42             : 
      43             : using namespace ::comphelper;
      44             : 
      45             : using namespace connectivity;
      46             : using namespace utl;
      47             : using namespace ::cppu;
      48             : using namespace connectivity::file;
      49             : using namespace connectivity::sdbcx;
      50             : using namespace connectivity::dbase;
      51             : using namespace com::sun::star::sdbc;
      52             : using namespace com::sun::star::sdbcx;
      53             : using namespace com::sun::star::uno;
      54             : using namespace com::sun::star::beans;
      55             : using namespace com::sun::star::lang;
      56             : 
      57           0 : IMPLEMENT_SERVICE_INFO(ODbaseIndex,"com.sun.star.sdbcx.driver.dbase.Index","com.sun.star.sdbcx.Index");
      58             : 
      59           0 : ODbaseIndex::ODbaseIndex(ODbaseTable* _pTable)
      60             :     : OIndex(true/*_pTable->getConnection()->getMetaData()->supportsMixedCaseQuotedIdentifiers()*/)
      61             :     , m_pFileStream(NULL)
      62             :     , m_nCurNode(NODE_NOTFOUND)
      63             :     , m_nPageCount(0)
      64             :     , m_nRootPage(0)
      65             :     , m_pTable(_pTable)
      66           0 :     , m_bUseCollector(false)
      67             : {
      68           0 :     memset(&m_aHeader, 0, sizeof(m_aHeader));
      69           0 :     construct();
      70           0 : }
      71             : 
      72           0 : ODbaseIndex::ODbaseIndex(   ODbaseTable* _pTable,
      73             :                             const NDXHeader& _rHeader,
      74             :                             const OUString& _rName)
      75             :     : OIndex(_rName, OUString(), _rHeader.db_unique, false, false, true)
      76             :     , m_pFileStream(NULL)
      77             :     , m_aHeader(_rHeader)
      78             :     , m_nCurNode(NODE_NOTFOUND)
      79             :     , m_nPageCount(0)
      80             :     , m_nRootPage(0)
      81             :     , m_pTable(_pTable)
      82           0 :     , m_bUseCollector(false)
      83             : {
      84           0 :     construct();
      85           0 : }
      86             : 
      87           0 : ODbaseIndex::~ODbaseIndex()
      88             : {
      89           0 :     closeImpl();
      90           0 : }
      91             : 
      92           0 : void ODbaseIndex::refreshColumns()
      93             : {
      94           0 :     ::osl::MutexGuard aGuard( m_aMutex );
      95             : 
      96           0 :     TStringVector aVector;
      97           0 :     if(!isNew())
      98             :     {
      99             :         OSL_ENSURE(m_pFileStream,"FileStream is not opened!");
     100             :         OSL_ENSURE(m_aHeader.db_name[0] != '\0',"Invalid name for the column!");
     101           0 :         aVector.push_back(OUString::createFromAscii(m_aHeader.db_name));
     102             :     }
     103             : 
     104           0 :     if(m_pColumns)
     105           0 :         m_pColumns->reFill(aVector);
     106             :     else
     107           0 :         m_pColumns = new ODbaseIndexColumns(this,m_aMutex,aVector);
     108           0 : }
     109             : 
     110           0 : Sequence< sal_Int8 > ODbaseIndex::getUnoTunnelImplementationId()
     111             : {
     112             :     static ::cppu::OImplementationId * pId = 0;
     113           0 :     if (! pId)
     114             :     {
     115           0 :         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
     116           0 :         if (! pId)
     117             :         {
     118           0 :             static ::cppu::OImplementationId aId;
     119           0 :             pId = &aId;
     120           0 :         }
     121             :     }
     122           0 :     return pId->getImplementationId();
     123             : }
     124             : 
     125             : // XUnoTunnel
     126             : 
     127           0 : sal_Int64 ODbaseIndex::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException, std::exception)
     128             : {
     129           0 :     return (rId.getLength() == 16 && 0 == memcmp(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
     130             :                 ? reinterpret_cast< sal_Int64 >( this )
     131           0 :                 : ODbaseIndex_BASE::getSomething(rId);
     132             : }
     133             : 
     134           0 : ONDXPagePtr ODbaseIndex::getRoot()
     135             : {
     136           0 :     openIndexFile();
     137           0 :     if (!m_aRoot.Is())
     138             :     {
     139           0 :         m_nRootPage = m_aHeader.db_rootpage;
     140           0 :         m_nPageCount = m_aHeader.db_pagecount;
     141           0 :         m_aRoot = CreatePage(m_nRootPage,NULL,true);
     142             :     }
     143           0 :     return m_aRoot;
     144             : }
     145             : 
     146           0 : bool ODbaseIndex::openIndexFile()
     147             : {
     148           0 :     if(!m_pFileStream)
     149             :     {
     150           0 :         OUString sFile = getCompletePath();
     151           0 :         if(UCBContentHelper::Exists(sFile))
     152             :         {
     153           0 :             m_pFileStream = OFileTable::createStream_simpleError(sFile, STREAM_READWRITE | StreamMode::NOCREATE | StreamMode::SHARE_DENYWRITE);
     154           0 :             if (!m_pFileStream)
     155           0 :                 m_pFileStream = OFileTable::createStream_simpleError(sFile, StreamMode::READ | StreamMode::NOCREATE | StreamMode::SHARE_DENYNONE);
     156           0 :             if(m_pFileStream)
     157             :             {
     158           0 :                 m_pFileStream->SetEndian(SvStreamEndian::LITTLE);
     159           0 :                 m_pFileStream->SetBufferSize(DINDEX_PAGE_SIZE);
     160           0 :                 (*m_pFileStream) >> *this;
     161             :             }
     162             :         }
     163           0 :         if(!m_pFileStream)
     164             :         {
     165           0 :             const OUString sError( m_pTable->getConnection()->getResources().getResourceStringWithSubstitution(
     166             :                 STR_COULD_NOT_LOAD_FILE,
     167             :                 "$filename$", sFile
     168           0 :              ) );
     169           0 :             ::dbtools::throwGenericSQLException( sError, *this );
     170           0 :         }
     171             :     }
     172             : 
     173           0 :     return m_pFileStream != NULL;
     174             : }
     175             : 
     176           0 : OIndexIterator* ODbaseIndex::createIterator(OBoolOperator* pOp,
     177             :                                             const OOperand* pOperand)
     178             : {
     179           0 :     openIndexFile();
     180           0 :     return new OIndexIterator(this, pOp, pOperand);
     181             : }
     182             : 
     183           0 : bool ODbaseIndex::ConvertToKey(ONDXKey* rKey, sal_uInt32 nRec, const ORowSetValue& rValue)
     184             : {
     185             :     OSL_ENSURE(m_pFileStream,"FileStream is not opened!");
     186             :     // Search a specific value in Index
     187             :     // If the Index is unique, the key doesn't matter
     188             :     try
     189             :     {
     190           0 :         if (m_aHeader.db_keytype == 0)
     191             :         {
     192           0 :             *rKey = ONDXKey(rValue.getString(), nRec );
     193             :         }
     194             :         else
     195             :         {
     196           0 :             if (rValue.isNull())
     197           0 :                 *rKey = ONDXKey(rValue.getDouble(), DataType::DOUBLE, nRec );
     198             :             else
     199           0 :                 *rKey = ONDXKey(rValue.getDouble(), nRec );
     200             :         }
     201             :     }
     202           0 :     catch (Exception&)
     203             :     {
     204             :         OSL_ASSERT(false);
     205           0 :         return false;
     206             :     }
     207           0 :     return true;
     208             : }
     209             : 
     210             : 
     211           0 : bool ODbaseIndex::Find(sal_uInt32 nRec, const ORowSetValue& rValue)
     212             : {
     213           0 :     openIndexFile();
     214             :     OSL_ENSURE(m_pFileStream,"FileStream is not opened!");
     215             :     // Search a specific value in Index
     216             :     // If the Index is unique, the key doesn't matter
     217           0 :     ONDXKey aKey;
     218           0 :     return ConvertToKey(&aKey, nRec, rValue) && getRoot()->Find(aKey);
     219             : }
     220             : 
     221             : 
     222           0 : bool ODbaseIndex::Insert(sal_uInt32 nRec, const ORowSetValue& rValue)
     223             : {
     224           0 :     openIndexFile();
     225             :     OSL_ENSURE(m_pFileStream,"FileStream is not opened!");
     226           0 :     ONDXKey aKey;
     227             : 
     228             :     // Does the value already exist
     229             :     // Use Find() always to determine the actual leaf
     230           0 :     if (!ConvertToKey(&aKey, nRec, rValue) || (getRoot()->Find(aKey) && isUnique()))
     231           0 :         return false;
     232             : 
     233           0 :     ONDXNode aNewNode(aKey);
     234             : 
     235             :     // insert in the current leaf
     236           0 :     if (!m_aCurLeaf.Is())
     237           0 :         return false;
     238             : 
     239           0 :     bool bResult = m_aCurLeaf->Insert(aNewNode);
     240           0 :     Release(bResult);
     241             : 
     242           0 :     return bResult;
     243             : }
     244             : 
     245             : 
     246           0 : bool ODbaseIndex::Update(sal_uInt32 nRec, const ORowSetValue& rOldValue,
     247             :                          const ORowSetValue& rNewValue)
     248             : {
     249           0 :     openIndexFile();
     250             :     OSL_ENSURE(m_pFileStream,"FileStream is not opened!");
     251           0 :     ONDXKey aKey;
     252           0 :     if (!ConvertToKey(&aKey, nRec, rNewValue) || (isUnique() && getRoot()->Find(aKey)))
     253           0 :         return false;
     254             :     else
     255           0 :         return Delete(nRec, rOldValue) && Insert(nRec,rNewValue);
     256             : }
     257             : 
     258             : 
     259           0 : bool ODbaseIndex::Delete(sal_uInt32 nRec, const ORowSetValue& rValue)
     260             : {
     261           0 :     openIndexFile();
     262             :     OSL_ENSURE(m_pFileStream,"FileStream is not opened!");
     263             :     // Does the value already exist
     264             :     // Always use Find() to determine the actual leaf
     265           0 :     ONDXKey aKey;
     266           0 :     if (!ConvertToKey(&aKey, nRec, rValue) || !getRoot()->Find(aKey))
     267           0 :         return false;
     268             : 
     269           0 :     ONDXNode aNewNode(aKey);
     270             : 
     271             :     // insert in the current leaf
     272           0 :     if (!m_aCurLeaf.Is())
     273           0 :         return false;
     274             : #if OSL_DEBUG_LEVEL > 1
     275             :     m_aRoot->PrintPage();
     276             : #endif
     277             : 
     278           0 :     return m_aCurLeaf->Delete(m_nCurNode);
     279             : }
     280             : 
     281           0 : void ODbaseIndex::Collect(ONDXPage* pPage)
     282             : {
     283           0 :     if (pPage)
     284           0 :         m_aCollector.push_back(pPage);
     285           0 : }
     286             : 
     287           0 : void ODbaseIndex::Release(bool bSave)
     288             : {
     289             :     // Release the Index-recources
     290           0 :     m_bUseCollector = false;
     291             : 
     292           0 :     if (m_aCurLeaf.Is())
     293             :     {
     294           0 :         m_aCurLeaf->Release(bSave);
     295           0 :         m_aCurLeaf.Clear();
     296             :     }
     297             : 
     298             :     // Release the root
     299           0 :     if (m_aRoot.Is())
     300             :     {
     301           0 :         m_aRoot->Release(bSave);
     302           0 :         m_aRoot.Clear();
     303             :     }
     304             :     // Release all references, before the FileStream will be closed
     305           0 :     for (sal_uIntPtr i = 0; i < m_aCollector.size(); i++)
     306           0 :         m_aCollector[i]->QueryDelete();
     307             : 
     308           0 :     m_aCollector.clear();
     309             : 
     310             :     // Header modified?
     311           0 :     if (bSave && (m_aHeader.db_rootpage != m_nRootPage ||
     312           0 :         m_aHeader.db_pagecount != m_nPageCount))
     313             :     {
     314           0 :         m_aHeader.db_rootpage = m_nRootPage;
     315           0 :         m_aHeader.db_pagecount = m_nPageCount;
     316           0 :         WriteODbaseIndex( *m_pFileStream, *this );
     317             :     }
     318           0 :     m_nRootPage = m_nPageCount = 0;
     319           0 :     m_nCurNode = NODE_NOTFOUND;
     320             : 
     321           0 :     closeImpl();
     322           0 : }
     323             : 
     324           0 : void ODbaseIndex::closeImpl()
     325             : {
     326           0 :     if(m_pFileStream)
     327             :     {
     328           0 :         delete m_pFileStream;
     329           0 :         m_pFileStream = NULL;
     330             :     }
     331           0 : }
     332             : 
     333           0 : ONDXPage* ODbaseIndex::CreatePage(sal_uInt32 nPagePos, ONDXPage* pParent, bool bLoad)
     334             : {
     335             :     OSL_ENSURE(m_pFileStream,"FileStream is not opened!");
     336             : 
     337             :     ONDXPage* pPage;
     338           0 :     if ( !m_aCollector.empty() )
     339             :     {
     340           0 :         pPage = *(m_aCollector.rbegin());
     341           0 :         m_aCollector.pop_back();
     342           0 :         pPage->SetPagePos(nPagePos);
     343           0 :         pPage->SetParent(pParent);
     344             :     }
     345             :     else
     346           0 :         pPage = new ONDXPage(*this, nPagePos, pParent);
     347             : 
     348           0 :     if (bLoad)
     349           0 :         (*m_pFileStream) >> *pPage;
     350             : 
     351           0 :     return pPage;
     352             : }
     353             : 
     354             : 
     355           0 : SvStream& connectivity::dbase::operator >> (SvStream &rStream, ODbaseIndex& rIndex)
     356             : {
     357           0 :     rStream.Seek(0);
     358           0 :     rStream.Read(&rIndex.m_aHeader,DINDEX_PAGE_SIZE);
     359             : 
     360           0 :     rIndex.m_nRootPage = rIndex.m_aHeader.db_rootpage;
     361           0 :     rIndex.m_nPageCount = rIndex.m_aHeader.db_pagecount;
     362           0 :     return rStream;
     363             : }
     364             : 
     365           0 : SvStream& connectivity::dbase::WriteODbaseIndex(SvStream &rStream, ODbaseIndex& rIndex)
     366             : {
     367           0 :     rStream.Seek(0);
     368           0 :     OSL_VERIFY_EQUALS( rStream.Write(&rIndex.m_aHeader,DINDEX_PAGE_SIZE), DINDEX_PAGE_SIZE, "Write not successful: Wrong header size for dbase index!");
     369           0 :     return rStream;
     370             : }
     371             : 
     372           0 : OUString ODbaseIndex::getCompletePath()
     373             : {
     374           0 :     OUString sDir = m_pTable->getConnection()->getURL() +
     375           0 :         OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DELIMITER) +
     376           0 :         m_Name + ".ndx";
     377           0 :     return sDir;
     378             : }
     379             : 
     380           0 : void ODbaseIndex::createINFEntry()
     381             : {
     382             :     // synchronize inf-file
     383           0 :     const OUString sEntry(m_Name + ".ndx");
     384             : 
     385           0 :     OUString sCfgFile(m_pTable->getConnection()->getURL() +
     386           0 :                       OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DELIMITER) +
     387           0 :                       m_pTable->getName() +
     388           0 :                       ".inf");
     389             : 
     390           0 :     OUString sPhysicalPath;
     391           0 :     LocalFileHelper::ConvertURLToPhysicalName(sCfgFile, sPhysicalPath);
     392             : 
     393           0 :     Config aInfFile(sPhysicalPath);
     394           0 :     aInfFile.SetGroup(dBASE_III_GROUP);
     395             : 
     396           0 :     sal_uInt16 nSuffix = aInfFile.GetKeyCount();
     397           0 :     OString aNewEntry,aKeyName;
     398           0 :     bool bCase = isCaseSensitive();
     399           0 :     while (aNewEntry.isEmpty())
     400             :     {
     401           0 :         aNewEntry = OString("NDX");
     402           0 :         aNewEntry += OString::number(++nSuffix);
     403           0 :         for (sal_uInt16 i = 0; i < aInfFile.GetKeyCount(); i++)
     404             :         {
     405           0 :             aKeyName = aInfFile.GetKeyName(i);
     406           0 :             if (bCase ? aKeyName.equals(aNewEntry) : aKeyName.equalsIgnoreAsciiCase(aNewEntry))
     407             :             {
     408           0 :                 aNewEntry.clear();
     409           0 :                 break;
     410             :             }
     411             :         }
     412             :     }
     413           0 :     aInfFile.WriteKey(aNewEntry, OUStringToOString(sEntry, m_pTable->getConnection()->getTextEncoding()));
     414           0 : }
     415             : 
     416           0 : bool ODbaseIndex::DropImpl()
     417             : {
     418           0 :     closeImpl();
     419             : 
     420           0 :     OUString sPath = getCompletePath();
     421           0 :     if(UCBContentHelper::Exists(sPath))
     422             :     {
     423           0 :         if(!UCBContentHelper::Kill(sPath))
     424           0 :             m_pTable->getConnection()->throwGenericSQLException(STR_COULD_NOT_DELETE_INDEX,*m_pTable);
     425             :     }
     426             : 
     427             :     // synchronize inf-file
     428           0 :     OUString sCfgFile = m_pTable->getConnection()->getURL() +
     429           0 :         OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DELIMITER) +
     430           0 :         m_pTable->getName() + ".inf";
     431             : 
     432           0 :     OUString sPhysicalPath;
     433             :     OSL_VERIFY_RES( LocalFileHelper::ConvertURLToPhysicalName(sCfgFile, sPhysicalPath),
     434           0 :         "Can not convert Config Filename into Physical Name!");
     435             : 
     436           0 :     Config aInfFile(sPhysicalPath);
     437           0 :     aInfFile.SetGroup(dBASE_III_GROUP);
     438           0 :     sal_uInt16 nKeyCnt = aInfFile.GetKeyCount();
     439           0 :     OString aKeyName;
     440           0 :     OUString sEntry = m_Name + ".ndx";
     441             : 
     442             :     // delete entries from the inf file
     443           0 :     for (sal_uInt16 nKey = 0; nKey < nKeyCnt; nKey++)
     444             :     {
     445             :         // References the Key to an Index-file?
     446           0 :         aKeyName = aInfFile.GetKeyName( nKey );
     447           0 :         if (aKeyName.copy(0,3) == "NDX")
     448             :         {
     449           0 :             if(sEntry == OStringToOUString(aInfFile.ReadKey(aKeyName),m_pTable->getConnection()->getTextEncoding()))
     450             :             {
     451           0 :                 aInfFile.DeleteKey(aKeyName);
     452           0 :                 break;
     453             :             }
     454             :         }
     455             :     }
     456           0 :     return true;
     457             : }
     458             : 
     459           0 : void ODbaseIndex::impl_killFileAndthrowError_throw(sal_uInt16 _nErrorId,const OUString& _sFile)
     460             : {
     461           0 :     closeImpl();
     462           0 :     if(UCBContentHelper::Exists(_sFile))
     463           0 :         UCBContentHelper::Kill(_sFile);
     464           0 :     m_pTable->getConnection()->throwGenericSQLException(_nErrorId,*this);
     465           0 : }
     466             : 
     467           0 : bool ODbaseIndex::CreateImpl()
     468             : {
     469             :     // Create the Index
     470           0 :     const OUString sFile = getCompletePath();
     471           0 :     if(UCBContentHelper::Exists(sFile))
     472             :     {
     473           0 :         const OUString sError( m_pTable->getConnection()->getResources().getResourceStringWithSubstitution(
     474             :             STR_COULD_NOT_CREATE_INDEX_NAME,
     475             :             "$filename$", sFile
     476           0 :          ) );
     477           0 :         ::dbtools::throwGenericSQLException( sError, *this );
     478             :     }
     479             :     // Index comprises only one column
     480           0 :     if (m_pColumns->getCount() > 1)
     481           0 :         m_pTable->getConnection()->throwGenericSQLException(STR_ONL_ONE_COLUMN_PER_INDEX,*this);
     482             : 
     483           0 :     Reference<XFastPropertySet> xCol(m_pColumns->getByIndex(0),UNO_QUERY);
     484             : 
     485             :     // Is the column already indexed?
     486           0 :     if ( !xCol.is() )
     487           0 :         ::dbtools::throwFunctionSequenceException(*this);
     488             : 
     489             :     // create the index file
     490           0 :     m_pFileStream = OFileTable::createStream_simpleError(sFile,STREAM_READWRITE | StreamMode::SHARE_DENYWRITE | StreamMode::TRUNC);
     491           0 :     if (!m_pFileStream)
     492             :     {
     493           0 :         const OUString sError( m_pTable->getConnection()->getResources().getResourceStringWithSubstitution(
     494             :             STR_COULD_NOT_LOAD_FILE,
     495             :             "$filename$", sFile
     496           0 :          ) );
     497           0 :         ::dbtools::throwGenericSQLException( sError, *this );
     498             :     }
     499             : 
     500           0 :     m_pFileStream->SetEndian(SvStreamEndian::LITTLE);
     501           0 :     m_pFileStream->SetBufferSize(DINDEX_PAGE_SIZE);
     502             : 
     503             :     // firstly the result must be sorted
     504           0 :     utl::SharedUNOComponent<XStatement> xStmt;
     505           0 :     utl::SharedUNOComponent<XResultSet> xSet;
     506           0 :     OUString aName;
     507             :     try
     508             :     {
     509           0 :         xStmt.set( m_pTable->getConnection()->createStatement(), UNO_SET_THROW);
     510             : 
     511           0 :         aName = getString(xCol->getFastPropertyValue(PROPERTY_ID_NAME));
     512             : 
     513           0 :         const OUString aQuote(m_pTable->getConnection()->getMetaData()->getIdentifierQuoteString());
     514           0 :         OUString aStatement( "SELECT " + aQuote + aName + aQuote +" FROM " + aQuote + m_pTable->getName() + aQuote + " ORDER BY " + aQuote + aName + aQuote);
     515             : 
     516           0 :         xSet.set( xStmt->executeQuery(aStatement),UNO_SET_THROW );
     517             :     }
     518           0 :     catch(const Exception& )
     519             :     {
     520           0 :         impl_killFileAndthrowError_throw(STR_COULD_NOT_CREATE_INDEX,sFile);
     521             :     }
     522           0 :     if (!xSet.is())
     523             :     {
     524           0 :         impl_killFileAndthrowError_throw(STR_COULD_NOT_CREATE_INDEX,sFile);
     525             :     }
     526             : 
     527             :     // Set the header info
     528           0 :     memset(&m_aHeader,0,sizeof(m_aHeader));
     529           0 :     sal_Int32 nType = 0;
     530           0 :     ::rtl::Reference<OSQLColumns> aCols = m_pTable->getTableColumns();
     531           0 :     const Reference< XPropertySet > xTableCol(*find(aCols->get().begin(),aCols->get().end(),aName,::comphelper::UStringMixEqual(isCaseSensitive())));
     532             : 
     533           0 :     xTableCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nType;
     534             : 
     535           0 :     m_aHeader.db_keytype = (nType == DataType::VARCHAR || nType == DataType::CHAR) ? 0 : 1;
     536           0 :     m_aHeader.db_keylen  = (m_aHeader.db_keytype) ? 8 : (sal_uInt16)getINT32(xTableCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION)));
     537           0 :     m_aHeader.db_keylen = (( m_aHeader.db_keylen - 1) / 4 + 1) * 4;
     538           0 :     m_aHeader.db_maxkeys = (DINDEX_PAGE_SIZE - 4) / (8 + m_aHeader.db_keylen);
     539           0 :     if ( m_aHeader.db_maxkeys < 3 )
     540             :     {
     541           0 :         impl_killFileAndthrowError_throw(STR_COULD_NOT_CREATE_INDEX_KEYSIZE,sFile);
     542             :     }
     543             : 
     544           0 :     m_pFileStream->SetStreamSize(DINDEX_PAGE_SIZE);
     545             : 
     546           0 :     OString aCol(OUStringToOString(aName, m_pTable->getConnection()->getTextEncoding()));
     547           0 :     strncpy(m_aHeader.db_name, aCol.getStr(), std::min<size_t>(sizeof(m_aHeader.db_name), aCol.getLength()));
     548           0 :     m_aHeader.db_unique  = m_IsUnique ? 1: 0;
     549           0 :     m_aHeader.db_keyrec  = m_aHeader.db_keylen + 8;
     550             : 
     551             :     // modifications of the header are detected by differences between
     552             :     // the HeaderInfo and nRootPage or nPageCount respectively
     553           0 :     m_nRootPage = 1;
     554           0 :     m_nPageCount = 2;
     555             : 
     556           0 :     m_aCurLeaf = m_aRoot = CreatePage(m_nRootPage);
     557           0 :     m_aRoot->SetModified(true);
     558             : 
     559           0 :     m_bUseCollector = true;
     560             : 
     561           0 :     sal_Int32 nRowsLeft = 0;
     562           0 :     Reference<XRow> xRow(xSet,UNO_QUERY);
     563             : 
     564           0 :     if(xSet->last())
     565             :     {
     566           0 :         Reference< XUnoTunnel> xTunnel(xSet, UNO_QUERY_THROW);
     567           0 :         ODbaseResultSet* pDbaseRes = reinterpret_cast< ODbaseResultSet* >( xTunnel->getSomething(ODbaseResultSet::getUnoTunnelImplementationId()) );
     568             :         assert(pDbaseRes); //"No dbase resultset found? What's going on here!
     569           0 :         Reference<XRowLocate> xRowLocate(xSet,UNO_QUERY);
     570           0 :         nRowsLeft = xSet->getRow();
     571             : 
     572           0 :         xSet->beforeFirst();
     573           0 :         ORowSetValue    atmpValue=ORowSetValue();
     574           0 :         ONDXKey aKey(atmpValue, nType, 0);
     575           0 :         ONDXKey aInsertKey(atmpValue, nType, 0);
     576             :         // Create the index structure
     577           0 :         while (xSet->next())
     578             :         {
     579           0 :             ORowSetValue aValue(m_aHeader.db_keytype ? ORowSetValue(xRow->getDouble(1)) : ORowSetValue(xRow->getString(1)));
     580             :             // checking for duplicate entries
     581           0 :             if (m_IsUnique && m_nCurNode != NODE_NOTFOUND)
     582             :             {
     583           0 :                 aKey.setValue(aValue);
     584           0 :                 if (aKey == (*m_aCurLeaf)[m_nCurNode].GetKey())
     585             :                 {
     586           0 :                     impl_killFileAndthrowError_throw(STR_COULD_NOT_CREATE_INDEX_NOT_UNIQUE,sFile);
     587             :                 }
     588             :             }
     589           0 :             aInsertKey.setValue(aValue);
     590           0 :             aInsertKey.setRecord(pDbaseRes->getCurrentFilePos());
     591             : 
     592           0 :             ONDXNode aNewNode(aInsertKey);
     593           0 :             if (!m_aCurLeaf->Insert(aNewNode, --nRowsLeft))
     594           0 :                 break;
     595           0 :         }
     596             :     }
     597             : 
     598           0 :     if(nRowsLeft)
     599             :     {
     600           0 :         impl_killFileAndthrowError_throw(STR_COULD_NOT_CREATE_INDEX,sFile);
     601             :     }
     602           0 :     Release();
     603           0 :     createINFEntry();
     604           0 :     return true;
     605             : }
     606             : 
     607             : 
     608           0 : void SAL_CALL ODbaseIndex::acquire() throw()
     609             : {
     610           0 :     ODbaseIndex_BASE::acquire();
     611           0 : }
     612             : 
     613           0 : void SAL_CALL ODbaseIndex::release() throw()
     614             : {
     615           0 :     ODbaseIndex_BASE::release();
     616           0 : }
     617             : 
     618             : 
     619             : 
     620             : 
     621             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11