1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "core_resource.hxx"
22 #include "core_resource.hrc"
23 #include <com/sun/star/beans/XPropertySet.hpp>
24 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
25 #include <com/sun/star/sdbc/ColumnValue.hpp>
26 #include <com/sun/star/sdbc/XPreparedStatement.hpp>
27 #include <com/sun/star/sdbc/XParameters.hpp>
28 #include <com/sun/star/sdbc/XGeneratedResultSet.hpp>
29 #include <com/sun/star/sdbc/XColumnLocate.hpp>
30 #include <com/sun/star/container/XIndexAccess.hpp>
31 #include "dbastrings.hrc"
32 #include "apitools.hxx"
33 #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
34 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
35 #include <com/sun/star/sdbcx/XIndexesSupplier.hpp>
36 #include <cppuhelper/typeprovider.hxx>
37 #include <comphelper/types.hxx>
38 #include <com/sun/star/sdbcx/KeyType.hpp>
39 #include <connectivity/dbtools.hxx>
40 #include <connectivity/dbexception.hxx>
44 #include <com/sun/star/io/XInputStream.hpp>
45 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
46 #include "querycomposer.hxx"
47 #include "composertools.hxx"
48 #include <tools/debug.hxx>
49 #include <rtl/logfile.hxx>
50 #include "PrivateRow.hxx"
52 using namespace dbaccess
;
53 using namespace ::connectivity
;
54 using namespace ::dbtools
;
55 using namespace ::com::sun::star::uno
;
56 using namespace ::com::sun::star::beans
;
57 using namespace ::com::sun::star::sdbc
;
58 using namespace ::com::sun::star::sdb
;
59 using namespace ::com::sun::star::sdbcx
;
60 using namespace ::com::sun::star::container
;
61 using namespace ::com::sun::star::lang
;
62 using namespace ::com::sun::star::util
;
63 using namespace ::com::sun::star::io
;
64 using namespace ::com::sun::star
;
65 using namespace ::cppu
;
66 using namespace ::osl
;
70 void lcl_fillIndexColumns(const Reference
<XIndexAccess
>& _xIndexes
, ::std::vector
< Reference
<XNameAccess
> >& _rAllIndexColumns
)
74 Reference
<XPropertySet
> xIndexColsSup
;
75 sal_Int32 nCount
= _xIndexes
->getCount();
76 for(sal_Int32 j
= 0 ; j
< nCount
; ++j
)
78 xIndexColsSup
.set(_xIndexes
->getByIndex(j
),UNO_QUERY
);
79 if( xIndexColsSup
.is()
80 && comphelper::getBOOL(xIndexColsSup
->getPropertyValue(PROPERTY_ISUNIQUE
))
81 && !comphelper::getBOOL(xIndexColsSup
->getPropertyValue(PROPERTY_ISPRIMARYKEYINDEX
))
83 _rAllIndexColumns
.push_back(Reference
<XColumnsSupplier
>(xIndexColsSup
,UNO_QUERY
)->getColumns());
88 template < typename T
> inline void tryDispose( Reference
<T
> &r
)
92 ::comphelper::disposeComponent(r
);
94 catch(const Exception
&)
100 OSL_FAIL("Unknown Exception occurred");
106 OKeySet::OKeySet(const connectivity::OSQLTable
& _xTable
,
107 const Reference
< XIndexAccess
>& _xTableKeys
,
108 const ::rtl::OUString
& _rUpdateTableName
, // this can be the alias or the full qualified name
109 const Reference
< XSingleSelectQueryAnalyzer
>& _xComposer
,
110 const ORowSetValueVector
& _aParameterValueForCache
,
111 sal_Int32 i_nMaxRows
,
112 sal_Int32
& o_nRowCount
)
113 :OCacheSet(i_nMaxRows
)
114 ,m_aParameterValueForCache(_aParameterValueForCache
)
115 ,m_pKeyColumnNames(NULL
)
116 ,m_pColumnNames(NULL
)
117 ,m_pParameterNames(NULL
)
118 ,m_pForeignColumnNames(NULL
)
120 ,m_xTableKeys(_xTableKeys
)
121 ,m_xComposer(_xComposer
)
122 ,m_sUpdateTableName(_rUpdateTableName
)
123 ,m_rRowCount(o_nRowCount
)
124 ,m_bRowCountFinal(sal_False
)
126 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::OKeySet" );
127 DBG_CTOR(OKeySet
,NULL
);
133 tryDispose(m_xStatement
);
138 DBG_DTOR(OKeySet
,NULL
);
140 void OKeySet::initColumns()
142 Reference
<XDatabaseMetaData
> xMeta
= m_xConnection
->getMetaData();
143 bool bCase
= (xMeta
.is() && xMeta
->supportsMixedCaseQuotedIdentifiers()) ? true : false;
144 m_pKeyColumnNames
.reset( new SelectColumnsMetaData(bCase
) );
145 m_pColumnNames
.reset( new SelectColumnsMetaData(bCase
) );
146 m_pParameterNames
.reset( new SelectColumnsMetaData(bCase
) );
147 m_pForeignColumnNames
.reset( new SelectColumnsMetaData(bCase
) );
150 SAL_WNODEPRECATED_DECLARATIONS_PUSH
151 void OKeySet::findTableColumnsMatching_throw( const Any
& i_aTable
,
152 const ::rtl::OUString
& i_rUpdateTableName
,
153 const Reference
<XDatabaseMetaData
>& i_xMeta
,
154 const Reference
<XNameAccess
>& i_xQueryColumns
,
155 ::std::auto_ptr
<SelectColumnsMetaData
>& o_pKeyColumnNames
)
157 // first ask the database itself for the best columns which can be used
158 Sequence
< ::rtl::OUString
> aBestColumnNames
;
159 Reference
<XNameAccess
> xKeyColumns
= getPrimaryKeyColumns_throw(i_aTable
);
160 if ( xKeyColumns
.is() )
161 aBestColumnNames
= xKeyColumns
->getElementNames();
163 const Reference
<XColumnsSupplier
> xTblColSup(i_aTable
,UNO_QUERY_THROW
);
164 const Reference
<XNameAccess
> xTblColumns
= xTblColSup
->getColumns();
165 // locate parameter in select columns
166 Reference
<XParametersSupplier
> xParaSup(m_xComposer
,UNO_QUERY
);
167 Reference
<XIndexAccess
> xQueryParameters
= xParaSup
->getParameters();
168 const sal_Int32 nParaCount
= xQueryParameters
->getCount();
169 Sequence
< ::rtl::OUString
> aParameterColumns(nParaCount
);
170 for(sal_Int32 i
= 0; i
< nParaCount
;++i
)
172 Reference
<XPropertySet
> xPara(xQueryParameters
->getByIndex(i
),UNO_QUERY_THROW
);
173 xPara
->getPropertyValue(PROPERTY_REALNAME
) >>= aParameterColumns
[i
];
176 ::rtl::OUString
sUpdateTableName( i_rUpdateTableName
);
177 if ( sUpdateTableName
.isEmpty() )
179 OSL_FAIL( "OKeySet::findTableColumnsMatching_throw: This is a fallback only - it won't work when the table has an alias name." );
180 // If i_aTable originates from a query composer, and is a table which appears with an alias in the SELECT statement,
181 // then the below code will not produce correct results.
182 // For instance, imagine a "SELECT alias.col FROM table AS alias". Now i_aTable would be the table named
183 // "table", so our sUpdateTableName would be "table" as well - not the information about the "alias" is
184 // already lost here.
185 // now getColumnPositions would travers the columns, and check which of them belong to the table denoted
186 // by sUpdateTableName. Since the latter is "table", but the columns only know that they belong to a table
187 // named "alias", there will be no matching - so getColumnPositions wouldn't find anything.
189 ::rtl::OUString sCatalog
, sSchema
, sTable
;
190 Reference
<XPropertySet
> xTableProp( i_aTable
, UNO_QUERY_THROW
);
191 xTableProp
->getPropertyValue( PROPERTY_CATALOGNAME
)>>= sCatalog
;
192 xTableProp
->getPropertyValue( PROPERTY_SCHEMANAME
) >>= sSchema
;
193 xTableProp
->getPropertyValue( PROPERTY_NAME
) >>= sTable
;
194 sUpdateTableName
= dbtools::composeTableName( i_xMeta
, sCatalog
, sSchema
, sTable
, sal_False
, ::dbtools::eInDataManipulation
);
197 ::dbaccess::getColumnPositions(i_xQueryColumns
,aBestColumnNames
,sUpdateTableName
,(*o_pKeyColumnNames
),true);
198 ::dbaccess::getColumnPositions(i_xQueryColumns
,xTblColumns
->getElementNames(),sUpdateTableName
,(*m_pColumnNames
),true);
199 ::dbaccess::getColumnPositions(i_xQueryColumns
,aParameterColumns
,sUpdateTableName
,(*m_pParameterNames
),true);
201 if ( o_pKeyColumnNames
->empty() )
203 ::dbtools::throwGenericSQLException( ::rtl::OUString( "Could not find any key column." ), *this );
206 for ( SelectColumnsMetaData::const_iterator keyColumn
= o_pKeyColumnNames
->begin();
207 keyColumn
!= o_pKeyColumnNames
->end();
211 if ( !xTblColumns
->hasByName( keyColumn
->second
.sRealName
) )
214 Reference
<XPropertySet
> xProp( xTblColumns
->getByName( keyColumn
->second
.sRealName
), UNO_QUERY
);
215 sal_Bool bAuto
= sal_False
;
216 if ( ( xProp
->getPropertyValue( PROPERTY_ISAUTOINCREMENT
) >>= bAuto
) && bAuto
)
217 m_aAutoColumns
.push_back( keyColumn
->first
);
220 SAL_WNODEPRECATED_DECLARATIONS_POP
224 void appendOneKeyColumnClause( const ::rtl::OUString
&tblName
, const ::rtl::OUString
&colName
, ::rtl::OUStringBuffer
&o_buf
)
226 static ::rtl::OUString
s_sDot(".");
227 static ::rtl::OUString
s_sParam0(" ( 1 = ? AND ");
228 static ::rtl::OUString
s_sParam1(" = ? OR 1 = ? AND ");
229 static ::rtl::OUString
s_sParam2(" IS NULL ) ");
230 o_buf
.append(s_sParam0
);
231 o_buf
.append(tblName
);
232 o_buf
.append(s_sDot
);
233 o_buf
.append(colName
);
234 o_buf
.append(s_sParam1
);
235 o_buf
.append(tblName
);
236 o_buf
.append(s_sDot
);
237 o_buf
.append(colName
);
238 o_buf
.append(s_sParam2
);
242 void OKeySet::setOneKeyColumnParameter( sal_Int32
&nPos
, const Reference
< XParameters
> &_xParameter
, const connectivity::ORowSetValue
&_rValue
, sal_Int32 _nType
, sal_Int32 _nScale
) const
244 if ( _rValue
.isNull() )
246 _xParameter
->setByte( nPos
++, 0 );
247 // We do the full call so that the right sqlType is passed to setNull
248 setParameter( nPos
++, _xParameter
, _rValue
, _nType
, _nScale
);
249 _xParameter
->setByte( nPos
++, 1 );
253 _xParameter
->setByte( nPos
++, 1 );
254 setParameter( nPos
++, _xParameter
, _rValue
, _nType
, _nScale
);
255 _xParameter
->setByte( nPos
++, 0 );
259 ::rtl::OUStringBuffer
OKeySet::createKeyFilter()
261 static ::rtl::OUString
aAnd(" AND ");
262 const ::rtl::OUString aQuote
= getIdentifierQuoteString();
263 ::rtl::OUStringBuffer aFilter
;
264 // create the where clause
265 Reference
<XDatabaseMetaData
> xMeta
= m_xConnection
->getMetaData();
266 SelectColumnsMetaData::iterator aPosEnd
= m_pKeyColumnNames
->end();
267 for(SelectColumnsMetaData::iterator aPosIter
= m_pKeyColumnNames
->begin();aPosIter
!= aPosEnd
;)
269 appendOneKeyColumnClause(::dbtools::quoteTableName( xMeta
,aPosIter
->second
.sTableName
,::dbtools::eInDataManipulation
),
270 ::dbtools::quoteName( aQuote
,aPosIter
->second
.sRealName
),
273 if(aPosIter
!= aPosEnd
)
274 aFilter
.append(aAnd
);
279 void OKeySet::construct(const Reference
< XResultSet
>& _xDriverSet
,const ::rtl::OUString
& i_sRowSetFilter
)
281 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::construct" );
282 OCacheSet::construct(_xDriverSet
,i_sRowSetFilter
);
285 Reference
<XNameAccess
> xKeyColumns
= getKeyColumns();
286 Reference
<XDatabaseMetaData
> xMeta
= m_xConnection
->getMetaData();
287 Reference
<XColumnsSupplier
> xQueryColSup(m_xComposer
,UNO_QUERY
);
288 const Reference
<XNameAccess
> xQueryColumns
= xQueryColSup
->getColumns();
289 findTableColumnsMatching_throw(makeAny(m_xTable
),m_sUpdateTableName
,xMeta
,xQueryColumns
,m_pKeyColumnNames
);
291 // the first row is empty because it's now easier for us to distinguish when we are beforefirst or first
292 // without extra variable to be set
293 OKeySetValue
keySetValue((ORowSetValueVector
*)NULL
,::std::pair
<sal_Int32
,Reference
<XRow
> >(0,(Reference
<XRow
>)NULL
));
294 m_aKeyMap
.insert(OKeySetMatrix::value_type(0, keySetValue
));
295 m_aKeyIter
= m_aKeyMap
.begin();
297 ::rtl::OUStringBuffer aFilter
= createKeyFilter();
299 Reference
< XSingleSelectQueryComposer
> xSourceComposer(m_xComposer
,UNO_QUERY
);
300 Reference
< XMultiServiceFactory
> xFactory(m_xConnection
, UNO_QUERY_THROW
);
301 Reference
<XSingleSelectQueryComposer
> xAnalyzer(xFactory
->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER
),UNO_QUERY
);
302 xAnalyzer
->setElementaryQuery(xSourceComposer
->getElementaryQuery());
303 Reference
<XTablesSupplier
> xTabSup(xAnalyzer
,uno::UNO_QUERY
);
304 Reference
<XNameAccess
> xSelectTables(xTabSup
->getTables(),uno::UNO_QUERY
);
305 const Sequence
< ::rtl::OUString
> aSeq
= xSelectTables
->getElementNames();
306 if ( aSeq
.getLength() > 1 ) // special handling for join
308 static ::rtl::OUString
aAnd(" AND ");
309 const ::rtl::OUString aQuote
= getIdentifierQuoteString();
310 const ::rtl::OUString
* pIter
= aSeq
.getConstArray();
311 const ::rtl::OUString
* pEnd
= pIter
+ aSeq
.getLength();
312 for(;pIter
!= pEnd
;++pIter
)
314 if ( *pIter
!= m_sUpdateTableName
)
316 connectivity::OSQLTable
xSelColSup(xSelectTables
->getByName(*pIter
),uno::UNO_QUERY
);
317 Reference
<XPropertySet
> xProp(xSelColSup
,uno::UNO_QUERY
);
318 ::rtl::OUString sSelectTableName
= ::dbtools::composeTableName( xMeta
, xProp
, ::dbtools::eInDataManipulation
, false, false, false );
320 ::dbaccess::getColumnPositions(xQueryColumns
,xSelColSup
->getColumns()->getElementNames(),sSelectTableName
,(*m_pForeignColumnNames
));
322 const SelectColumnsMetaData::iterator aPosEnd
= (*m_pForeignColumnNames
).end();
323 for(SelectColumnsMetaData::iterator aPosIter
= (*m_pForeignColumnNames
).begin();aPosIter
!= aPosEnd
;++aPosIter
)
325 // look for columns not in the source columns to use them as filter as well
326 if ( aFilter
.getLength() )
327 aFilter
.append(aAnd
);
328 appendOneKeyColumnClause(::dbtools::quoteName( aQuote
,sSelectTableName
),
329 ::dbtools::quoteName( aQuote
,aPosIter
->second
.sRealName
),
336 executeStatement(aFilter
,i_sRowSetFilter
,xAnalyzer
);
338 void OKeySet::executeStatement(::rtl::OUStringBuffer
& io_aFilter
,const ::rtl::OUString
& i_sRowSetFilter
,Reference
<XSingleSelectQueryComposer
>& io_xAnalyzer
)
340 bool bFilterSet
= !i_sRowSetFilter
.isEmpty();
343 FilterCreator aFilterCreator
;
344 aFilterCreator
.append( i_sRowSetFilter
);
345 aFilterCreator
.append( io_aFilter
.makeStringAndClear() );
346 io_aFilter
= aFilterCreator
.getComposedAndClear();
348 io_xAnalyzer
->setFilter(io_aFilter
.makeStringAndClear());
351 Sequence
< Sequence
< PropertyValue
> > aFilter2
= io_xAnalyzer
->getStructuredFilter();
352 const Sequence
< PropertyValue
>* pOr
= aFilter2
.getConstArray();
353 const Sequence
< PropertyValue
>* pOrEnd
= pOr
+ aFilter2
.getLength();
354 for(;pOr
!= pOrEnd
;++pOr
)
356 const PropertyValue
* pAnd
= pOr
->getConstArray();
357 const PropertyValue
* pAndEnd
= pAnd
+ pOr
->getLength();
358 for(;pAnd
!= pAndEnd
;++pAnd
)
360 ::rtl::OUString sValue
;
361 if ( !(pAnd
->Value
>>= sValue
) || !( sValue
== "?" || sValue
.matchAsciiL( ":",1,0 ) ) )
362 { // we have a criteria which has to be taken into account for updates
363 m_aFilterColumns
.push_back(pAnd
->Name
);
368 m_xStatement
= m_xConnection
->prepareStatement(io_xAnalyzer
->getQueryWithSubstitution());
369 ::comphelper::disposeComponent(io_xAnalyzer
);
372 void OKeySet::invalidateRow()
375 ::comphelper::disposeComponent(m_xSet
);
378 Any SAL_CALL
OKeySet::getBookmark() throw(SQLException
, RuntimeException
)
380 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBookmark" );
381 OSL_ENSURE(m_aKeyIter
!= m_aKeyMap
.end() && m_aKeyIter
!= m_aKeyMap
.begin(),
382 "getBookmark is only possible when we stand on a valid row!");
383 return makeAny(m_aKeyIter
->first
);
386 sal_Bool SAL_CALL
OKeySet::moveToBookmark( const Any
& bookmark
) throw(SQLException
, RuntimeException
)
388 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::moveToBookmark" );
389 m_bInserted
= m_bUpdated
= m_bDeleted
= sal_False
;
390 m_aKeyIter
= m_aKeyMap
.find(::comphelper::getINT32(bookmark
));
392 return m_aKeyIter
!= m_aKeyMap
.end();
395 sal_Bool SAL_CALL
OKeySet::moveRelativeToBookmark( const Any
& bookmark
, sal_Int32 rows
) throw(SQLException
, RuntimeException
)
397 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::moveRelativeToBookmark" );
398 m_bInserted
= m_bUpdated
= m_bDeleted
= sal_False
;
399 m_aKeyIter
= m_aKeyMap
.find(::comphelper::getINT32(bookmark
));
400 if(m_aKeyIter
!= m_aKeyMap
.end())
402 return relative(rows
);
409 sal_Int32 SAL_CALL
OKeySet::compareBookmarks( const Any
& _first
, const Any
& _second
) throw(SQLException
, RuntimeException
)
411 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::compareBookmarks" );
412 sal_Int32 nFirst
= 0, nSecond
= 0;
416 return (nFirst
!= nSecond
) ? CompareBookmark::NOT_EQUAL
: CompareBookmark::EQUAL
;
419 sal_Bool SAL_CALL
OKeySet::hasOrderedBookmarks( ) throw(SQLException
, RuntimeException
)
421 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::hasOrderedBookmarks" );
425 sal_Int32 SAL_CALL
OKeySet::hashBookmark( const Any
& bookmark
) throw(SQLException
, RuntimeException
)
427 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::hashBookmark" );
428 return ::comphelper::getINT32(bookmark
);
431 // ::com::sun::star::sdbcx::XDeleteRows
432 Sequence
< sal_Int32
> SAL_CALL
OKeySet::deleteRows( const Sequence
< Any
>& rows
,const connectivity::OSQLTable
& _xTable
) throw(SQLException
, RuntimeException
)
434 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::deleteRows" );
435 Reference
<XPropertySet
> xSet(_xTable
,UNO_QUERY
);
438 ::rtl::OUStringBuffer aSql
= ::rtl::OUString("DELETE FROM ");
439 aSql
.append(m_aComposedTableName
);
440 aSql
.append(::rtl::OUString(" WHERE "));
442 // list all columns that should be set
443 const ::rtl::OUString aQuote
= getIdentifierQuoteString();
444 static ::rtl::OUString
aAnd(" AND ");
445 static ::rtl::OUString
aOr(" OR ");
446 static ::rtl::OUString
aEqual(" = ?");
449 // use keys and indexes for exact postioning
451 Reference
<XNameAccess
> xKeyColumns
= getKeyColumns();
453 ::rtl::OUStringBuffer aCondition
= ::rtl::OUString("( ");
455 SelectColumnsMetaData::const_iterator aIter
= (*m_pKeyColumnNames
).begin();
456 SelectColumnsMetaData::const_iterator aPosEnd
= (*m_pKeyColumnNames
).end();
457 for(;aIter
!= aPosEnd
;++aIter
)
459 aCondition
.append(::dbtools::quoteName( aQuote
,aIter
->second
.sRealName
));
460 aCondition
.append(aEqual
);
461 aCondition
.append(aAnd
);
463 aCondition
.setLength(aCondition
.getLength()-5);
464 const ::rtl::OUString
sCon( aCondition
.makeStringAndClear() );
466 const Any
* pBegin
= rows
.getConstArray();
467 const Any
* pEnd
= pBegin
+ rows
.getLength();
469 Sequence
< Any
> aKeys
;
470 for(;pBegin
!= pEnd
;++pBegin
)
475 aSql
.setLength(aSql
.getLength()-3);
477 // now create end execute the prepared statement
479 Reference
< XPreparedStatement
> xPrep(m_xConnection
->prepareStatement(aSql
.makeStringAndClear()));
480 Reference
< XParameters
> xParameter(xPrep
,UNO_QUERY
);
482 pBegin
= rows
.getConstArray();
484 for(;pBegin
!= pEnd
;++pBegin
)
486 m_aKeyIter
= m_aKeyMap
.find(::comphelper::getINT32(*pBegin
));
487 if(m_aKeyIter
!= m_aKeyMap
.end())
489 connectivity::ORowVector
< ORowSetValue
>::Vector::iterator aKeyIter
= m_aKeyIter
->second
.first
->get().begin();
490 connectivity::ORowVector
< ORowSetValue
>::Vector::iterator aKeyEnd
= m_aKeyIter
->second
.first
->get().end();
491 SelectColumnsMetaData::const_iterator aPosIter
= (*m_pKeyColumnNames
).begin();
492 for(sal_uInt16 j
= 0;aKeyIter
!= aKeyEnd
;++aKeyIter
,++j
,++aPosIter
)
494 setParameter(i
++,xParameter
,*aKeyIter
,aPosIter
->second
.nType
,aPosIter
->second
.nScale
);
499 sal_Bool bOk
= xPrep
->executeUpdate() > 0;
500 Sequence
< sal_Int32
> aRet(rows
.getLength());
501 memset(aRet
.getArray(),bOk
,sizeof(sal_Int32
)*aRet
.getLength());
504 pBegin
= rows
.getConstArray();
505 pEnd
= pBegin
+ rows
.getLength();
507 for(;pBegin
!= pEnd
;++pBegin
)
511 if(m_aKeyIter
== m_aKeyMap
.find(nPos
) && m_aKeyIter
!= m_aKeyMap
.end())
513 m_aKeyMap
.erase(nPos
);
514 m_bDeleted
= sal_True
;
520 void SAL_CALL
OKeySet::updateRow(const ORowSetRow
& _rInsertRow
,const ORowSetRow
& _rOrginalRow
,const connectivity::OSQLTable
& _xTable
) throw(SQLException
, RuntimeException
)
522 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::updateRow" );
523 Reference
<XPropertySet
> xSet(_xTable
,UNO_QUERY
);
526 ::rtl::OUStringBuffer aSql
= ::rtl::OUString("UPDATE ");
527 aSql
.append(m_aComposedTableName
);
528 aSql
.append(::rtl::OUString(" SET "));
529 // list all cloumns that should be set
530 static ::rtl::OUString
aPara(" = ?,");
531 ::rtl::OUString aQuote
= getIdentifierQuoteString();
532 static ::rtl::OUString
aAnd(" AND ");
533 ::rtl::OUString
sIsNull(" IS NULL");
534 ::rtl::OUString
sParam(" = ?");
536 // use keys and indexes for excat postioning
538 Reference
<XNameAccess
> xKeyColumns
= getKeyColumns();
540 // second the indexes
541 Reference
<XIndexesSupplier
> xIndexSup(_xTable
,UNO_QUERY
);
542 Reference
<XIndexAccess
> xIndexes
;
543 if ( xIndexSup
.is() )
544 xIndexes
.set(xIndexSup
->getIndexes(),UNO_QUERY
);
547 ::std::vector
< Reference
<XNameAccess
> > aAllIndexColumns
;
548 lcl_fillIndexColumns(xIndexes
,aAllIndexColumns
);
550 ::rtl::OUString aColumnName
;
551 ::rtl::OUStringBuffer sKeyCondition
,sIndexCondition
;
552 ::std::vector
<sal_Int32
> aIndexColumnPositions
;
554 const sal_Int32 nOldLength
= aSql
.getLength();
556 // here we build the condition part for the update statement
557 SelectColumnsMetaData::const_iterator aIter
= m_pColumnNames
->begin();
558 SelectColumnsMetaData::const_iterator aEnd
= m_pColumnNames
->end();
559 for(;aIter
!= aEnd
;++aIter
,++i
)
561 if ( m_pKeyColumnNames
->find(aIter
->first
) != m_pKeyColumnNames
->end() )
563 sKeyCondition
.append(::dbtools::quoteName( aQuote
,aIter
->second
.sRealName
));
564 if((_rOrginalRow
->get())[aIter
->second
.nPosition
].isNull())
565 sKeyCondition
.append(sIsNull
);
567 sKeyCondition
.append(sParam
);
568 sKeyCondition
.append(aAnd
);
572 ::std::vector
< Reference
<XNameAccess
> >::const_iterator aIndexEnd
= aAllIndexColumns
.end();
573 for( ::std::vector
< Reference
<XNameAccess
> >::const_iterator aIndexIter
= aAllIndexColumns
.begin();
574 aIndexIter
!= aIndexEnd
;++aIndexIter
)
576 if((*aIndexIter
)->hasByName(aIter
->first
))
578 sIndexCondition
.append(::dbtools::quoteName( aQuote
,aIter
->second
.sRealName
));
579 if((_rOrginalRow
->get())[aIter
->second
.nPosition
].isNull())
580 sIndexCondition
.append(sIsNull
);
583 sIndexCondition
.append(sParam
);
584 aIndexColumnPositions
.push_back(aIter
->second
.nPosition
);
586 sIndexCondition
.append(aAnd
);
591 if((_rInsertRow
->get())[aIter
->second
.nPosition
].isModified())
593 aSql
.append(::dbtools::quoteName( aQuote
,aIter
->second
.sRealName
));
598 if( aSql
.getLength() != nOldLength
)
600 aSql
.setLength(aSql
.getLength()-1);
603 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_VALUE_CHANGED
), SQL_GENERAL_ERROR
, m_xConnection
);
605 if(sKeyCondition
.getLength() || sIndexCondition
.getLength())
607 aSql
.append(::rtl::OUString(" WHERE "));
608 if(sKeyCondition
.getLength() && sIndexCondition
.getLength())
610 aSql
.append(sKeyCondition
.makeStringAndClear());
611 aSql
.append(sIndexCondition
.makeStringAndClear());
613 else if(sKeyCondition
.getLength())
615 aSql
.append(sKeyCondition
.makeStringAndClear());
617 else if(sIndexCondition
.getLength())
619 aSql
.append(sIndexCondition
.makeStringAndClear());
621 aSql
.setLength(aSql
.getLength()-5); // remove the last AND
624 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_CONDITION_FOR_PK
), SQL_GENERAL_ERROR
, m_xConnection
);
626 // now create end execute the prepared statement
627 ::rtl::OUString sEmpty
;
628 executeUpdate(_rInsertRow
,_rOrginalRow
,aSql
.makeStringAndClear(),sEmpty
,aIndexColumnPositions
);
631 void OKeySet::executeUpdate(const ORowSetRow
& _rInsertRow
,const ORowSetRow
& _rOrginalRow
,const ::rtl::OUString
& i_sSQL
,const ::rtl::OUString
& i_sTableName
,const ::std::vector
<sal_Int32
>& _aIndexColumnPositions
)
633 // now create end execute the prepared statement
634 Reference
< XPreparedStatement
> xPrep(m_xConnection
->prepareStatement(i_sSQL
));
635 Reference
< XParameters
> xParameter(xPrep
,UNO_QUERY
);
637 bool bRefetch
= true;
638 Reference
<XRow
> xRow
;
640 // first the set values
641 SelectColumnsMetaData::const_iterator aIter
= m_pColumnNames
->begin();
642 SelectColumnsMetaData::const_iterator aEnd
= m_pColumnNames
->end();
644 for(;aIter
!= aEnd
;++aIter
,++j
)
646 if ( i_sTableName
.isEmpty() || aIter
->second
.sTableName
== i_sTableName
)
648 sal_Int32 nPos
= aIter
->second
.nPosition
;
649 if((_rInsertRow
->get())[nPos
].isModified())
653 bRefetch
= ::std::find(m_aFilterColumns
.begin(),m_aFilterColumns
.end(),aIter
->second
.sRealName
) == m_aFilterColumns
.end();
655 impl_convertValue_throw(_rInsertRow
,aIter
->second
);
656 (_rInsertRow
->get())[nPos
].setSigned((_rOrginalRow
->get())[nPos
].isSigned());
657 setParameter(i
++,xParameter
,(_rInsertRow
->get())[nPos
],aIter
->second
.nType
,aIter
->second
.nScale
);
661 // and then the values of the where condition
662 aIter
= m_pKeyColumnNames
->begin();
663 aEnd
= m_pKeyColumnNames
->end();
665 for(;aIter
!= aEnd
;++aIter
,++j
)
667 if ( i_sTableName
.isEmpty() || aIter
->second
.sTableName
== i_sTableName
)
669 setParameter(i
++,xParameter
,(_rOrginalRow
->get())[aIter
->second
.nPosition
],aIter
->second
.nType
,aIter
->second
.nScale
);
672 if ( !_aIndexColumnPositions
.empty() )
674 // now we have to set the index values
675 ::std::vector
<sal_Int32
>::const_iterator aIdxColIter
= _aIndexColumnPositions
.begin();
676 ::std::vector
<sal_Int32
>::const_iterator aIdxColEnd
= _aIndexColumnPositions
.end();
678 aIter
= m_pColumnNames
->begin();
679 for(;aIdxColIter
!= aIdxColEnd
;++aIdxColIter
,++i
,++j
,++aIter
)
681 setParameter(i
,xParameter
,(_rOrginalRow
->get())[*aIdxColIter
],(_rOrginalRow
->get())[*aIdxColIter
].getTypeKind(),aIter
->second
.nScale
);
684 const sal_Int32 nRowsUpdated
= xPrep
->executeUpdate();
685 m_bUpdated
= nRowsUpdated
> 0;
688 const sal_Int32 nBookmark
= ::comphelper::getINT32((_rInsertRow
->get())[0].getAny());
689 m_aKeyIter
= m_aKeyMap
.find(nBookmark
);
690 m_aKeyIter
->second
.second
.first
= 2;
691 m_aKeyIter
->second
.second
.second
= xRow
;
692 copyRowValue(_rInsertRow
,m_aKeyIter
->second
.first
,nBookmark
);
693 tryRefetch(_rInsertRow
,bRefetch
);
697 void SAL_CALL
OKeySet::insertRow( const ORowSetRow
& _rInsertRow
,const connectivity::OSQLTable
& _xTable
) throw(SQLException
, RuntimeException
)
699 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::insertRow" );
700 ::rtl::OUStringBuffer
aSql(::rtl::OUString("INSERT INTO "));
701 Reference
<XPropertySet
> xSet(_xTable
,UNO_QUERY
);
704 aSql
.append(m_aComposedTableName
);
705 aSql
.append(::rtl::OUString(" ( "));
706 // set values and column names
707 ::rtl::OUStringBuffer
aValues(::rtl::OUString(" VALUES ( "));
708 static ::rtl::OUString
aPara("?,");
709 ::rtl::OUString aQuote
= getIdentifierQuoteString();
710 static ::rtl::OUString
aComma(",");
712 SelectColumnsMetaData::const_iterator aIter
= m_pColumnNames
->begin();
713 SelectColumnsMetaData::const_iterator aEnd
= m_pColumnNames
->end();
715 bool bRefetch
= true;
716 sal_Bool bModified
= sal_False
;
717 for(;aIter
!= aEnd
;++aIter
,++j
)
719 if((_rInsertRow
->get())[aIter
->second
.nPosition
].isModified())
723 bRefetch
= ::std::find(m_aFilterColumns
.begin(),m_aFilterColumns
.end(),aIter
->second
.sRealName
) == m_aFilterColumns
.end();
725 aSql
.append(::dbtools::quoteName( aQuote
,aIter
->second
.sRealName
));
727 aValues
.append(aPara
);
728 bModified
= sal_True
;
732 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_VALUE_CHANGED
), SQL_GENERAL_ERROR
, m_xConnection
);
734 aSql
[aSql
.getLength() - 1] = ')';
735 aValues
[aValues
.getLength() - 1] = ')';
736 aSql
.append(aValues
.makeStringAndClear());
737 // now create,fill and execute the prepared statement
738 ::rtl::OUString sEmpty
;
739 executeInsert(_rInsertRow
,aSql
.makeStringAndClear(),sEmpty
,bRefetch
);
742 void OKeySet::executeInsert( const ORowSetRow
& _rInsertRow
,const ::rtl::OUString
& i_sSQL
,const ::rtl::OUString
& i_sTableName
,bool bRefetch
)
744 // now create,fill and execute the prepared statement
745 Reference
< XPreparedStatement
> xPrep(m_xConnection
->prepareStatement(i_sSQL
));
746 Reference
< XParameters
> xParameter(xPrep
,UNO_QUERY
);
748 SelectColumnsMetaData::const_iterator aIter
= m_pColumnNames
->begin();
749 SelectColumnsMetaData::const_iterator aEnd
= m_pColumnNames
->end();
750 for(sal_Int32 i
= 1;aIter
!= aEnd
;++aIter
)
752 if ( i_sTableName
.isEmpty() || aIter
->second
.sTableName
== i_sTableName
)
754 const sal_Int32 nPos
= aIter
->second
.nPosition
;
755 if((_rInsertRow
->get())[nPos
].isModified())
757 if((_rInsertRow
->get())[nPos
].isNull())
758 xParameter
->setNull(i
++,(_rInsertRow
->get())[nPos
].getTypeKind());
761 impl_convertValue_throw(_rInsertRow
,aIter
->second
);
762 (_rInsertRow
->get())[nPos
].setSigned(m_aSignedFlags
[nPos
-1]);
763 setParameter(i
++,xParameter
,(_rInsertRow
->get())[nPos
],aIter
->second
.nType
,aIter
->second
.nScale
);
769 m_bInserted
= xPrep
->executeUpdate() > 0;
770 sal_Bool bAutoValuesFetched
= sal_False
;
773 // first insert the default values into the insertrow
774 aIter
= m_pColumnNames
->begin();
775 for(;aIter
!= aEnd
;++aIter
)
777 if ( !(_rInsertRow
->get())[aIter
->second
.nPosition
].isModified() )
778 (_rInsertRow
->get())[aIter
->second
.nPosition
] = aIter
->second
.sDefaultValue
;
782 Reference
< XGeneratedResultSet
> xGRes(xPrep
, UNO_QUERY
);
785 Reference
< XResultSet
> xRes
= xGRes
->getGeneratedValues();
786 Reference
< XRow
> xRow(xRes
,UNO_QUERY
);
787 if ( xRow
.is() && xRes
->next() )
789 Reference
< XResultSetMetaDataSupplier
> xMdSup(xRes
,UNO_QUERY
);
790 Reference
< XResultSetMetaData
> xMd
= xMdSup
->getMetaData();
791 sal_Int32 nColumnCount
= xMd
->getColumnCount();
792 ::std::vector
< ::rtl::OUString
>::iterator aAutoIter
= m_aAutoColumns
.begin();
793 ::std::vector
< ::rtl::OUString
>::iterator aAutoEnd
= m_aAutoColumns
.end();
794 for (sal_Int32 i
= 1;aAutoIter
!= aAutoEnd
&& i
<= nColumnCount
; ++aAutoIter
,++i
)
796 #if OSL_DEBUG_LEVEL > 1
797 ::rtl::OUString
sColumnName( xMd
->getColumnName(i
) );
799 SelectColumnsMetaData::iterator aFind
= m_pKeyColumnNames
->find(*aAutoIter
);
800 if ( aFind
!= m_pKeyColumnNames
->end() )
801 (_rInsertRow
->get())[aFind
->second
.nPosition
].fill(i
, aFind
->second
.nType
, xRow
);
803 bAutoValuesFetched
= sal_True
;
807 catch(const Exception
&)
809 OSL_FAIL("Could not execute GeneratedKeys() stmt");
813 ::comphelper::disposeComponent(xPrep
);
815 if ( i_sTableName
.isEmpty() && !bAutoValuesFetched
&& m_bInserted
)
817 // first check if all key column values were set
818 const ::rtl::OUString
sMax(" MAX(");
819 const ::rtl::OUString
sMaxEnd("),");
820 const ::rtl::OUString sQuote
= getIdentifierQuoteString();
821 ::rtl::OUString sMaxStmt
;
822 aEnd
= m_pKeyColumnNames
->end();
823 ::std::vector
< ::rtl::OUString
>::iterator aAutoIter
= m_aAutoColumns
.begin();
824 ::std::vector
< ::rtl::OUString
>::iterator aAutoEnd
= m_aAutoColumns
.end();
825 for (;aAutoIter
!= aAutoEnd
; ++aAutoIter
)
827 // we will only fetch values which are keycolumns
828 SelectColumnsMetaData::iterator aFind
= m_pKeyColumnNames
->find(*aAutoIter
);
832 sMaxStmt
+= ::dbtools::quoteName( sQuote
,aFind
->second
.sRealName
838 if(!sMaxStmt
.isEmpty())
840 sMaxStmt
= sMaxStmt
.replaceAt(sMaxStmt
.getLength()-1,1,::rtl::OUString(" "));
841 ::rtl::OUString sStmt
= ::rtl::OUString("SELECT ");
843 sStmt
+= ::rtl::OUString("FROM ");
844 ::rtl::OUString sCatalog
,sSchema
,sTable
;
845 ::dbtools::qualifiedNameComponents(m_xConnection
->getMetaData(),m_sUpdateTableName
,sCatalog
,sSchema
,sTable
,::dbtools::eInDataManipulation
);
846 sStmt
+= ::dbtools::composeTableNameForSelect( m_xConnection
, sCatalog
, sSchema
, sTable
);
849 // now fetch the autoincrement values
850 Reference
<XStatement
> xStatement
= m_xConnection
->createStatement();
851 Reference
<XResultSet
> xRes
= xStatement
->executeQuery(sStmt
);
852 Reference
<XRow
> xRow(xRes
,UNO_QUERY
);
853 if(xRow
.is() && xRes
->next())
855 aAutoIter
= m_aAutoColumns
.begin();
856 for (sal_Int32 i
=1;aAutoIter
!= aAutoEnd
; ++aAutoIter
,++i
)
858 // we will only fetch values which are keycolumns
859 SelectColumnsMetaData::iterator aFind
= m_pKeyColumnNames
->find(*aAutoIter
);
861 (_rInsertRow
->get())[aFind
->second
.nPosition
].fill(i
, aFind
->second
.nType
, xRow
);
864 ::comphelper::disposeComponent(xStatement
);
868 OSL_FAIL("Could not fetch with MAX() ");
874 OKeySetMatrix::iterator aKeyIter
= m_aKeyMap
.end();
876 ORowSetRow aKeyRow
= new connectivity::ORowVector
< ORowSetValue
>(m_pKeyColumnNames
->size());
877 copyRowValue(_rInsertRow
,aKeyRow
,aKeyIter
->first
+ 1);
879 m_aKeyIter
= m_aKeyMap
.insert(OKeySetMatrix::value_type(aKeyIter
->first
+ 1,OKeySetValue(aKeyRow
,::std::pair
<sal_Int32
,Reference
<XRow
> >(1,(Reference
<XRow
>)NULL
)))).first
;
880 // now we set the bookmark for this row
881 (_rInsertRow
->get())[0] = makeAny((sal_Int32
)m_aKeyIter
->first
);
882 tryRefetch(_rInsertRow
,bRefetch
);
885 void OKeySet::tryRefetch(const ORowSetRow
& _rInsertRow
,bool bRefetch
)
891 bRefetch
= doTryRefetch_throw();
893 catch(const Exception
&)
900 m_aKeyIter
->second
.second
.second
= new OPrivateRow(_rInsertRow
->get());
904 void OKeySet::copyRowValue(const ORowSetRow
& _rInsertRow
,ORowSetRow
& _rKeyRow
,sal_Int32 i_nBookmark
)
906 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::copyRowValue" );
907 connectivity::ORowVector
< ORowSetValue
>::Vector::iterator aIter
= _rKeyRow
->get().begin();
909 // check the if the parameter values have been changed
910 OSL_ENSURE((m_aParameterValueForCache
.get().size()-1) == m_pParameterNames
->size(),"OKeySet::copyRowValue: Parameter values and names differ!");
911 connectivity::ORowVector
< ORowSetValue
>::Vector::const_iterator aParaValuesIter
= m_aParameterValueForCache
.get().begin() +1;
913 bool bChanged
= false;
914 SelectColumnsMetaData::const_iterator aParaIter
= (*m_pParameterNames
).begin();
915 SelectColumnsMetaData::const_iterator aParaEnd
= (*m_pParameterNames
).end();
916 for(sal_Int32 i
= 1;aParaIter
!= aParaEnd
;++aParaIter
,++aParaValuesIter
,++i
)
918 ORowSetValue
aValue(*aParaValuesIter
);
919 aValue
.setSigned(m_aSignedFlags
[aParaIter
->second
.nPosition
]);
920 if ( (_rInsertRow
->get())[aParaIter
->second
.nPosition
] != aValue
)
922 ORowSetValueVector
aCopy(m_aParameterValueForCache
);
923 (aCopy
.get())[i
] = (_rInsertRow
->get())[aParaIter
->second
.nPosition
];
924 m_aUpdatedParameter
[i_nBookmark
] = aCopy
;
930 m_aUpdatedParameter
.erase(i_nBookmark
);
933 // update the key values
934 SelectColumnsMetaData::const_iterator aPosIter
= (*m_pKeyColumnNames
).begin();
935 SelectColumnsMetaData::const_iterator aPosEnd
= (*m_pKeyColumnNames
).end();
936 for(;aPosIter
!= aPosEnd
;++aPosIter
,++aIter
)
938 impl_convertValue_throw(_rInsertRow
,aPosIter
->second
);
939 *aIter
= (_rInsertRow
->get())[aPosIter
->second
.nPosition
];
940 aIter
->setTypeKind(aPosIter
->second
.nType
);
944 void SAL_CALL
OKeySet::deleteRow(const ORowSetRow
& _rDeleteRow
,const connectivity::OSQLTable
& _xTable
) throw(SQLException
, RuntimeException
)
946 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::deleteRow" );
947 Reference
<XPropertySet
> xSet(_xTable
,UNO_QUERY
);
950 ::rtl::OUStringBuffer aSql
= ::rtl::OUString("DELETE FROM ");
951 aSql
.append(m_aComposedTableName
);
952 aSql
.append(::rtl::OUString(" WHERE "));
954 // list all cloumns that should be set
955 ::rtl::OUString aQuote
= getIdentifierQuoteString();
956 static ::rtl::OUString
aAnd(" AND ");
958 // use keys and indexes for excat postioning
959 Reference
<XNameAccess
> xKeyColumns
= getKeyColumns();
960 // second the indexes
961 Reference
<XIndexesSupplier
> xIndexSup(_xTable
,UNO_QUERY
);
962 Reference
<XIndexAccess
> xIndexes
;
963 if ( xIndexSup
.is() )
964 xIndexes
.set(xIndexSup
->getIndexes(),UNO_QUERY
);
966 // Reference<XColumnsSupplier>
967 ::std::vector
< Reference
<XNameAccess
> > aAllIndexColumns
;
968 lcl_fillIndexColumns(xIndexes
,aAllIndexColumns
);
970 ::rtl::OUString aColumnName
;
971 ::rtl::OUStringBuffer sIndexCondition
;
972 ::std::vector
<sal_Int32
> aIndexColumnPositions
;
973 SelectColumnsMetaData::const_iterator aIter
= m_pColumnNames
->begin();
974 SelectColumnsMetaData::const_iterator aEnd
= m_pColumnNames
->end();
977 for(i
= 1;aIter
!= aEnd
;++aIter
,++i
)
979 if ( m_pKeyColumnNames
->find(aIter
->first
) != m_pKeyColumnNames
->end() )
981 aSql
.append(::dbtools::quoteName( aQuote
,aIter
->second
.sRealName
));
982 if((_rDeleteRow
->get())[aIter
->second
.nPosition
].isNull())
984 OSL_FAIL("can a primary key be null");
985 aSql
.append(::rtl::OUString(" IS NULL"));
988 aSql
.append(::rtl::OUString(" = ?"));
993 ::std::vector
< Reference
<XNameAccess
> >::const_iterator aIndexEnd
= aAllIndexColumns
.end();
994 for( ::std::vector
< Reference
<XNameAccess
> >::const_iterator aIndexIter
= aAllIndexColumns
.begin();
995 aIndexIter
!= aIndexEnd
;++aIndexIter
)
997 if((*aIndexIter
)->hasByName(aIter
->first
))
999 sIndexCondition
.append(::dbtools::quoteName( aQuote
,aIter
->second
.sRealName
));
1000 if((_rDeleteRow
->get())[aIter
->second
.nPosition
].isNull())
1001 sIndexCondition
.append(::rtl::OUString(" IS NULL"));
1004 sIndexCondition
.append(::rtl::OUString(" = ?"));
1005 aIndexColumnPositions
.push_back(aIter
->second
.nPosition
);
1007 sIndexCondition
.append(aAnd
);
1014 aSql
.append(sIndexCondition
.makeStringAndClear());
1015 aSql
.setLength(aSql
.getLength()-5);
1017 // now create end execute the prepared statement
1018 Reference
< XPreparedStatement
> xPrep(m_xConnection
->prepareStatement(aSql
.makeStringAndClear()));
1019 Reference
< XParameters
> xParameter(xPrep
,UNO_QUERY
);
1021 aIter
= (*m_pKeyColumnNames
).begin();
1022 aEnd
= (*m_pKeyColumnNames
).end();
1024 for(;aIter
!= aEnd
;++aIter
,++i
)
1026 setParameter(i
,xParameter
,(_rDeleteRow
->get())[aIter
->second
.nPosition
],aIter
->second
.nType
,aIter
->second
.nScale
);
1029 // now we have to set the index values
1030 ::std::vector
<sal_Int32
>::iterator aIdxColIter
= aIndexColumnPositions
.begin();
1031 ::std::vector
<sal_Int32
>::iterator aIdxColEnd
= aIndexColumnPositions
.end();
1032 aIter
= m_pColumnNames
->begin();
1033 for(;aIdxColIter
!= aIdxColEnd
;++aIdxColIter
,++i
,++aIter
)
1035 setParameter(i
,xParameter
,(_rDeleteRow
->get())[*aIdxColIter
],(_rDeleteRow
->get())[*aIdxColIter
].getTypeKind(),aIter
->second
.nScale
);
1038 m_bDeleted
= xPrep
->executeUpdate() > 0;
1042 sal_Int32 nBookmark
= ::comphelper::getINT32((_rDeleteRow
->get())[0].getAny());
1043 if(m_aKeyIter
== m_aKeyMap
.find(nBookmark
) && m_aKeyIter
!= m_aKeyMap
.end())
1045 m_aKeyMap
.erase(nBookmark
);
1046 m_bDeleted
= sal_True
;
1050 void SAL_CALL
OKeySet::cancelRowUpdates( ) throw(SQLException
, RuntimeException
)
1052 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::cancelRowUpdates" );
1053 m_bInserted
= m_bUpdated
= m_bDeleted
= sal_False
;
1056 void SAL_CALL
OKeySet::moveToInsertRow( ) throw(SQLException
, RuntimeException
)
1058 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::moveToInsertRow" );
1061 void SAL_CALL
OKeySet::moveToCurrentRow( ) throw(SQLException
, RuntimeException
)
1063 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::moveToCurrentRow" );
1066 Reference
<XNameAccess
> OKeySet::getKeyColumns() const
1068 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getKeyColumns" );
1069 // use keys and indexes for excat postioning
1072 Reference
<XIndexAccess
> xKeys
= m_xTableKeys
;
1075 Reference
<XPropertySet
> xSet(m_xTable
,UNO_QUERY
);
1076 const Reference
<XNameAccess
> xPrimaryKeyColumns
= getPrimaryKeyColumns_throw(xSet
);
1077 return xPrimaryKeyColumns
;
1080 Reference
<XColumnsSupplier
> xKeyColsSup
;
1081 Reference
<XNameAccess
> xKeyColumns
;
1084 Reference
<XPropertySet
> xProp
;
1085 sal_Int32 nCount
= xKeys
->getCount();
1086 for(sal_Int32 i
= 0;i
< nCount
;++i
)
1088 xProp
.set(xKeys
->getByIndex(i
),UNO_QUERY
);
1091 sal_Int32 nKeyType
= 0;
1092 xProp
->getPropertyValue(PROPERTY_TYPE
) >>= nKeyType
;
1093 if(KeyType::PRIMARY
== nKeyType
)
1095 xKeyColsSup
.set(xProp
,UNO_QUERY
);
1096 OSL_ENSURE(xKeyColsSup
.is(),"Columnsupplier is null!");
1097 xKeyColumns
= xKeyColsSup
->getColumns();
1107 sal_Bool SAL_CALL
OKeySet::next( ) throw(SQLException
, RuntimeException
)
1109 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::next" );
1110 m_bInserted
= m_bUpdated
= m_bDeleted
= sal_False
;
1115 if(!m_bRowCountFinal
&& m_aKeyIter
== m_aKeyMap
.end())
1117 // not yet all records fetched, but we reached the end of those we fetched
1118 // try to fetch one more row
1121 OSL_ENSURE(!isAfterLast(), "fetchRow succeeded, but isAfterLast()");
1126 // nope, we arrived at end of data
1127 m_aKeyIter
= m_aKeyMap
.end();
1128 OSL_ENSURE(isAfterLast(), "fetchRow failed, but not end of data");
1133 return !isAfterLast();
1136 sal_Bool SAL_CALL
OKeySet::isBeforeFirst( ) throw(SQLException
, RuntimeException
)
1138 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isBeforeFirst" );
1139 return m_aKeyIter
== m_aKeyMap
.begin();
1142 sal_Bool SAL_CALL
OKeySet::isAfterLast( ) throw(SQLException
, RuntimeException
)
1144 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isAfterLast" );
1145 return m_bRowCountFinal
&& m_aKeyIter
== m_aKeyMap
.end();
1148 sal_Bool SAL_CALL
OKeySet::isFirst( ) throw(SQLException
, RuntimeException
)
1150 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isFirst" );
1151 OKeySetMatrix::iterator aTemp
= m_aKeyMap
.begin();
1153 return m_aKeyIter
== aTemp
&& m_aKeyIter
!= m_aKeyMap
.end();
1156 sal_Bool SAL_CALL
OKeySet::isLast( ) throw(SQLException
, RuntimeException
)
1158 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isLast" );
1159 if(!m_bRowCountFinal
)
1162 OKeySetMatrix::iterator aTemp
= m_aKeyMap
.end();
1164 return m_aKeyIter
== aTemp
;
1167 void SAL_CALL
OKeySet::beforeFirst( ) throw(SQLException
, RuntimeException
)
1169 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::beforeFirst" );
1170 m_bInserted
= m_bUpdated
= m_bDeleted
= sal_False
;
1171 m_aKeyIter
= m_aKeyMap
.begin();
1175 void SAL_CALL
OKeySet::afterLast( ) throw(SQLException
, RuntimeException
)
1177 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::afterLast" );
1178 m_bInserted
= m_bUpdated
= m_bDeleted
= sal_False
;
1180 m_aKeyIter
= m_aKeyMap
.end();
1184 sal_Bool SAL_CALL
OKeySet::first( ) throw(SQLException
, RuntimeException
)
1186 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::first" );
1187 m_bInserted
= m_bUpdated
= m_bDeleted
= sal_False
;
1188 m_aKeyIter
= m_aKeyMap
.begin();
1190 if(m_aKeyIter
== m_aKeyMap
.end())
1194 m_aKeyIter
= m_aKeyMap
.end();
1200 return m_aKeyIter
!= m_aKeyMap
.end() && m_aKeyIter
!= m_aKeyMap
.begin();
1203 sal_Bool SAL_CALL
OKeySet::last( ) throw(SQLException
, RuntimeException
)
1205 return last_checked(sal_True
);
1208 sal_Bool
OKeySet::last_checked( sal_Bool
/* i_bFetchRow */ )
1210 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::last_checked" );
1211 m_bInserted
= m_bUpdated
= m_bDeleted
= sal_False
;
1212 bool fetchedRow
= fillAllRows();
1214 m_aKeyIter
= m_aKeyMap
.end();
1220 return m_aKeyIter
!= m_aKeyMap
.end() && m_aKeyIter
!= m_aKeyMap
.begin();
1223 sal_Int32 SAL_CALL
OKeySet::getRow( ) throw(SQLException
, RuntimeException
)
1225 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getRow" );
1226 OSL_ENSURE(!isAfterLast(),"getRow is not allowed when afterlast record!");
1227 OSL_ENSURE(!isBeforeFirst(),"getRow is not allowed when beforefirst record!");
1229 return ::std::distance(m_aKeyMap
.begin(),m_aKeyIter
);
1232 sal_Bool SAL_CALL
OKeySet::absolute( sal_Int32 row
) throw(SQLException
, RuntimeException
)
1234 return absolute_checked(row
,sal_True
);
1236 sal_Bool
OKeySet::absolute_checked( sal_Int32 row
, sal_Bool
/* i_bFetchRow */ )
1238 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::absolute" );
1239 m_bInserted
= m_bUpdated
= m_bDeleted
= sal_False
;
1240 OSL_ENSURE(row
,"absolute(0) isn't allowed!");
1241 bool fetchedRow
= false;
1244 if(!m_bRowCountFinal
)
1245 fetchedRow
= fillAllRows();
1247 for(;row
< 0 && m_aKeyIter
!= m_aKeyMap
.begin();++row
)
1252 if(row
>= (sal_Int32
)m_aKeyMap
.size())
1254 // we don't have this row
1255 if(!m_bRowCountFinal
)
1257 // but there may still be rows to fetch.
1258 sal_Bool bNext
= sal_True
;
1259 for(sal_Int32 i
=m_aKeyMap
.size()-1;i
< row
&& bNext
;++i
)
1261 // it is guaranteed that the above loop has executed at least once,
1262 // that is fetchRow called at least once.
1269 // reached end of data before desired row
1270 m_aKeyIter
= m_aKeyMap
.end();
1276 // no more rows to fetch -> fail
1277 m_aKeyIter
= m_aKeyMap
.end();
1283 m_aKeyIter
= m_aKeyMap
.begin();
1284 for(;row
> 0 && m_aKeyIter
!= m_aKeyMap
.end();--row
)
1293 return m_aKeyIter
!= m_aKeyMap
.end() && m_aKeyIter
!= m_aKeyMap
.begin();
1296 sal_Bool SAL_CALL
OKeySet::relative( sal_Int32 rows
) throw(SQLException
, RuntimeException
)
1298 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::relative" );
1304 return absolute(getRow()+rows
);
1307 sal_Bool
OKeySet::previous_checked( sal_Bool
/* i_bFetchRow */ )
1309 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::previous" );
1310 m_bInserted
= m_bUpdated
= m_bDeleted
= sal_False
;
1311 if(m_aKeyIter
!= m_aKeyMap
.begin())
1316 return m_aKeyIter
!= m_aKeyMap
.begin();
1318 sal_Bool SAL_CALL
OKeySet::previous( ) throw(SQLException
, RuntimeException
)
1320 return previous_checked(sal_True
);
1323 bool OKeySet::doTryRefetch_throw() throw(SQLException
, RuntimeException
)
1325 // we just reassign the base members
1326 Reference
< XParameters
> xParameter(m_xStatement
,UNO_QUERY
);
1327 OSL_ENSURE(xParameter
.is(),"No Parameter interface!");
1328 xParameter
->clearParameters();
1331 connectivity::ORowVector
< ORowSetValue
>::Vector::const_iterator aParaIter
;
1332 connectivity::ORowVector
< ORowSetValue
>::Vector::const_iterator aParaEnd
;
1333 OUpdatedParameter::iterator aUpdateFind
= m_aUpdatedParameter
.find(m_aKeyIter
->first
);
1334 if ( aUpdateFind
== m_aUpdatedParameter
.end() )
1336 aParaIter
= m_aParameterValueForCache
.get().begin();
1337 aParaEnd
= m_aParameterValueForCache
.get().end();
1341 aParaIter
= aUpdateFind
->second
.get().begin();
1342 aParaEnd
= aUpdateFind
->second
.get().end();
1345 for(++aParaIter
;aParaIter
!= aParaEnd
;++aParaIter
,++nPos
)
1347 ::dbtools::setObjectWithInfo( xParameter
, nPos
, aParaIter
->makeAny(), aParaIter
->getTypeKind() );
1350 // now set the primary key column values
1351 connectivity::ORowVector
< ORowSetValue
>::Vector::const_iterator aIter
= m_aKeyIter
->second
.first
->get().begin();
1352 SelectColumnsMetaData::const_iterator aPosIter
= (*m_pKeyColumnNames
).begin();
1353 SelectColumnsMetaData::const_iterator aPosEnd
= (*m_pKeyColumnNames
).end();
1354 for(;aPosIter
!= aPosEnd
;++aPosIter
,++aIter
)
1355 setOneKeyColumnParameter(nPos
,xParameter
,*aIter
,aPosIter
->second
.nType
,aPosIter
->second
.nScale
);
1356 aPosIter
= (*m_pForeignColumnNames
).begin();
1357 aPosEnd
= (*m_pForeignColumnNames
).end();
1358 for(;aPosIter
!= aPosEnd
;++aPosIter
,++aIter
)
1359 setOneKeyColumnParameter(nPos
,xParameter
,*aIter
,aPosIter
->second
.nType
,aPosIter
->second
.nScale
);
1361 m_xSet
= m_xStatement
->executeQuery();
1362 OSL_ENSURE(m_xSet
.is(),"No resultset from statement!");
1363 return m_xSet
->next();
1366 // -----------------------------------------------------------------------------
1367 void SAL_CALL
OKeySet::refreshRow() throw(SQLException
, RuntimeException
)
1369 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::refreshRow" );
1373 if(isBeforeFirst() || isAfterLast() || !m_xStatement
.is())
1376 if ( m_aKeyIter
->second
.second
.second
.is() )
1378 m_xRow
= m_aKeyIter
->second
.second
.second
;
1382 sal_Bool bOK
= doTryRefetch_throw();
1385 // This row has disappeared; remove it.
1386 OKeySetMatrix::iterator aTemp
= m_aKeyIter
;
1389 m_aKeyMap
.erase(aTemp
);
1391 // adjust RowCount for the row we have removed
1392 if (m_rRowCount
> 0)
1395 OSL_FAIL("m_rRowCount got out of sync: non-empty m_aKeyMap, but m_rRowCount <= 0");
1397 if (m_aKeyIter
== m_aKeyMap
.end())
1399 ::comphelper::disposeComponent(m_xSet
);
1402 // it was the last fetched row,
1403 // but there may be another one to fetch
1406 // nope, that really was the last
1407 m_aKeyIter
= m_aKeyMap
.end();
1408 OSL_ENSURE(isAfterLast(), "fetchRow() failed but not isAfterLast()!");
1411 // Now, either fetchRow has set m_xRow or isAfterLast()
1420 m_xRow
.set(m_xSet
,UNO_QUERY
);
1421 OSL_ENSURE(m_xRow
.is(),"No row from statement!");
1425 sal_Bool
OKeySet::fetchRow()
1427 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::fetchRow" );
1428 // fetch the next row and append on the keyset
1429 sal_Bool bRet
= sal_False
;
1430 if ( !m_bRowCountFinal
&& (!m_nMaxRows
|| sal_Int32(m_aKeyMap
.size()) < m_nMaxRows
) )
1431 bRet
= m_xDriverSet
->next();
1434 ORowSetRow aKeyRow
= new connectivity::ORowVector
< ORowSetValue
>((*m_pKeyColumnNames
).size() + m_pForeignColumnNames
->size());
1436 ::comphelper::disposeComponent(m_xSet
);
1437 m_xRow
.set(m_xDriverRow
, UNO_QUERY_THROW
);
1439 connectivity::ORowVector
< ORowSetValue
>::Vector::iterator aIter
= aKeyRow
->get().begin();
1441 SelectColumnsMetaData::const_iterator aPosIter
= (*m_pKeyColumnNames
).begin();
1442 SelectColumnsMetaData::const_iterator aPosEnd
= (*m_pKeyColumnNames
).end();
1443 for(;aPosIter
!= aPosEnd
;++aPosIter
,++aIter
)
1445 const SelectColumnDescription
& rColDesc
= aPosIter
->second
;
1446 aIter
->fill(rColDesc
.nPosition
, rColDesc
.nType
, m_xRow
);
1448 // copy missing columns from other tables
1449 aPosIter
= (*m_pForeignColumnNames
).begin();
1450 aPosEnd
= (*m_pForeignColumnNames
).end();
1451 for(;aPosIter
!= aPosEnd
;++aPosIter
,++aIter
)
1453 const SelectColumnDescription
& rColDesc
= aPosIter
->second
;
1454 aIter
->fill(rColDesc
.nPosition
, rColDesc
.nType
, m_xRow
);
1456 m_aKeyIter
= m_aKeyMap
.insert(OKeySetMatrix::value_type(m_aKeyMap
.rbegin()->first
+1,OKeySetValue(aKeyRow
,::std::pair
<sal_Int32
,Reference
<XRow
> >(0,(Reference
<XRow
>)NULL
)))).first
;
1459 m_bRowCountFinal
= sal_True
;
1463 bool OKeySet::fillAllRows()
1465 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::fillAllRows" );
1466 if(m_bRowCountFinal
)
1478 sal_Bool SAL_CALL
OKeySet::wasNull( ) throw(SQLException
, RuntimeException
)
1480 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::wasNull" );
1481 if ( ! m_xRow
.is() )
1482 throwGenericSQLException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Must call getFOO() for some FOO before wasNull()")), *this);
1484 OSL_ENSURE(m_xRow
.is(),"m_xRow is null! I've thrown, but function execution continued?");
1485 return m_xRow
->wasNull();
1488 inline void OKeySet::ensureRowForData( ) throw(SQLException
, RuntimeException
)
1493 throwSQLException("Failed to refetch row", "02000", *this, -2);
1495 OSL_ENSURE(m_xRow
.is(),"m_xRow is null! I've called throwSQLException but execution continued?");
1498 ::rtl::OUString SAL_CALL
OKeySet::getString( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1500 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getString" );
1502 return m_xRow
->getString(columnIndex
);
1505 sal_Bool SAL_CALL
OKeySet::getBoolean( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1507 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBoolean" );
1509 return m_xRow
->getBoolean(columnIndex
);
1512 sal_Int8 SAL_CALL
OKeySet::getByte( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1514 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getByte" );
1516 return m_xRow
->getByte(columnIndex
);
1519 sal_Int16 SAL_CALL
OKeySet::getShort( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1521 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getShort" );
1523 return m_xRow
->getShort(columnIndex
);
1526 sal_Int32 SAL_CALL
OKeySet::getInt( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1528 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getInt" );
1530 return m_xRow
->getInt(columnIndex
);
1533 sal_Int64 SAL_CALL
OKeySet::getLong( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1535 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getLong" );
1537 return m_xRow
->getLong(columnIndex
);
1540 float SAL_CALL
OKeySet::getFloat( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1542 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getFloat" );
1544 return m_xRow
->getFloat(columnIndex
);
1547 double SAL_CALL
OKeySet::getDouble( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1549 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getDouble" );
1551 return m_xRow
->getDouble(columnIndex
);
1554 Sequence
< sal_Int8
> SAL_CALL
OKeySet::getBytes( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1556 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBytes" );
1558 return m_xRow
->getBytes(columnIndex
);
1561 ::com::sun::star::util::Date SAL_CALL
OKeySet::getDate( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1563 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getDate" );
1565 return m_xRow
->getDate(columnIndex
);
1568 ::com::sun::star::util::Time SAL_CALL
OKeySet::getTime( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1570 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getTime" );
1572 return m_xRow
->getTime(columnIndex
);
1575 ::com::sun::star::util::DateTime SAL_CALL
OKeySet::getTimestamp( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1577 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getTimestamp" );
1579 return m_xRow
->getTimestamp(columnIndex
);
1582 Reference
< ::com::sun::star::io::XInputStream
> SAL_CALL
OKeySet::getBinaryStream( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1584 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBinaryStream" );
1586 return m_xRow
->getBinaryStream(columnIndex
);
1589 Reference
< ::com::sun::star::io::XInputStream
> SAL_CALL
OKeySet::getCharacterStream( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1591 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getCharacterStream" );
1593 return m_xRow
->getCharacterStream(columnIndex
);
1596 Any SAL_CALL
OKeySet::getObject( sal_Int32 columnIndex
, const Reference
< ::com::sun::star::container::XNameAccess
>& typeMap
) throw(SQLException
, RuntimeException
)
1598 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getObject" );
1600 return m_xRow
->getObject(columnIndex
,typeMap
);
1603 Reference
< XRef
> SAL_CALL
OKeySet::getRef( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1605 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getRef" );
1607 return m_xRow
->getRef(columnIndex
);
1610 Reference
< XBlob
> SAL_CALL
OKeySet::getBlob( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1612 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBlob" );
1614 return m_xRow
->getBlob(columnIndex
);
1617 Reference
< XClob
> SAL_CALL
OKeySet::getClob( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1619 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getClob" );
1621 return m_xRow
->getClob(columnIndex
);
1624 Reference
< XArray
> SAL_CALL
OKeySet::getArray( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
)
1626 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getArray" );
1628 return m_xRow
->getArray(columnIndex
);
1631 sal_Bool SAL_CALL
OKeySet::rowUpdated( ) throw(SQLException
, RuntimeException
)
1633 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::rowUpdated" );
1634 return m_aKeyIter
!= m_aKeyMap
.begin() && m_aKeyIter
!= m_aKeyMap
.end() && m_aKeyIter
->second
.second
.first
== 2;
1637 sal_Bool SAL_CALL
OKeySet::rowInserted( ) throw(SQLException
, RuntimeException
)
1639 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::rowInserted" );
1640 return m_aKeyIter
!= m_aKeyMap
.begin() && m_aKeyIter
!= m_aKeyMap
.end() && m_aKeyIter
->second
.second
.first
== 1;
1643 sal_Bool SAL_CALL
OKeySet::rowDeleted( ) throw(SQLException
, RuntimeException
)
1645 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::rowDeleted" );
1646 sal_Bool bDeleted
= m_bDeleted
;
1647 m_bDeleted
= sal_False
;
1654 void getColumnPositions(const Reference
<XNameAccess
>& _rxQueryColumns
,
1655 const ::com::sun::star::uno::Sequence
< ::rtl::OUString
>& _aColumnNames
,
1656 const ::rtl::OUString
& _rsUpdateTableName
,
1657 SelectColumnsMetaData
& o_rColumnNames
,
1658 bool i_bAppendTableName
)
1660 // get the real name of the columns
1661 Sequence
< ::rtl::OUString
> aSelNames(_rxQueryColumns
->getElementNames());
1662 const ::rtl::OUString
* pSelIter
= aSelNames
.getConstArray();
1663 const ::rtl::OUString
* pSelEnd
= pSelIter
+ aSelNames
.getLength();
1665 const ::rtl::OUString
* pTblColumnIter
= _aColumnNames
.getConstArray();
1666 const ::rtl::OUString
* pTblColumnEnd
= pTblColumnIter
+ _aColumnNames
.getLength();
1669 ::comphelper::UStringMixLess
aTmp(o_rColumnNames
.key_comp());
1670 ::comphelper::UStringMixEqual
bCase(static_cast< ::comphelper::UStringMixLess
*>(&aTmp
)->isCaseSensitive());
1672 for(sal_Int32 nPos
= 1;pSelIter
!= pSelEnd
;++pSelIter
,++nPos
)
1674 Reference
<XPropertySet
> xQueryColumnProp(_rxQueryColumns
->getByName(*pSelIter
),UNO_QUERY_THROW
);
1675 ::rtl::OUString sRealName
,sTableName
;
1676 OSL_ENSURE(xQueryColumnProp
->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME
),"Property REALNAME not available!");
1677 OSL_ENSURE(xQueryColumnProp
->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME
),"Property TABLENAME not available!");
1678 xQueryColumnProp
->getPropertyValue(PROPERTY_REALNAME
) >>= sRealName
;
1679 xQueryColumnProp
->getPropertyValue(PROPERTY_TABLENAME
) >>= sTableName
;
1681 for(;pTblColumnIter
!= pTblColumnEnd
;++pTblColumnIter
)
1683 if(bCase(sRealName
,*pTblColumnIter
) && bCase(_rsUpdateTableName
,sTableName
) && o_rColumnNames
.find(*pTblColumnIter
) == o_rColumnNames
.end())
1685 sal_Int32 nType
= 0;
1686 xQueryColumnProp
->getPropertyValue(PROPERTY_TYPE
) >>= nType
;
1687 sal_Int32 nScale
= 0;
1688 xQueryColumnProp
->getPropertyValue(PROPERTY_SCALE
) >>= nScale
;
1689 ::rtl::OUString sColumnDefault
;
1690 if ( xQueryColumnProp
->getPropertySetInfo()->hasPropertyByName(PROPERTY_DEFAULTVALUE
) )
1691 xQueryColumnProp
->getPropertyValue(PROPERTY_DEFAULTVALUE
) >>= sColumnDefault
;
1693 sal_Int32 nNullable
= ColumnValue::NULLABLE_UNKNOWN
;
1694 OSL_VERIFY( xQueryColumnProp
->getPropertyValue( PROPERTY_ISNULLABLE
) >>= nNullable
);
1696 if ( i_bAppendTableName
)
1698 ::rtl::OUStringBuffer sName
;
1699 sName
.append(sTableName
);
1700 sName
.appendAscii(".");
1701 sName
.append(sRealName
);
1702 SelectColumnDescription
aColDesc( nPos
, nType
,nScale
,nNullable
!= sdbc::ColumnValue::NO_NULLS
, sColumnDefault
);
1703 aColDesc
.sRealName
= sRealName
;
1704 aColDesc
.sTableName
= sTableName
;
1705 o_rColumnNames
[sName
.makeStringAndClear()] = aColDesc
;
1708 o_rColumnNames
[sRealName
] = SelectColumnDescription( nPos
, nType
,nScale
,nNullable
!= sdbc::ColumnValue::NO_NULLS
, sColumnDefault
);
1713 pTblColumnIter
= _aColumnNames
.getConstArray();
1718 void OKeySet::impl_convertValue_throw(const ORowSetRow
& _rInsertRow
,const SelectColumnDescription
& i_aMetaData
)
1720 ORowSetValue
& aValue((_rInsertRow
->get())[i_aMetaData
.nPosition
]);
1721 switch(i_aMetaData
.nType
)
1723 case DataType::DECIMAL
:
1724 case DataType::NUMERIC
:
1726 ::rtl::OUString sValue
= aValue
.getString();
1727 sal_Int32 nIndex
= sValue
.indexOf('.');
1730 aValue
= sValue
.copy(0,::std::min(sValue
.getLength(),nIndex
+ (i_aMetaData
.nScale
> 0 ? i_aMetaData
.nScale
+ 1 : 0)));
1738 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */