1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbaccess.hxx"
26
27 #ifndef DBACCESS_CORE_API_KEYSET_HXX
28 #include "KeySet.hxx"
29 #endif
30 #ifndef _DBA_CORE_RESOURCE_HXX_
31 #include "core_resource.hxx"
32 #endif
33 #ifndef _DBA_CORE_RESOURCE_HRC_
34 #include "core_resource.hrc"
35 #endif
36 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #endif
39 #ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
40 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
41 #endif
42 #include <com/sun/star/sdbc/ColumnValue.hpp>
43 #ifndef _COM_SUN_STAR_SDBC_XPREPAREDSTATEMENT_HPP_
44 #include <com/sun/star/sdbc/XPreparedStatement.hpp>
45 #endif
46 #ifndef _COM_SUN_STAR_SDBCxParameterS_HPP_
47 #include <com/sun/star/sdbc/XParameters.hpp>
48 #endif
49 #ifndef _COM_SUN_STAR_SDBC_XGENERATEDRESULTSET_HPP_
50 #include <com/sun/star/sdbc/XGeneratedResultSet.hpp>
51 #endif
52 #ifndef _COM_SUN_STAR_SDBC_XCOLUMNLOCATE_HPP_
53 #include <com/sun/star/sdbc/XColumnLocate.hpp>
54 #endif
55 #ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_
56 #include <com/sun/star/container/XIndexAccess.hpp>
57 #endif
58 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC
59 #include "dbastrings.hrc"
60 #endif
61 #ifndef _DBASHARED_APITOOLS_HXX_
62 #include "apitools.hxx"
63 #endif
64 #ifndef _COM_SUN_STAR_SDBCX_XKEYSSUPPLIER_HPP_
65 #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
66 #endif
67 #ifndef _COM_SUN_STAR_SDB_XSINGLESELECTQUERYCOMPOSER_HPP_
68 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
69 #endif
70 #ifndef _COM_SUN_STAR_SDBCX_XINDEXESSUPPLIER_HPP_
71 #include <com/sun/star/sdbcx/XIndexesSupplier.hpp>
72 #endif
73 #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
74 #include <cppuhelper/typeprovider.hxx>
75 #endif
76 #ifndef _COMPHELPER_TYPES_HXX_
77 #include <comphelper/types.hxx>
78 #endif
79 #ifndef _COM_SUN_STAR_SDBCX_KEYTYPE_HPP_
80 #include <com/sun/star/sdbcx/KeyType.hpp>
81 #endif
82 #ifndef _CONNECTIVITY_DBTOOLS_HXX_
83 #include <connectivity/dbtools.hxx>
84 #endif
85 #ifndef _DBHELPER_DBEXCEPTION_HXX_
86 #include <connectivity/dbexception.hxx>
87 #endif
88 #include <list>
89 #include <algorithm>
90 #include <string.h>
91 #ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
92 #include <com/sun/star/io/XInputStream.hpp>
93 #endif
94 #ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
95 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
96 #endif
97 #ifndef DBACCESS_CORE_API_QUERYCOMPOSER_HXX
98 #include "querycomposer.hxx"
99 #endif
100 #ifndef DBACCESS_SOURCE_CORE_INC_COMPOSERTOOLS_HXX
101 #include "composertools.hxx"
102 #endif
103 #ifndef _TOOLS_DEBUG_HXX
104 #include <tools/debug.hxx>
105 #endif
106 #include <string.h>
107 #include <rtl/logfile.hxx>
108 #include "PrivateRow.hxx"
109
110 using namespace dbaccess;
111 using namespace ::connectivity;
112 using namespace ::dbtools;
113 using namespace ::com::sun::star::uno;
114 using namespace ::com::sun::star::beans;
115 using namespace ::com::sun::star::sdbc;
116 using namespace ::com::sun::star::sdb;
117 using namespace ::com::sun::star::sdbcx;
118 using namespace ::com::sun::star::container;
119 using namespace ::com::sun::star::lang;
120 using namespace ::com::sun::star::util;
121 using namespace ::com::sun::star::io;
122 using namespace ::com::sun::star;
123 using namespace ::cppu;
124 using namespace ::osl;
125
126 namespace
127 {
lcl_fillIndexColumns(const Reference<XIndexAccess> & _xIndexes,::std::vector<Reference<XNameAccess>> & _rAllIndexColumns)128 void lcl_fillIndexColumns(const Reference<XIndexAccess>& _xIndexes, ::std::vector< Reference<XNameAccess> >& _rAllIndexColumns)
129 {
130 if ( _xIndexes.is() )
131 {
132 Reference<XPropertySet> xIndexColsSup;
133 sal_Int32 nCount = _xIndexes->getCount();
134 for(sal_Int32 j = 0 ; j < nCount ; ++j)
135 {
136 xIndexColsSup.set(_xIndexes->getByIndex(j),UNO_QUERY);
137 if( xIndexColsSup.is()
138 && comphelper::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISUNIQUE))
139 && !comphelper::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISPRIMARYKEYINDEX))
140 )
141 _rAllIndexColumns.push_back(Reference<XColumnsSupplier>(xIndexColsSup,UNO_QUERY)->getColumns());
142 }
143 }
144 }
145 }
DBG_NAME(OKeySet)146 DBG_NAME(OKeySet)
147 // -------------------------------------------------------------------------
148 OKeySet::OKeySet(const connectivity::OSQLTable& _xTable,
149 const Reference< XIndexAccess>& _xTableKeys,
150 const ::rtl::OUString& _rUpdateTableName, // this can be the alias or the full qualified name
151 const Reference< XSingleSelectQueryAnalyzer >& _xComposer,
152 const ORowSetValueVector& _aParameterValueForCache,
153 sal_Int32 i_nMaxRows,
154 sal_Int32& o_nRowCount)
155 :OCacheSet(i_nMaxRows)
156 ,m_aParameterValueForCache(_aParameterValueForCache)
157 ,m_pKeyColumnNames(NULL)
158 ,m_pColumnNames(NULL)
159 ,m_pParameterNames(NULL)
160 ,m_pForeignColumnNames(NULL)
161 ,m_xTable(_xTable)
162 ,m_xTableKeys(_xTableKeys)
163 ,m_xComposer(_xComposer)
164 ,m_sUpdateTableName(_rUpdateTableName)
165 ,m_rRowCount(o_nRowCount)
166 ,m_bRowCountFinal(sal_False)
167 {
168 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::OKeySet" );
169 DBG_CTOR(OKeySet,NULL);
170
171 }
172 // -----------------------------------------------------------------------------
~OKeySet()173 OKeySet::~OKeySet()
174 {
175 try
176 {
177 ::comphelper::disposeComponent(m_xStatement);
178 }
179 catch(Exception&)
180 {
181 m_xStatement = NULL;
182 }
183 catch(...)
184 {
185 OSL_ENSURE(0,"Unknown Exception occurred");
186 }
187 m_xComposer = NULL;
188
189 DBG_DTOR(OKeySet,NULL);
190 }
initColumns()191 void OKeySet::initColumns()
192 {
193 Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
194 bool bCase = (xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers()) ? true : false;
195 m_pKeyColumnNames.reset( new SelectColumnsMetaData(bCase) );
196 m_pColumnNames.reset( new SelectColumnsMetaData(bCase) );
197 m_pParameterNames.reset( new SelectColumnsMetaData(bCase) );
198 m_pForeignColumnNames.reset( new SelectColumnsMetaData(bCase) );
199 }
findTableColumnsMatching_throw(const Any & i_aTable,const::rtl::OUString & i_rUpdateTableName,const Reference<XDatabaseMetaData> & i_xMeta,const Reference<XNameAccess> & i_xQueryColumns,::std::auto_ptr<SelectColumnsMetaData> & o_pKeyColumnNames)200 void OKeySet::findTableColumnsMatching_throw( const Any& i_aTable,
201 const ::rtl::OUString& i_rUpdateTableName,
202 const Reference<XDatabaseMetaData>& i_xMeta,
203 const Reference<XNameAccess>& i_xQueryColumns,
204 ::std::auto_ptr<SelectColumnsMetaData>& o_pKeyColumnNames)
205 {
206 // first ask the database itself for the best columns which can be used
207 Sequence< ::rtl::OUString> aBestColumnNames;
208 Reference<XNameAccess> xKeyColumns = getPrimaryKeyColumns_throw(i_aTable);
209 if ( xKeyColumns.is() )
210 aBestColumnNames = xKeyColumns->getElementNames();
211
212 const Reference<XColumnsSupplier> xTblColSup(i_aTable,UNO_QUERY_THROW);
213 const Reference<XNameAccess> xTblColumns = xTblColSup->getColumns();
214 // locate parameter in select columns
215 Reference<XParametersSupplier> xParaSup(m_xComposer,UNO_QUERY);
216 Reference<XIndexAccess> xQueryParameters = xParaSup->getParameters();
217 const sal_Int32 nParaCount = xQueryParameters->getCount();
218 Sequence< ::rtl::OUString> aParameterColumns(nParaCount);
219 for(sal_Int32 i = 0; i< nParaCount;++i)
220 {
221 Reference<XPropertySet> xPara(xQueryParameters->getByIndex(i),UNO_QUERY_THROW);
222 xPara->getPropertyValue(PROPERTY_REALNAME) >>= aParameterColumns[i];
223 }
224
225 ::rtl::OUString sUpdateTableName( i_rUpdateTableName );
226 if ( sUpdateTableName.getLength() == 0 )
227 {
228 OSL_ENSURE( false, "OKeySet::findTableColumnsMatching_throw: This is a fallback only - it won't work when the table has an alias name." );
229 // If i_aTable originates from a query composer, and is a table which appears with an alias in the SELECT statement,
230 // then the below code will not produce correct results.
231 // For instance, imagine a "SELECT alias.col FROM table AS alias". Now i_aTable would be the table named
232 // "table", so our sUpdateTableName would be "table" as well - not the information about the "alias" is
233 // already lost here.
234 // now getColumnPositions would travers the columns, and check which of them belong to the table denoted
235 // by sUpdateTableName. Since the latter is "table", but the columns only know that they belong to a table
236 // named "alias", there will be no matching - so getColumnPositions wouldn't find anything.
237
238 ::rtl::OUString sCatalog, sSchema, sTable;
239 Reference<XPropertySet> xTableProp( i_aTable, UNO_QUERY_THROW );
240 xTableProp->getPropertyValue( PROPERTY_CATALOGNAME )>>= sCatalog;
241 xTableProp->getPropertyValue( PROPERTY_SCHEMANAME ) >>= sSchema;
242 xTableProp->getPropertyValue( PROPERTY_NAME ) >>= sTable;
243 sUpdateTableName = dbtools::composeTableName( i_xMeta, sCatalog, sSchema, sTable, sal_False, ::dbtools::eInDataManipulation );
244 }
245
246 ::dbaccess::getColumnPositions(i_xQueryColumns,aBestColumnNames,sUpdateTableName,(*o_pKeyColumnNames),true);
247 ::dbaccess::getColumnPositions(i_xQueryColumns,xTblColumns->getElementNames(),sUpdateTableName,(*m_pColumnNames),true);
248 ::dbaccess::getColumnPositions(i_xQueryColumns,aParameterColumns,sUpdateTableName,(*m_pParameterNames),true);
249
250 if ( o_pKeyColumnNames->empty() )
251 {
252 ::dbtools::throwGenericSQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not find any key column." ) ), *this );
253 }
254
255 for ( SelectColumnsMetaData::const_iterator keyColumn = o_pKeyColumnNames->begin();
256 keyColumn != o_pKeyColumnNames->end();
257 ++keyColumn
258 )
259 {
260 if ( !xTblColumns->hasByName( keyColumn->second.sRealName ) )
261 continue;
262
263 Reference<XPropertySet> xProp( xTblColumns->getByName( keyColumn->second.sRealName ), UNO_QUERY );
264 sal_Bool bAuto = sal_False;
265 if ( ( xProp->getPropertyValue( PROPERTY_ISAUTOINCREMENT ) >>= bAuto ) && bAuto )
266 m_aAutoColumns.push_back( keyColumn->first );
267 }
268 }
createKeyFilter()269 ::rtl::OUStringBuffer OKeySet::createKeyFilter()
270 {
271 static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND ");
272 const ::rtl::OUString aQuote = getIdentifierQuoteString();
273 ::rtl::OUStringBuffer aFilter;
274 static ::rtl::OUString s_sDot(RTL_CONSTASCII_USTRINGPARAM("."));
275 static ::rtl::OUString s_sParam(RTL_CONSTASCII_USTRINGPARAM(" = ?"));
276 // create the where clause
277 Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
278 SelectColumnsMetaData::iterator aPosEnd = m_pKeyColumnNames->end();
279 for(SelectColumnsMetaData::iterator aPosIter = m_pKeyColumnNames->begin();aPosIter != aPosEnd;)
280 {
281 aFilter.append(::dbtools::quoteTableName( xMeta,aPosIter->second.sTableName,::dbtools::eInDataManipulation));
282 aFilter.append(s_sDot);
283 aFilter.append(::dbtools::quoteName( aQuote,aPosIter->second.sRealName));
284 aFilter.append(s_sParam);
285 ++aPosIter;
286 if(aPosIter != aPosEnd)
287 aFilter.append(aAnd);
288 }
289 return aFilter;
290 }
291 // -----------------------------------------------------------------------------
construct(const Reference<XResultSet> & _xDriverSet,const::rtl::OUString & i_sRowSetFilter)292 void OKeySet::construct(const Reference< XResultSet>& _xDriverSet,const ::rtl::OUString& i_sRowSetFilter)
293 {
294 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::construct" );
295 OCacheSet::construct(_xDriverSet,i_sRowSetFilter);
296 initColumns();
297
298 Reference<XNameAccess> xKeyColumns = getKeyColumns();
299 Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
300 Reference<XColumnsSupplier> xQueryColSup(m_xComposer,UNO_QUERY);
301 const Reference<XNameAccess> xQueryColumns = xQueryColSup->getColumns();
302 findTableColumnsMatching_throw(makeAny(m_xTable),m_sUpdateTableName,xMeta,xQueryColumns,m_pKeyColumnNames);
303
304 // the first row is empty because it's now easier for us to distinguish when we are beforefirst or first
305 // without extra variable to be set
306 m_aKeyMap.insert(OKeySetMatrix::value_type(0,OKeySetValue(NULL,::std::pair<sal_Int32,Reference<XRow> >(0,NULL))));
307 m_aKeyIter = m_aKeyMap.begin();
308
309 ::rtl::OUStringBuffer aFilter = createKeyFilter();
310
311 Reference< XSingleSelectQueryComposer> xSourceComposer(m_xComposer,UNO_QUERY);
312 Reference< XMultiServiceFactory > xFactory(m_xConnection, UNO_QUERY_THROW);
313 Reference<XSingleSelectQueryComposer> xAnalyzer(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY);
314 xAnalyzer->setElementaryQuery(xSourceComposer->getElementaryQuery());
315 Reference<XTablesSupplier> xTabSup(xAnalyzer,uno::UNO_QUERY);
316 Reference<XNameAccess> xSelectTables(xTabSup->getTables(),uno::UNO_QUERY);
317 const Sequence< ::rtl::OUString> aSeq = xSelectTables->getElementNames();
318 if ( aSeq.getLength() > 1 ) // special handling for join
319 {
320 static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND ");
321 const ::rtl::OUString aQuote = getIdentifierQuoteString();
322 static ::rtl::OUString s_sDot(RTL_CONSTASCII_USTRINGPARAM("."));
323 static ::rtl::OUString s_sParam(RTL_CONSTASCII_USTRINGPARAM(" = ?"));
324 const ::rtl::OUString* pIter = aSeq.getConstArray();
325 const ::rtl::OUString* pEnd = pIter + aSeq.getLength();
326 for(;pIter != pEnd;++pIter)
327 {
328 if ( *pIter != m_sUpdateTableName )
329 {
330 connectivity::OSQLTable xSelColSup(xSelectTables->getByName(*pIter),uno::UNO_QUERY);
331 Reference<XPropertySet> xProp(xSelColSup,uno::UNO_QUERY);
332 ::rtl::OUString sSelectTableName = ::dbtools::composeTableName( xMeta, xProp, ::dbtools::eInDataManipulation, false, false, false );
333
334 ::dbaccess::getColumnPositions(xQueryColumns,xSelColSup->getColumns()->getElementNames(),sSelectTableName,(*m_pForeignColumnNames));
335
336 SelectColumnsMetaData::iterator aPosEnd = (*m_pForeignColumnNames).end();
337 for(SelectColumnsMetaData::iterator aPosIter = (*m_pForeignColumnNames).begin();aPosIter != aPosEnd;++aPosIter)
338 {
339 // look for columns not in the source columns to use them as filter as well
340 // if ( !xSourceColumns->hasByName(aPosIter->first) )
341 {
342 if ( aFilter.getLength() )
343 aFilter.append(aAnd);
344 aFilter.append(::dbtools::quoteName( aQuote,sSelectTableName));
345 aFilter.append(s_sDot);
346 aFilter.append(::dbtools::quoteName( aQuote,aPosIter->second.sRealName));
347 aFilter.append(s_sParam);
348 }
349 }
350 break;
351 }
352 }
353 } // if ( aSeq.getLength() > 1 ) // special handling for join
354 executeStatement(aFilter,i_sRowSetFilter,xAnalyzer);
355 }
executeStatement(::rtl::OUStringBuffer & io_aFilter,const::rtl::OUString & i_sRowSetFilter,Reference<XSingleSelectQueryComposer> & io_xAnalyzer)356 void OKeySet::executeStatement(::rtl::OUStringBuffer& io_aFilter,const ::rtl::OUString& i_sRowSetFilter,Reference<XSingleSelectQueryComposer>& io_xAnalyzer)
357 {
358 bool bFilterSet = i_sRowSetFilter.getLength() != 0;
359 if ( bFilterSet )
360 {
361 FilterCreator aFilterCreator;
362 aFilterCreator.append( i_sRowSetFilter );
363 aFilterCreator.append( io_aFilter.makeStringAndClear() );
364 io_aFilter = aFilterCreator.getComposedAndClear();
365 }
366 io_xAnalyzer->setFilter(io_aFilter.makeStringAndClear());
367 if ( bFilterSet )
368 {
369 Sequence< Sequence< PropertyValue > > aFilter2 = io_xAnalyzer->getStructuredFilter();
370 const Sequence< PropertyValue >* pOr = aFilter2.getConstArray();
371 const Sequence< PropertyValue >* pOrEnd = pOr + aFilter2.getLength();
372 for(;pOr != pOrEnd;++pOr)
373 {
374 const PropertyValue* pAnd = pOr->getConstArray();
375 const PropertyValue* pAndEnd = pAnd + pOr->getLength();
376 for(;pAnd != pAndEnd;++pAnd)
377 {
378 ::rtl::OUString sValue;
379 if ( !(pAnd->Value >>= sValue) || !(sValue.equalsAscii("?") || sValue.matchAsciiL(":",1,0)) )
380 { // we have a criteria which has to be taken into account for updates
381 m_aFilterColumns.push_back(pAnd->Name);
382 }
383 }
384 }
385 }
386 m_xStatement = m_xConnection->prepareStatement(io_xAnalyzer->getQueryWithSubstitution());
387 ::comphelper::disposeComponent(io_xAnalyzer);
388 }
389 // -------------------------------------------------------------------------
getBookmark()390 Any SAL_CALL OKeySet::getBookmark() throw(SQLException, RuntimeException)
391 {
392 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBookmark" );
393 OSL_ENSURE(m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin(),
394 "getBookmark is only possible when we stand on a valid row!");
395 return makeAny(m_aKeyIter->first);
396 }
397
398 // -------------------------------------------------------------------------
moveToBookmark(const Any & bookmark)399 sal_Bool SAL_CALL OKeySet::moveToBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
400 {
401 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::moveToBookmark" );
402 m_bInserted = m_bUpdated = m_bDeleted = sal_False;
403 m_aKeyIter = m_aKeyMap.find(::comphelper::getINT32(bookmark));
404 return m_aKeyIter != m_aKeyMap.end();
405 }
406 // -------------------------------------------------------------------------
moveRelativeToBookmark(const Any & bookmark,sal_Int32 rows)407 sal_Bool SAL_CALL OKeySet::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows ) throw(SQLException, RuntimeException)
408 {
409 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::moveRelativeToBookmark" );
410 m_bInserted = m_bUpdated = m_bDeleted = sal_False;
411 m_aKeyIter = m_aKeyMap.find(::comphelper::getINT32(bookmark));
412 if(m_aKeyIter != m_aKeyMap.end())
413 {
414 relative(rows);
415 }
416
417 return !isBeforeFirst() && !isAfterLast();
418 }
419 // -------------------------------------------------------------------------
compareBookmarks(const Any & _first,const Any & _second)420 sal_Int32 SAL_CALL OKeySet::compareBookmarks( const Any& _first, const Any& _second ) throw(SQLException, RuntimeException)
421 {
422 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::compareBookmarks" );
423 sal_Int32 nFirst = 0, nSecond = 0;
424 _first >>= nFirst;
425 _second >>= nSecond;
426
427 return (nFirst != nSecond) ? CompareBookmark::NOT_EQUAL : CompareBookmark::EQUAL;
428 }
429 // -------------------------------------------------------------------------
hasOrderedBookmarks()430 sal_Bool SAL_CALL OKeySet::hasOrderedBookmarks( ) throw(SQLException, RuntimeException)
431 {
432 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::hasOrderedBookmarks" );
433 return sal_True;
434 }
435 // -------------------------------------------------------------------------
hashBookmark(const Any & bookmark)436 sal_Int32 SAL_CALL OKeySet::hashBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
437 {
438 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::hashBookmark" );
439 return ::comphelper::getINT32(bookmark);
440 }
441 // -------------------------------------------------------------------------
442 // ::com::sun::star::sdbcx::XDeleteRows
deleteRows(const Sequence<Any> & rows,const connectivity::OSQLTable & _xTable)443 Sequence< sal_Int32 > SAL_CALL OKeySet::deleteRows( const Sequence< Any >& rows ,const connectivity::OSQLTable& _xTable) throw(SQLException, RuntimeException)
444 {
445 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::deleteRows" );
446 Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
447 fillTableName(xSet);
448
449 ::rtl::OUStringBuffer aSql = ::rtl::OUString::createFromAscii("DELETE FROM ");
450 aSql.append(m_aComposedTableName);
451 aSql.append(::rtl::OUString::createFromAscii(" WHERE "));
452
453 // list all columns that should be set
454 const ::rtl::OUString aQuote = getIdentifierQuoteString();
455 static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND ");
456 static ::rtl::OUString aOr = ::rtl::OUString::createFromAscii(" OR ");
457 static ::rtl::OUString aEqual = ::rtl::OUString::createFromAscii(" = ?");
458
459
460 // use keys and indexes for exact positioning
461 // first the keys
462 Reference<XNameAccess> xKeyColumns = getKeyColumns();
463
464 ::rtl::OUStringBuffer aCondition = ::rtl::OUString::createFromAscii("( ");
465
466 SelectColumnsMetaData::const_iterator aIter = (*m_pKeyColumnNames).begin();
467 SelectColumnsMetaData::const_iterator aPosEnd = (*m_pKeyColumnNames).end();
468 for(;aIter != aPosEnd;++aIter)
469 {
470 aCondition.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
471 aCondition.append(aEqual);
472 aCondition.append(aAnd);
473 }
474 aCondition.setLength(aCondition.getLength()-5);
475 const ::rtl::OUString sCon( aCondition.makeStringAndClear() );
476
477 const Any* pBegin = rows.getConstArray();
478 const Any* pEnd = pBegin + rows.getLength();
479
480 Sequence< Any > aKeys;
481 for(;pBegin != pEnd;++pBegin)
482 {
483 aSql.append(sCon);
484 aSql.append(aOr);
485 }
486 aSql.setLength(aSql.getLength()-3);
487
488 // now create end execute the prepared statement
489
490 Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(aSql.makeStringAndClear()));
491 Reference< XParameters > xParameter(xPrep,UNO_QUERY);
492
493 pBegin = rows.getConstArray();
494 sal_Int32 i=1;
495 for(;pBegin != pEnd;++pBegin)
496 {
497 m_aKeyIter = m_aKeyMap.find(::comphelper::getINT32(*pBegin));
498 if(m_aKeyIter != m_aKeyMap.end())
499 {
500 connectivity::ORowVector< ORowSetValue >::Vector::iterator aKeyIter = m_aKeyIter->second.first->get().begin();
501 connectivity::ORowVector< ORowSetValue >::Vector::iterator aKeyEnd = m_aKeyIter->second.first->get().end();
502 SelectColumnsMetaData::const_iterator aPosIter = (*m_pKeyColumnNames).begin();
503 for(sal_uInt16 j = 0;aKeyIter != aKeyEnd;++aKeyIter,++j,++aPosIter)
504 {
505 setParameter(i++,xParameter,*aKeyIter,aPosIter->second.nType,aPosIter->second.nScale);
506 }
507 }
508 }
509
510 sal_Bool bOk = xPrep->executeUpdate() > 0;
511 Sequence< sal_Int32 > aRet(rows.getLength());
512 memset(aRet.getArray(),bOk,sizeof(sal_Int32)*aRet.getLength());
513 if(bOk)
514 {
515 pBegin = rows.getConstArray();
516 pEnd = pBegin + rows.getLength();
517
518 for(;pBegin != pEnd;++pBegin)
519 {
520 sal_Int32 nPos = 0;
521 *pBegin >>= nPos;
522 if(m_aKeyIter == m_aKeyMap.find(nPos) && m_aKeyIter != m_aKeyMap.end())
523 ++m_aKeyIter;
524 m_aKeyMap.erase(nPos);
525 m_bDeleted = sal_True;
526 }
527 }
528 return aRet;
529 }
530 // -------------------------------------------------------------------------
updateRow(const ORowSetRow & _rInsertRow,const ORowSetRow & _rOrginalRow,const connectivity::OSQLTable & _xTable)531 void SAL_CALL OKeySet::updateRow(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
532 {
533 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::updateRow" );
534 Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
535 fillTableName(xSet);
536
537 ::rtl::OUStringBuffer aSql = ::rtl::OUString::createFromAscii("UPDATE ");
538 aSql.append(m_aComposedTableName);
539 aSql.append(::rtl::OUString::createFromAscii(" SET "));
540 // list all columns that should be set
541 static ::rtl::OUString aPara = ::rtl::OUString::createFromAscii(" = ?,");
542 ::rtl::OUString aQuote = getIdentifierQuoteString();
543 static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND ");
544 ::rtl::OUString sIsNull(RTL_CONSTASCII_USTRINGPARAM(" IS NULL"));
545 ::rtl::OUString sParam(RTL_CONSTASCII_USTRINGPARAM(" = ?"));
546
547 // use keys and indexes for exact positioning
548 // first the keys
549 Reference<XNameAccess> xKeyColumns = getKeyColumns();
550
551 // second the indexes
552 Reference<XIndexesSupplier> xIndexSup(_xTable,UNO_QUERY);
553 Reference<XIndexAccess> xIndexes;
554 if ( xIndexSup.is() )
555 xIndexes.set(xIndexSup->getIndexes(),UNO_QUERY);
556
557
558 ::std::vector< Reference<XNameAccess> > aAllIndexColumns;
559 lcl_fillIndexColumns(xIndexes,aAllIndexColumns);
560
561 ::rtl::OUString aColumnName;
562 ::rtl::OUStringBuffer sKeyCondition,sIndexCondition;
563 ::std::vector<sal_Int32> aIndexColumnPositions;
564
565 const sal_Int32 nOldLength = aSql.getLength();
566 sal_Int32 i = 1;
567 // here we build the condition part for the update statement
568 SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
569 SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
570 for(;aIter != aEnd;++aIter,++i)
571 {
572 //if(xKeyColumns.is() && xKeyColumns->hasByName(aIter->first))
573 if ( m_pKeyColumnNames->find(aIter->first) != m_pKeyColumnNames->end() )
574 {
575 sKeyCondition.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
576 if((_rOrginalRow->get())[aIter->second.nPosition].isNull())
577 sKeyCondition.append(sIsNull);
578 else
579 sKeyCondition.append(sParam);
580 sKeyCondition.append(aAnd);
581 }
582 else
583 {
584 ::std::vector< Reference<XNameAccess> >::const_iterator aIndexEnd = aAllIndexColumns.end();
585 for( ::std::vector< Reference<XNameAccess> >::const_iterator aIndexIter = aAllIndexColumns.begin();
586 aIndexIter != aIndexEnd;++aIndexIter)
587 {
588 if((*aIndexIter)->hasByName(aIter->first))
589 {
590 sIndexCondition.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
591 if((_rOrginalRow->get())[aIter->second.nPosition].isNull())
592 sIndexCondition.append(sIsNull);
593 else
594 {
595 sIndexCondition.append(sParam);
596 aIndexColumnPositions.push_back(aIter->second.nPosition);
597 }
598 sIndexCondition.append(aAnd);
599 break;
600 }
601 }
602 }
603 if((_rInsertRow->get())[aIter->second.nPosition].isModified())
604 {
605 aSql.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
606 aSql.append(aPara);
607 }
608 }
609
610 if( aSql.getLength() != nOldLength )
611 {
612 aSql.setLength(aSql.getLength()-1);
613 }
614 else
615 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_VALUE_CHANGED ), SQL_GENERAL_ERROR, m_xConnection );
616
617 if(sKeyCondition.getLength() || sIndexCondition.getLength())
618 {
619 aSql.append(::rtl::OUString::createFromAscii(" WHERE "));
620 if(sKeyCondition.getLength() && sIndexCondition.getLength())
621 {
622 aSql.append(sKeyCondition.makeStringAndClear());
623 aSql.append(sIndexCondition.makeStringAndClear());
624 }
625 else if(sKeyCondition.getLength())
626 {
627 aSql.append(sKeyCondition.makeStringAndClear());
628 }
629 else if(sIndexCondition.getLength())
630 {
631 aSql.append(sIndexCondition.makeStringAndClear());
632 }
633 aSql.setLength(aSql.getLength()-5); // remove the last AND
634 }
635 else
636 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_CONDITION_FOR_PK ), SQL_GENERAL_ERROR, m_xConnection );
637
638 // now create end execute the prepared statement
639
640 ::rtl::OUString sEmpty;
641 executeUpdate(_rInsertRow ,_rOrginalRow,aSql.makeStringAndClear(),sEmpty,aIndexColumnPositions);
642 }
643 // -----------------------------------------------------------------------------
executeUpdate(const ORowSetRow & _rInsertRow,const ORowSetRow & _rOrginalRow,const::rtl::OUString & i_sSQL,const::rtl::OUString & i_sTableName,const::std::vector<sal_Int32> & _aIndexColumnPositions)644 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)
645 {
646 // now create end execute the prepared statement
647 Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(i_sSQL));
648 Reference< XParameters > xParameter(xPrep,UNO_QUERY);
649
650 bool bRefetch = true;
651 Reference<XRow> xRow;
652 sal_Int32 i = 1;
653 // first the set values
654 SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
655 SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
656 sal_uInt16 j = 0;
657 for(;aIter != aEnd;++aIter,++j)
658 {
659 if ( !i_sTableName.getLength() || aIter->second.sTableName == i_sTableName )
660 {
661 sal_Int32 nPos = aIter->second.nPosition;
662 if((_rInsertRow->get())[nPos].isModified())
663 {
664 if ( bRefetch )
665 {
666 bRefetch = ::std::find(m_aFilterColumns.begin(),m_aFilterColumns.end(),aIter->second.sRealName) == m_aFilterColumns.end();
667 }
668 impl_convertValue_throw(_rInsertRow,aIter->second);
669 (_rInsertRow->get())[nPos].setSigned((_rOrginalRow->get())[nPos].isSigned());
670 setParameter(i++,xParameter,(_rInsertRow->get())[nPos],aIter->second.nType,aIter->second.nScale);
671 }
672 }
673 }
674 // and then the values of the where condition
675 aIter = m_pKeyColumnNames->begin();
676 aEnd = m_pKeyColumnNames->end();
677 j = 0;
678 for(;aIter != aEnd;++aIter,++j)
679 {
680 if ( !i_sTableName.getLength() || aIter->second.sTableName == i_sTableName )
681 {
682 setParameter(i++,xParameter,(_rOrginalRow->get())[aIter->second.nPosition],aIter->second.nType,aIter->second.nScale);
683 }
684 }
685 if ( !_aIndexColumnPositions.empty() )
686 {
687 // now we have to set the index values
688 ::std::vector<sal_Int32>::const_iterator aIdxColIter = _aIndexColumnPositions.begin();
689 ::std::vector<sal_Int32>::const_iterator aIdxColEnd = _aIndexColumnPositions.end();
690 j = 0;
691 aIter = m_pColumnNames->begin();
692 for(;aIdxColIter != aIdxColEnd;++aIdxColIter,++i,++j,++aIter)
693 {
694 setParameter(i,xParameter,(_rOrginalRow->get())[*aIdxColIter],(_rOrginalRow->get())[*aIdxColIter].getTypeKind(),aIter->second.nScale);
695 }
696 }
697 const sal_Int32 nRowsUpdated = xPrep->executeUpdate();
698 m_bUpdated = nRowsUpdated > 0;
699 if(m_bUpdated)
700 {
701 const sal_Int32 nBookmark = ::comphelper::getINT32((_rInsertRow->get())[0].getAny());
702 m_aKeyIter = m_aKeyMap.find(nBookmark);
703 m_aKeyIter->second.second.first = 2;
704 m_aKeyIter->second.second.second = xRow;
705 copyRowValue(_rInsertRow,m_aKeyIter->second.first,nBookmark);
706 tryRefetch(_rInsertRow,bRefetch);
707 }
708 }
709 // -------------------------------------------------------------------------
insertRow(const ORowSetRow & _rInsertRow,const connectivity::OSQLTable & _xTable)710 void SAL_CALL OKeySet::insertRow( const ORowSetRow& _rInsertRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
711 {
712 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::insertRow" );
713 ::rtl::OUStringBuffer aSql(::rtl::OUString::createFromAscii("INSERT INTO "));
714 Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
715 fillTableName(xSet);
716
717 aSql.append(m_aComposedTableName);
718 aSql.append(::rtl::OUString::createFromAscii(" ( "));
719 // set values and column names
720 ::rtl::OUStringBuffer aValues(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" VALUES ( ")));
721 static ::rtl::OUString aPara(RTL_CONSTASCII_USTRINGPARAM("?,"));
722 ::rtl::OUString aQuote = getIdentifierQuoteString();
723 static ::rtl::OUString aComma(RTL_CONSTASCII_USTRINGPARAM(","));
724
725 SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
726 SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
727 sal_Int32 j = 1;
728 bool bRefetch = true;
729 sal_Bool bModified = sal_False;
730 for(;aIter != aEnd;++aIter,++j)
731 {
732 if((_rInsertRow->get())[aIter->second.nPosition].isModified())
733 {
734 if ( bRefetch )
735 {
736 bRefetch = ::std::find(m_aFilterColumns.begin(),m_aFilterColumns.end(),aIter->second.sRealName) == m_aFilterColumns.end();
737 }
738 aSql.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
739 aSql.append(aComma);
740 aValues.append(aPara);
741 bModified = sal_True;
742 }
743 }
744 if ( !bModified )
745 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_VALUE_CHANGED ), SQL_GENERAL_ERROR, m_xConnection );
746
747 aSql.setCharAt(aSql.getLength()-1,')');
748 aValues.setCharAt(aValues.getLength()-1,')');
749 aSql.append(aValues.makeStringAndClear());
750 // now create,fill and execute the prepared statement
751 ::rtl::OUString sEmpty;
752 executeInsert(_rInsertRow,aSql.makeStringAndClear(),sEmpty,bRefetch);
753 }
754 // -------------------------------------------------------------------------
executeInsert(const ORowSetRow & _rInsertRow,const::rtl::OUString & i_sSQL,const::rtl::OUString & i_sTableName,bool bRefetch)755 void OKeySet::executeInsert( const ORowSetRow& _rInsertRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName,bool bRefetch )
756 {
757 // now create,fill and execute the prepared statement
758 Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(i_sSQL));
759 Reference< XParameters > xParameter(xPrep,UNO_QUERY);
760
761 SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
762 SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
763 for(sal_Int32 i = 1;aIter != aEnd;++aIter)
764 {
765 if ( !i_sTableName.getLength() || aIter->second.sTableName == i_sTableName )
766 {
767 const sal_Int32 nPos = aIter->second.nPosition;
768 if((_rInsertRow->get())[nPos].isModified())
769 {
770 if((_rInsertRow->get())[nPos].isNull())
771 xParameter->setNull(i++,(_rInsertRow->get())[nPos].getTypeKind());
772 else
773 {
774 impl_convertValue_throw(_rInsertRow,aIter->second);
775 (_rInsertRow->get())[nPos].setSigned(m_aSignedFlags[nPos-1]);
776 setParameter(i++,xParameter,(_rInsertRow->get())[nPos],aIter->second.nType,aIter->second.nScale);
777 }
778 }
779 }
780 }
781
782 m_bInserted = xPrep->executeUpdate() > 0;
783 sal_Bool bAutoValuesFetched = sal_False;
784 if ( m_bInserted )
785 {
786 // first insert the default values into the insertrow
787 aIter = m_pColumnNames->begin();
788 for(;aIter != aEnd;++aIter)
789 {
790 if ( !(_rInsertRow->get())[aIter->second.nPosition].isModified() )
791 (_rInsertRow->get())[aIter->second.nPosition] = aIter->second.sDefaultValue;
792 }
793 try
794 {
795 Reference< XGeneratedResultSet > xGRes(xPrep, UNO_QUERY);
796 if ( xGRes.is() )
797 {
798 Reference< XResultSet > xRes = xGRes->getGeneratedValues();
799 Reference< XRow > xRow(xRes,UNO_QUERY);
800 if ( xRow.is() && xRes->next() )
801 {
802 Reference< XResultSetMetaDataSupplier > xMdSup(xRes,UNO_QUERY);
803 Reference< XResultSetMetaData > xMd = xMdSup->getMetaData();
804 sal_Int32 nColumnCount = xMd->getColumnCount();
805 ::std::vector< ::rtl::OUString >::iterator aAutoIter = m_aAutoColumns.begin();
806 ::std::vector< ::rtl::OUString >::iterator aAutoEnd = m_aAutoColumns.end();
807 for (sal_Int32 i = 1;aAutoIter != aAutoEnd && i <= nColumnCount; ++aAutoIter,++i)
808 {
809 #if OSL_DEBUG_LEVEL > 1
810 ::rtl::OUString sColumnName( xMd->getColumnName(i) );
811 #endif
812 SelectColumnsMetaData::iterator aFind = m_pKeyColumnNames->find(*aAutoIter);
813 if ( aFind != m_pKeyColumnNames->end() )
814 (_rInsertRow->get())[aFind->second.nPosition].fill(i,aFind->second.nType,aFind->second.bNullable,xRow);
815 }
816 bAutoValuesFetched = sal_True;
817 }
818 }
819 }
820 catch(Exception&)
821 {
822 OSL_ENSURE(0,"Could not execute GeneratedKeys() stmt");
823 }
824 }
825
826 ::comphelper::disposeComponent(xPrep);
827
828 if ( !i_sTableName.getLength() && !bAutoValuesFetched && m_bInserted )
829 {
830 // first check if all key column values were set
831 const ::rtl::OUString sMax(RTL_CONSTASCII_USTRINGPARAM(" MAX("));
832 const ::rtl::OUString sMaxEnd(RTL_CONSTASCII_USTRINGPARAM("),"));
833 const ::rtl::OUString sQuote = getIdentifierQuoteString();
834 ::rtl::OUString sMaxStmt;
835 aEnd = m_pKeyColumnNames->end();
836 ::std::vector< ::rtl::OUString >::iterator aAutoIter = m_aAutoColumns.begin();
837 ::std::vector< ::rtl::OUString >::iterator aAutoEnd = m_aAutoColumns.end();
838 for (;aAutoIter != aAutoEnd; ++aAutoIter)
839 {
840 // we will only fetch values which are keycolumns
841 SelectColumnsMetaData::iterator aFind = m_pKeyColumnNames->find(*aAutoIter);
842 if ( aFind != aEnd )
843 {
844 sMaxStmt += sMax;
845 sMaxStmt += ::dbtools::quoteName( sQuote,aFind->second.sRealName
846 );
847 sMaxStmt += sMaxEnd;
848 }
849 }
850
851 if(sMaxStmt.getLength())
852 {
853 sMaxStmt = sMaxStmt.replaceAt(sMaxStmt.getLength()-1,1,::rtl::OUString::createFromAscii(" "));
854 ::rtl::OUString sStmt = ::rtl::OUString::createFromAscii("SELECT ");
855 sStmt += sMaxStmt;
856 sStmt += ::rtl::OUString::createFromAscii("FROM ");
857 ::rtl::OUString sCatalog,sSchema,sTable;
858 ::dbtools::qualifiedNameComponents(m_xConnection->getMetaData(),m_sUpdateTableName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation);
859 sStmt += ::dbtools::composeTableNameForSelect( m_xConnection, sCatalog, sSchema, sTable );
860 try
861 {
862 // now fetch the autoincrement values
863 Reference<XStatement> xStatement = m_xConnection->createStatement();
864 Reference<XResultSet> xRes = xStatement->executeQuery(sStmt);
865 Reference<XRow> xRow(xRes,UNO_QUERY);
866 if(xRow.is() && xRes->next())
867 {
868 aAutoIter = m_aAutoColumns.begin();
869 for (sal_Int32 i=1;aAutoIter != aAutoEnd; ++aAutoIter,++i)
870 {
871 // we will only fetch values which are keycolumns
872 SelectColumnsMetaData::iterator aFind = m_pKeyColumnNames->find(*aAutoIter);
873 if ( aFind != aEnd )
874 (_rInsertRow->get())[aFind->second.nPosition].fill(i,aFind->second.nType,aFind->second.bNullable,xRow);
875 }
876 }
877 ::comphelper::disposeComponent(xStatement);
878 }
879 catch(SQLException&)
880 {
881 OSL_ENSURE(0,"Could not fetch with MAX() ");
882 }
883 }
884 }
885 if ( m_bInserted )
886 {
887 OKeySetMatrix::iterator aKeyIter = m_aKeyMap.end();
888 --aKeyIter;
889 ORowSetRow aKeyRow = new connectivity::ORowVector< ORowSetValue >(m_pKeyColumnNames->size());
890 copyRowValue(_rInsertRow,aKeyRow,aKeyIter->first + 1);
891
892 m_aKeyIter = m_aKeyMap.insert(OKeySetMatrix::value_type(aKeyIter->first + 1,OKeySetValue(aKeyRow,::std::pair<sal_Int32,Reference<XRow> >(1,NULL)))).first;
893 // now we set the bookmark for this row
894 (_rInsertRow->get())[0] = makeAny((sal_Int32)m_aKeyIter->first);
895 tryRefetch(_rInsertRow,bRefetch);
896 }
897 }
tryRefetch(const ORowSetRow & _rInsertRow,bool bRefetch)898 void OKeySet::tryRefetch(const ORowSetRow& _rInsertRow,bool bRefetch)
899 {
900 if ( bRefetch )
901 {
902 // we just areassign the base members
903 try
904 {
905 Reference< XParameters > xParameter(m_xStatement,UNO_QUERY);
906 OSL_ENSURE(xParameter.is(),"No Parameter interface!");
907 xParameter->clearParameters();
908
909 sal_Int32 nPos=1;
910 connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aParaIter;
911 connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aParaEnd;
912 OUpdatedParameter::iterator aUpdateFind = m_aUpdatedParameter.find(m_aKeyIter->first);
913 if ( aUpdateFind == m_aUpdatedParameter.end() )
914 {
915 aParaIter = m_aParameterValueForCache.get().begin();
916 aParaEnd = m_aParameterValueForCache.get().end();
917 }
918 else
919 {
920 aParaIter = aUpdateFind->second.get().begin();
921 aParaEnd = aUpdateFind->second.get().end();
922 }
923
924 for(++aParaIter;aParaIter != aParaEnd;++aParaIter,++nPos)
925 {
926 ::dbtools::setObjectWithInfo( xParameter, nPos, aParaIter->makeAny(), aParaIter->getTypeKind() );
927 }
928 connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aIter2 = m_aKeyIter->second.first->get().begin();
929 SelectColumnsMetaData::const_iterator aPosIter = (*m_pKeyColumnNames).begin();
930 SelectColumnsMetaData::const_iterator aPosEnd = (*m_pKeyColumnNames).end();
931 for(;aPosIter != aPosEnd;++aPosIter,++aIter2,++nPos)
932 setParameter(nPos,xParameter,*aIter2,aPosIter->second.nType,aPosIter->second.nScale);
933 aPosIter = (*m_pForeignColumnNames).begin();
934 aPosEnd = (*m_pForeignColumnNames).end();
935 for(;aPosIter != aPosEnd;++aPosIter,++aIter2,++nPos)
936 setParameter(nPos,xParameter,*aIter2,aPosIter->second.nType,aPosIter->second.nScale);
937
938 m_xSet = m_xStatement->executeQuery();
939 OSL_ENSURE(m_xSet.is(),"No resultset form statement!");
940 bRefetch = m_xSet->next();
941 }
942 catch(Exception)
943 {
944 bRefetch = false;
945 }
946 }
947 if ( !bRefetch )
948 {
949 m_aKeyIter->second.second.second = new OPrivateRow(_rInsertRow->get());
950 }
951 }
952 // -----------------------------------------------------------------------------
copyRowValue(const ORowSetRow & _rInsertRow,ORowSetRow & _rKeyRow,sal_Int32 i_nBookmark)953 void OKeySet::copyRowValue(const ORowSetRow& _rInsertRow,ORowSetRow& _rKeyRow,sal_Int32 i_nBookmark)
954 {
955 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::copyRowValue" );
956 connectivity::ORowVector< ORowSetValue >::Vector::iterator aIter = _rKeyRow->get().begin();
957
958 // check the if the parameter values have been changed
959 OSL_ENSURE((m_aParameterValueForCache.get().size()-1) == m_pParameterNames->size(),"OKeySet::copyRowValue: Parameter values and names differ!");
960 connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aParaValuesIter = m_aParameterValueForCache.get().begin() +1;
961
962 bool bChanged = false;
963 SelectColumnsMetaData::const_iterator aParaIter = (*m_pParameterNames).begin();
964 SelectColumnsMetaData::const_iterator aParaEnd = (*m_pParameterNames).end();
965 for(sal_Int32 i = 1;aParaIter != aParaEnd;++aParaIter,++aParaValuesIter,++i)
966 {
967 ORowSetValue aValue(*aParaValuesIter);
968 aValue.setSigned(m_aSignedFlags[aParaIter->second.nPosition]);
969 if ( (_rInsertRow->get())[aParaIter->second.nPosition] != aValue )
970 {
971 ORowSetValueVector aCopy(m_aParameterValueForCache);
972 (aCopy.get())[i] = (_rInsertRow->get())[aParaIter->second.nPosition];
973 m_aUpdatedParameter[i_nBookmark] = aCopy;
974 bChanged = true;
975 }
976 }
977 if ( !bChanged )
978 {
979 m_aUpdatedParameter.erase(i_nBookmark);
980 }
981
982 // update the key values
983 SelectColumnsMetaData::const_iterator aPosIter = (*m_pKeyColumnNames).begin();
984 SelectColumnsMetaData::const_iterator aPosEnd = (*m_pKeyColumnNames).end();
985 for(;aPosIter != aPosEnd;++aPosIter,++aIter)
986 {
987 impl_convertValue_throw(_rInsertRow,aPosIter->second);
988 *aIter = (_rInsertRow->get())[aPosIter->second.nPosition];
989 aIter->setTypeKind(aPosIter->second.nType);
990 }
991 }
992 // -------------------------------------------------------------------------
deleteRow(const ORowSetRow & _rDeleteRow,const connectivity::OSQLTable & _xTable)993 void SAL_CALL OKeySet::deleteRow(const ORowSetRow& _rDeleteRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
994 {
995 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::deleteRow" );
996 Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
997 fillTableName(xSet);
998
999 ::rtl::OUStringBuffer aSql = ::rtl::OUString::createFromAscii("DELETE FROM ");
1000 aSql.append(m_aComposedTableName);
1001 aSql.append(::rtl::OUString::createFromAscii(" WHERE "));
1002
1003 // list all columns that should be set
1004 ::rtl::OUString aQuote = getIdentifierQuoteString();
1005 static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND ");
1006
1007 // use keys and indexes for exact positioning
1008 Reference<XNameAccess> xKeyColumns = getKeyColumns();
1009 // second the indexes
1010 Reference<XIndexesSupplier> xIndexSup(_xTable,UNO_QUERY);
1011 Reference<XIndexAccess> xIndexes;
1012 if ( xIndexSup.is() )
1013 xIndexes.set(xIndexSup->getIndexes(),UNO_QUERY);
1014
1015 // Reference<XColumnsSupplier>
1016 ::std::vector< Reference<XNameAccess> > aAllIndexColumns;
1017 lcl_fillIndexColumns(xIndexes,aAllIndexColumns);
1018
1019 ::rtl::OUString aColumnName;
1020 ::rtl::OUStringBuffer sIndexCondition;
1021 ::std::vector<sal_Int32> aIndexColumnPositions;
1022 SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
1023 SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
1024
1025 sal_Int32 i = 1;
1026 for(i = 1;aIter != aEnd;++aIter,++i)
1027 {
1028 if ( m_pKeyColumnNames->find(aIter->first) != m_pKeyColumnNames->end() )
1029 {
1030 aSql.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
1031 if((_rDeleteRow->get())[aIter->second.nPosition].isNull())
1032 {
1033 OSL_ENSURE(0,"can a primary key be null");
1034 aSql.append(::rtl::OUString::createFromAscii(" IS NULL"));
1035 }
1036 else
1037 aSql.append(::rtl::OUString::createFromAscii(" = ?"));
1038 aSql.append(aAnd);
1039 }
1040 else
1041 {
1042 ::std::vector< Reference<XNameAccess> >::const_iterator aIndexEnd = aAllIndexColumns.end();
1043 for( ::std::vector< Reference<XNameAccess> >::const_iterator aIndexIter = aAllIndexColumns.begin();
1044 aIndexIter != aIndexEnd;++aIndexIter)
1045 {
1046 if((*aIndexIter)->hasByName(aIter->first))
1047 {
1048 sIndexCondition.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
1049 if((_rDeleteRow->get())[aIter->second.nPosition].isNull())
1050 sIndexCondition.append(::rtl::OUString::createFromAscii(" IS NULL"));
1051 else
1052 {
1053 sIndexCondition.append(::rtl::OUString::createFromAscii(" = ?"));
1054 aIndexColumnPositions.push_back(aIter->second.nPosition);
1055 }
1056 sIndexCondition.append(aAnd);
1057
1058 break;
1059 }
1060 }
1061 }
1062 }
1063 aSql.append(sIndexCondition.makeStringAndClear());
1064 aSql.setLength(aSql.getLength()-5);
1065
1066 // now create end execute the prepared statement
1067 Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(aSql.makeStringAndClear()));
1068 Reference< XParameters > xParameter(xPrep,UNO_QUERY);
1069
1070 aIter = (*m_pKeyColumnNames).begin();
1071 aEnd = (*m_pKeyColumnNames).end();
1072 i = 1;
1073 for(;aIter != aEnd;++aIter,++i)
1074 {
1075 setParameter(i,xParameter,(_rDeleteRow->get())[aIter->second.nPosition],aIter->second.nType,aIter->second.nScale);
1076 }
1077
1078 // now we have to set the index values
1079 ::std::vector<sal_Int32>::iterator aIdxColIter = aIndexColumnPositions.begin();
1080 ::std::vector<sal_Int32>::iterator aIdxColEnd = aIndexColumnPositions.end();
1081 aIter = m_pColumnNames->begin();
1082 for(;aIdxColIter != aIdxColEnd;++aIdxColIter,++i,++aIter)
1083 {
1084 setParameter(i,xParameter,(_rDeleteRow->get())[*aIdxColIter],(_rDeleteRow->get())[*aIdxColIter].getTypeKind(),aIter->second.nScale);
1085 }
1086
1087 m_bDeleted = xPrep->executeUpdate() > 0;
1088
1089 if(m_bDeleted)
1090 {
1091 sal_Int32 nBookmark = ::comphelper::getINT32((_rDeleteRow->get())[0].getAny());
1092 if(m_aKeyIter == m_aKeyMap.find(nBookmark) && m_aKeyIter != m_aKeyMap.end())
1093 ++m_aKeyIter;
1094 m_aKeyMap.erase(nBookmark);
1095 m_bDeleted = sal_True;
1096 }
1097 }
1098 // -------------------------------------------------------------------------
cancelRowUpdates()1099 void SAL_CALL OKeySet::cancelRowUpdates( ) throw(SQLException, RuntimeException)
1100 {
1101 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::cancelRowUpdates" );
1102 m_bInserted = m_bUpdated = m_bDeleted = sal_False;
1103 }
1104 // -------------------------------------------------------------------------
moveToInsertRow()1105 void SAL_CALL OKeySet::moveToInsertRow( ) throw(SQLException, RuntimeException)
1106 {
1107 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::moveToInsertRow" );
1108 }
1109 // -------------------------------------------------------------------------
moveToCurrentRow()1110 void SAL_CALL OKeySet::moveToCurrentRow( ) throw(SQLException, RuntimeException)
1111 {
1112 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::moveToCurrentRow" );
1113 }
1114 // -------------------------------------------------------------------------
getKeyColumns() const1115 Reference<XNameAccess> OKeySet::getKeyColumns() const
1116 {
1117 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getKeyColumns" );
1118 // use keys and indexes for exact positioning
1119 // first the keys
1120
1121 Reference<XIndexAccess> xKeys = m_xTableKeys;
1122 if ( !xKeys.is() )
1123 {
1124 Reference<XPropertySet> xSet(m_xTable,UNO_QUERY);
1125 const Reference<XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(xSet);
1126 return xPrimaryKeyColumns;
1127 }
1128
1129 Reference<XColumnsSupplier> xKeyColsSup;
1130 Reference<XNameAccess> xKeyColumns;
1131 if(xKeys.is())
1132 {
1133 Reference<XPropertySet> xProp;
1134 sal_Int32 nCount = xKeys->getCount();
1135 for(sal_Int32 i = 0;i< nCount;++i)
1136 {
1137 xProp.set(xKeys->getByIndex(i),UNO_QUERY);
1138 if ( xProp.is() )
1139 {
1140 sal_Int32 nKeyType = 0;
1141 xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;
1142 if(KeyType::PRIMARY == nKeyType)
1143 {
1144 xKeyColsSup.set(xProp,UNO_QUERY);
1145 OSL_ENSURE(xKeyColsSup.is(),"Columnsupplier is null!");
1146 xKeyColumns = xKeyColsSup->getColumns();
1147 break;
1148 }
1149 }
1150 }
1151 }
1152
1153 return xKeyColumns;
1154 }
1155 // -----------------------------------------------------------------------------
next()1156 sal_Bool SAL_CALL OKeySet::next( ) throw(SQLException, RuntimeException)
1157 {
1158 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::next" );
1159 m_bInserted = m_bUpdated = m_bDeleted = sal_False;
1160
1161 if(isAfterLast())
1162 return sal_False;
1163 if(!m_bRowCountFinal) // not yet all records fetched
1164 {
1165 ++m_aKeyIter; // this is possible because we stand on begin() and this is the "beforefirst" row
1166 if(m_aKeyIter == m_aKeyMap.end() && !fetchRow())
1167 m_aKeyIter = m_aKeyMap.end();
1168 else
1169 {
1170 //m_aKeyIter->second.second.second = new OPrivateRow(_rInsertRow->get());
1171 m_xRow.set(m_xDriverRow,UNO_QUERY_THROW);
1172 return !isAfterLast();
1173 }
1174 }
1175 else if(!isAfterLast())
1176 ++m_aKeyIter;
1177
1178 refreshRow();
1179 return !isAfterLast();
1180 }
1181 // -----------------------------------------------------------------------------
isBeforeFirst()1182 sal_Bool SAL_CALL OKeySet::isBeforeFirst( ) throw(SQLException, RuntimeException)
1183 {
1184 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isBeforeFirst" );
1185 return m_aKeyIter == m_aKeyMap.begin();
1186 }
1187 // -----------------------------------------------------------------------------
isAfterLast()1188 sal_Bool SAL_CALL OKeySet::isAfterLast( ) throw(SQLException, RuntimeException)
1189 {
1190 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isAfterLast" );
1191 return m_bRowCountFinal && m_aKeyIter == m_aKeyMap.end();
1192 }
1193 // -----------------------------------------------------------------------------
isFirst()1194 sal_Bool SAL_CALL OKeySet::isFirst( ) throw(SQLException, RuntimeException)
1195 {
1196 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isFirst" );
1197 OKeySetMatrix::iterator aTemp = m_aKeyMap.begin();
1198 ++aTemp;
1199 return m_aKeyIter == aTemp && m_aKeyIter != m_aKeyMap.end();
1200 }
1201 // -----------------------------------------------------------------------------
isLast()1202 sal_Bool SAL_CALL OKeySet::isLast( ) throw(SQLException, RuntimeException)
1203 {
1204 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isLast" );
1205 if(!m_bRowCountFinal)
1206 return sal_False;
1207
1208 OKeySetMatrix::iterator aTemp = m_aKeyMap.end();
1209 --aTemp;
1210 return m_aKeyIter == aTemp;
1211 }
1212 // -----------------------------------------------------------------------------
beforeFirst()1213 void SAL_CALL OKeySet::beforeFirst( ) throw(SQLException, RuntimeException)
1214 {
1215 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::beforeFirst" );
1216 m_bInserted = m_bUpdated = m_bDeleted = sal_False;
1217 m_aKeyIter = m_aKeyMap.begin();
1218 m_xRow = NULL;
1219 ::comphelper::disposeComponent(m_xSet);
1220 }
1221 // -----------------------------------------------------------------------------
afterLast()1222 void SAL_CALL OKeySet::afterLast( ) throw(SQLException, RuntimeException)
1223 {
1224 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::afterLast" );
1225 m_bInserted = m_bUpdated = m_bDeleted = sal_False;
1226 fillAllRows();
1227 m_aKeyIter = m_aKeyMap.end();
1228 m_xRow = NULL;
1229 ::comphelper::disposeComponent(m_xSet);
1230 }
1231 // -----------------------------------------------------------------------------
first()1232 sal_Bool SAL_CALL OKeySet::first( ) throw(SQLException, RuntimeException)
1233 {
1234 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::first" );
1235 m_bInserted = m_bUpdated = m_bDeleted = sal_False;
1236 m_aKeyIter = m_aKeyMap.begin();
1237 ++m_aKeyIter;
1238 if(m_aKeyIter == m_aKeyMap.end() && !fetchRow())
1239 m_aKeyIter = m_aKeyMap.end();
1240 else
1241 refreshRow();
1242 return m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin();
1243 }
1244 // -----------------------------------------------------------------------------
last()1245 sal_Bool SAL_CALL OKeySet::last( ) throw(SQLException, RuntimeException)
1246 {
1247 return last_checked(sal_True);
1248 }
1249
last_checked(sal_Bool i_bFetchRow)1250 sal_Bool OKeySet::last_checked( sal_Bool i_bFetchRow)
1251 {
1252 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::last_checked" );
1253 m_bInserted = m_bUpdated = m_bDeleted = sal_False;
1254 fillAllRows();
1255
1256 m_aKeyIter = m_aKeyMap.end();
1257 --m_aKeyIter;
1258 if ( i_bFetchRow )
1259 refreshRow();
1260 return m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin();
1261 }
1262 // -----------------------------------------------------------------------------
getRow()1263 sal_Int32 SAL_CALL OKeySet::getRow( ) throw(SQLException, RuntimeException)
1264 {
1265 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getRow" );
1266 OSL_ENSURE(!isAfterLast(),"getRow is not allowed when afterlast record!");
1267 OSL_ENSURE(!isBeforeFirst(),"getRow is not allowed when beforefirst record!");
1268
1269 return ::std::distance(m_aKeyMap.begin(),m_aKeyIter);
1270 }
1271 // -----------------------------------------------------------------------------
absolute(sal_Int32 row)1272 sal_Bool SAL_CALL OKeySet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException)
1273 {
1274 return absolute_checked(row,sal_True);
1275 }
absolute_checked(sal_Int32 row,sal_Bool i_bFetchRow)1276 sal_Bool OKeySet::absolute_checked( sal_Int32 row,sal_Bool i_bFetchRow )
1277 {
1278 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::absolute" );
1279 m_bInserted = m_bUpdated = m_bDeleted = sal_False;
1280 OSL_ENSURE(row,"absolute(0) isn't allowed!");
1281 if(row < 0)
1282 {
1283 if(!m_bRowCountFinal)
1284 fillAllRows();
1285
1286 for(;row < 0 && m_aKeyIter != m_aKeyMap.begin();++row)
1287 m_aKeyIter--;
1288 }
1289 else
1290 {
1291 if(row >= (sal_Int32)m_aKeyMap.size())
1292 {
1293 if(!m_bRowCountFinal)
1294 {
1295 sal_Bool bNext = sal_True;
1296 for(sal_Int32 i=m_aKeyMap.size()-1;i < row && bNext;++i)
1297 bNext = fetchRow();
1298 if ( bNext )
1299 {
1300 m_xRow.set(m_xDriverRow,UNO_QUERY_THROW);
1301 return m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin();
1302 }
1303 }
1304 else
1305 m_aKeyIter = m_aKeyMap.end();
1306 }
1307 else
1308 {
1309 m_aKeyIter = m_aKeyMap.begin();
1310 for(;row > 0 && m_aKeyIter != m_aKeyMap.end();--row)
1311 ++m_aKeyIter;
1312 }
1313 }
1314 if ( i_bFetchRow )
1315 refreshRow();
1316
1317 return m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin();
1318 }
1319 // -----------------------------------------------------------------------------
relative(sal_Int32 rows)1320 sal_Bool SAL_CALL OKeySet::relative( sal_Int32 rows ) throw(SQLException, RuntimeException)
1321 {
1322 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::relative" );
1323 if(!rows)
1324 {
1325 refreshRow();
1326 return sal_True;
1327 }
1328 return absolute(getRow()+rows);
1329 }
1330 // -----------------------------------------------------------------------------
previous_checked(sal_Bool i_bFetchRow)1331 sal_Bool OKeySet::previous_checked( sal_Bool i_bFetchRow )
1332 {
1333 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::previous" );
1334 m_bInserted = m_bUpdated = m_bDeleted = sal_False;
1335 if(m_aKeyIter != m_aKeyMap.begin())
1336 {
1337 --m_aKeyIter;
1338 if ( i_bFetchRow )
1339 refreshRow();
1340 }
1341 return m_aKeyIter != m_aKeyMap.begin();
1342 }
1343 // -----------------------------------------------------------------------------
previous()1344 sal_Bool SAL_CALL OKeySet::previous( ) throw(SQLException, RuntimeException)
1345 {
1346 return previous_checked(sal_True);
1347 }
1348
1349 // -----------------------------------------------------------------------------
refreshRow()1350 void SAL_CALL OKeySet::refreshRow() throw(SQLException, RuntimeException)
1351 {
1352 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::refreshRow" );
1353 if(isBeforeFirst() || isAfterLast() || !m_xStatement.is())
1354 return;
1355
1356 m_xRow = NULL;
1357 ::comphelper::disposeComponent(m_xSet);
1358
1359 if ( m_aKeyIter->second.second.second.is() )
1360 {
1361 m_xRow = m_aKeyIter->second.second.second;
1362 return;
1363 }
1364 // we just reassign the base members
1365 Reference< XParameters > xParameter(m_xStatement,UNO_QUERY);
1366 OSL_ENSURE(xParameter.is(),"No Parameter interface!");
1367 xParameter->clearParameters();
1368
1369 sal_Int32 nPos=1;
1370 connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aParaIter;
1371 connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aParaEnd;
1372 OUpdatedParameter::iterator aUpdateFind = m_aUpdatedParameter.find(m_aKeyIter->first);
1373 if ( aUpdateFind == m_aUpdatedParameter.end() )
1374 {
1375 aParaIter = m_aParameterValueForCache.get().begin();
1376 aParaEnd = m_aParameterValueForCache.get().end();
1377 }
1378 else
1379 {
1380 aParaIter = aUpdateFind->second.get().begin();
1381 aParaEnd = aUpdateFind->second.get().end();
1382 }
1383
1384 for(++aParaIter;aParaIter != aParaEnd;++aParaIter,++nPos)
1385 {
1386 ::dbtools::setObjectWithInfo( xParameter, nPos, aParaIter->makeAny(), aParaIter->getTypeKind() );
1387 }
1388
1389 // now set the primary key column values
1390 connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aIter = m_aKeyIter->second.first->get().begin();
1391 SelectColumnsMetaData::const_iterator aPosIter = (*m_pKeyColumnNames).begin();
1392 SelectColumnsMetaData::const_iterator aPosEnd = (*m_pKeyColumnNames).end();
1393 for(;aPosIter != aPosEnd;++aPosIter,++aIter,++nPos)
1394 setParameter(nPos,xParameter,*aIter,aPosIter->second.nType,aPosIter->second.nScale);
1395 aPosIter = (*m_pForeignColumnNames).begin();
1396 aPosEnd = (*m_pForeignColumnNames).end();
1397 for(;aPosIter != aPosEnd;++aPosIter,++aIter,++nPos)
1398 setParameter(nPos,xParameter,*aIter,aPosIter->second.nType,aPosIter->second.nScale);
1399
1400 m_xSet = m_xStatement->executeQuery();
1401 OSL_ENSURE(m_xSet.is(),"No resultset form statement!");
1402 sal_Bool bOK = m_xSet->next();
1403 if ( !bOK )
1404 {
1405 OKeySetMatrix::iterator aTemp = m_aKeyIter;
1406 ++m_aKeyIter;
1407 m_aKeyMap.erase(aTemp);
1408 --m_rRowCount;
1409 refreshRow();
1410 }
1411 else
1412 {
1413 m_xRow.set(m_xSet,UNO_QUERY);
1414 OSL_ENSURE(m_xRow.is(),"No row form statement!");
1415 }
1416 }
1417 // -----------------------------------------------------------------------------
fetchRow()1418 sal_Bool OKeySet::fetchRow()
1419 {
1420 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::fetchRow" );
1421 // fetch the next row and append on the keyset
1422 sal_Bool bRet = sal_False;
1423 if ( !m_bRowCountFinal && (!m_nMaxRows || sal_Int32(m_aKeyMap.size()) < m_nMaxRows) )
1424 bRet = m_xDriverSet->next();
1425 if ( bRet )
1426 {
1427 ORowSetRow aKeyRow = new connectivity::ORowVector< ORowSetValue >((*m_pKeyColumnNames).size() + m_pForeignColumnNames->size());
1428 connectivity::ORowVector< ORowSetValue >::Vector::iterator aIter = aKeyRow->get().begin();
1429 // first fetch the values needed for the key column
1430 SelectColumnsMetaData::const_iterator aPosIter = (*m_pKeyColumnNames).begin();
1431 SelectColumnsMetaData::const_iterator aPosEnd = (*m_pKeyColumnNames).end();
1432 for(;aPosIter != aPosEnd;++aPosIter,++aIter)
1433 {
1434 const SelectColumnDescription& rColDesc = aPosIter->second;
1435 aIter->fill(rColDesc.nPosition,rColDesc.nType,rColDesc.bNullable,m_xDriverRow);
1436 }
1437 // now fetch the values from the missing columns from other tables
1438 aPosIter = (*m_pForeignColumnNames).begin();
1439 aPosEnd = (*m_pForeignColumnNames).end();
1440 for(;aPosIter != aPosEnd;++aPosIter,++aIter)
1441 {
1442 const SelectColumnDescription& rColDesc = aPosIter->second;
1443 aIter->fill(rColDesc.nPosition,rColDesc.nType,rColDesc.bNullable,m_xDriverRow);
1444 }
1445 m_aKeyIter = m_aKeyMap.insert(OKeySetMatrix::value_type(m_aKeyMap.rbegin()->first+1,OKeySetValue(aKeyRow,::std::pair<sal_Int32,Reference<XRow> >(0,NULL)))).first;
1446 }
1447 else
1448 m_bRowCountFinal = sal_True;
1449 return bRet;
1450 }
1451 // -------------------------------------------------------------------------
fillAllRows()1452 void OKeySet::fillAllRows()
1453 {
1454 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::fillAllRows" );
1455 if(!m_bRowCountFinal)
1456 {
1457 while(fetchRow())
1458 ;
1459 }
1460 }
1461 // XRow
wasNull()1462 sal_Bool SAL_CALL OKeySet::wasNull( ) throw(SQLException, RuntimeException)
1463 {
1464 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::wasNull" );
1465 return m_xRow->wasNull();
1466 }
1467 // -------------------------------------------------------------------------
getString(sal_Int32 columnIndex)1468 ::rtl::OUString SAL_CALL OKeySet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1469 {
1470 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getString" );
1471 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1472 return m_xRow->getString(columnIndex);
1473 }
1474 // -------------------------------------------------------------------------
getBoolean(sal_Int32 columnIndex)1475 sal_Bool SAL_CALL OKeySet::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1476 {
1477 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBoolean" );
1478 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1479 return m_xRow->getBoolean(columnIndex);
1480 }
1481 // -------------------------------------------------------------------------
getByte(sal_Int32 columnIndex)1482 sal_Int8 SAL_CALL OKeySet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1483 {
1484 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getByte" );
1485 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1486 return m_xRow->getByte(columnIndex);
1487 }
1488 // -------------------------------------------------------------------------
getShort(sal_Int32 columnIndex)1489 sal_Int16 SAL_CALL OKeySet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1490 {
1491 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getShort" );
1492 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1493 return m_xRow->getShort(columnIndex);
1494 }
1495 // -------------------------------------------------------------------------
getInt(sal_Int32 columnIndex)1496 sal_Int32 SAL_CALL OKeySet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1497 {
1498 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getInt" );
1499 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1500 return m_xRow->getInt(columnIndex);
1501 }
1502 // -------------------------------------------------------------------------
getLong(sal_Int32 columnIndex)1503 sal_Int64 SAL_CALL OKeySet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1504 {
1505 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getLong" );
1506 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1507 return m_xRow->getLong(columnIndex);
1508 }
1509 // -------------------------------------------------------------------------
getFloat(sal_Int32 columnIndex)1510 float SAL_CALL OKeySet::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1511 {
1512 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getFloat" );
1513 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1514 return m_xRow->getFloat(columnIndex);
1515 }
1516 // -------------------------------------------------------------------------
getDouble(sal_Int32 columnIndex)1517 double SAL_CALL OKeySet::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1518 {
1519 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getDouble" );
1520 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1521 return m_xRow->getDouble(columnIndex);
1522 }
1523 // -------------------------------------------------------------------------
getBytes(sal_Int32 columnIndex)1524 Sequence< sal_Int8 > SAL_CALL OKeySet::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1525 {
1526 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBytes" );
1527 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1528 return m_xRow->getBytes(columnIndex);
1529 }
1530 // -------------------------------------------------------------------------
getDate(sal_Int32 columnIndex)1531 ::com::sun::star::util::Date SAL_CALL OKeySet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1532 {
1533 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getDate" );
1534 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1535 return m_xRow->getDate(columnIndex);
1536 }
1537 // -------------------------------------------------------------------------
getTime(sal_Int32 columnIndex)1538 ::com::sun::star::util::Time SAL_CALL OKeySet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1539 {
1540 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getTime" );
1541 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1542 return m_xRow->getTime(columnIndex);
1543 }
1544 // -------------------------------------------------------------------------
getTimestamp(sal_Int32 columnIndex)1545 ::com::sun::star::util::DateTime SAL_CALL OKeySet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1546 {
1547 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getTimestamp" );
1548 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1549 return m_xRow->getTimestamp(columnIndex);
1550 }
1551 // -------------------------------------------------------------------------
getBinaryStream(sal_Int32 columnIndex)1552 Reference< ::com::sun::star::io::XInputStream > SAL_CALL OKeySet::getBinaryStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1553 {
1554 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBinaryStream" );
1555 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1556 return m_xRow->getBinaryStream(columnIndex);
1557 }
1558 // -------------------------------------------------------------------------
getCharacterStream(sal_Int32 columnIndex)1559 Reference< ::com::sun::star::io::XInputStream > SAL_CALL OKeySet::getCharacterStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1560 {
1561 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getCharacterStream" );
1562 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1563 return m_xRow->getCharacterStream(columnIndex);
1564 }
1565 // -------------------------------------------------------------------------
getObject(sal_Int32 columnIndex,const Reference<::com::sun::star::container::XNameAccess> & typeMap)1566 Any SAL_CALL OKeySet::getObject( sal_Int32 columnIndex, const Reference< ::com::sun::star::container::XNameAccess >& typeMap ) throw(SQLException, RuntimeException)
1567 {
1568 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getObject" );
1569 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1570 return m_xRow->getObject(columnIndex,typeMap);
1571 }
1572 // -------------------------------------------------------------------------
getRef(sal_Int32 columnIndex)1573 Reference< XRef > SAL_CALL OKeySet::getRef( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1574 {
1575 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getRef" );
1576 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1577 return m_xRow->getRef(columnIndex);
1578 }
1579 // -------------------------------------------------------------------------
getBlob(sal_Int32 columnIndex)1580 Reference< XBlob > SAL_CALL OKeySet::getBlob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1581 {
1582 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBlob" );
1583 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1584 return m_xRow->getBlob(columnIndex);
1585 }
1586 // -------------------------------------------------------------------------
getClob(sal_Int32 columnIndex)1587 Reference< XClob > SAL_CALL OKeySet::getClob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1588 {
1589 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getClob" );
1590 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1591 return m_xRow->getClob(columnIndex);
1592 }
1593 // -------------------------------------------------------------------------
getArray(sal_Int32 columnIndex)1594 Reference< XArray > SAL_CALL OKeySet::getArray( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1595 {
1596 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getArray" );
1597 OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
1598 return m_xRow->getArray(columnIndex);
1599 }
1600 // -------------------------------------------------------------------------
rowUpdated()1601 sal_Bool SAL_CALL OKeySet::rowUpdated( ) throw(SQLException, RuntimeException)
1602 {
1603 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::rowUpdated" );
1604 return m_aKeyIter != m_aKeyMap.begin() && m_aKeyIter != m_aKeyMap.end() && m_aKeyIter->second.second.first == 2;
1605 }
1606 // -------------------------------------------------------------------------
rowInserted()1607 sal_Bool SAL_CALL OKeySet::rowInserted( ) throw(SQLException, RuntimeException)
1608 {
1609 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::rowInserted" );
1610 return m_aKeyIter != m_aKeyMap.begin() && m_aKeyIter != m_aKeyMap.end() && m_aKeyIter->second.second.first == 1;
1611 }
1612 // -------------------------------------------------------------------------
rowDeleted()1613 sal_Bool SAL_CALL OKeySet::rowDeleted( ) throw(SQLException, RuntimeException)
1614 {
1615 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::rowDeleted" );
1616 sal_Bool bDeleted = m_bDeleted;
1617 m_bDeleted = sal_False;
1618 return bDeleted;
1619 }
1620 // -----------------------------------------------------------------------------
getComposedTableName(const::rtl::OUString & _sCatalog,const::rtl::OUString & _sSchema,const::rtl::OUString & _sTable)1621 ::rtl::OUString OKeySet::getComposedTableName(const ::rtl::OUString& _sCatalog,
1622 const ::rtl::OUString& _sSchema,
1623 const ::rtl::OUString& _sTable)
1624 {
1625 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getComposedTableName" );
1626 ::rtl::OUString aComposedName;
1627 Reference<XDatabaseMetaData> xMetaData = m_xConnection->getMetaData();
1628
1629 if( xMetaData.is() && xMetaData->supportsTableCorrelationNames() )
1630 {
1631 aComposedName = ::dbtools::composeTableName( xMetaData, _sCatalog, _sSchema, _sTable, sal_False, ::dbtools::eInDataManipulation );
1632 // first we have to check if the composed tablename is in the select clause or if an alias is used
1633 Reference<XTablesSupplier> xTabSup(m_xComposer,UNO_QUERY);
1634 Reference<XNameAccess> xSelectTables = xTabSup->getTables();
1635 OSL_ENSURE(xSelectTables.is(),"No Select tables!");
1636 if(xSelectTables.is())
1637 {
1638 if(!xSelectTables->hasByName(aComposedName))
1639 { // the composed name isn't used in the select clause so we have to find out which name is used instead
1640 ::rtl::OUString sCatalog,sSchema,sTable;
1641 ::dbtools::qualifiedNameComponents(xMetaData,m_sUpdateTableName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation);
1642 aComposedName = ::dbtools::composeTableNameForSelect( m_xConnection, sCatalog, sSchema, sTable );
1643 }
1644 else
1645 aComposedName = ::dbtools::composeTableNameForSelect( m_xConnection, _sCatalog, _sSchema, _sTable );
1646 }
1647 }
1648 else
1649 aComposedName = ::dbtools::composeTableNameForSelect( m_xConnection, _sCatalog, _sSchema, _sTable );
1650
1651 return aComposedName;
1652 }
1653 // -----------------------------------------------------------------------------
1654 namespace dbaccess
1655 {
1656
getColumnPositions(const Reference<XNameAccess> & _rxQueryColumns,const::com::sun::star::uno::Sequence<::rtl::OUString> & _aColumnNames,const::rtl::OUString & _rsUpdateTableName,SelectColumnsMetaData & o_rColumnNames,bool i_bAppendTableName)1657 void getColumnPositions(const Reference<XNameAccess>& _rxQueryColumns,
1658 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _aColumnNames,
1659 const ::rtl::OUString& _rsUpdateTableName,
1660 SelectColumnsMetaData& o_rColumnNames,
1661 bool i_bAppendTableName)
1662 {
1663 // get the real name of the columns
1664 Sequence< ::rtl::OUString> aSelNames(_rxQueryColumns->getElementNames());
1665 const ::rtl::OUString* pSelIter = aSelNames.getConstArray();
1666 const ::rtl::OUString* pSelEnd = pSelIter + aSelNames.getLength();
1667
1668 const ::rtl::OUString* pTblColumnIter = _aColumnNames.getConstArray();
1669 const ::rtl::OUString* pTblColumnEnd = pTblColumnIter + _aColumnNames.getLength();
1670
1671
1672 ::comphelper::UStringMixLess aTmp(o_rColumnNames.key_comp());
1673 ::comphelper::UStringMixEqual bCase(static_cast< ::comphelper::UStringMixLess*>(&aTmp)->isCaseSensitive());
1674
1675 for(sal_Int32 nPos = 1;pSelIter != pSelEnd;++pSelIter,++nPos)
1676 {
1677 Reference<XPropertySet> xQueryColumnProp(_rxQueryColumns->getByName(*pSelIter),UNO_QUERY_THROW);
1678 ::rtl::OUString sRealName,sTableName;
1679 OSL_ENSURE(xQueryColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME),"Property REALNAME not available!");
1680 OSL_ENSURE(xQueryColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME),"Property TABLENAME not available!");
1681 xQueryColumnProp->getPropertyValue(PROPERTY_REALNAME) >>= sRealName;
1682 xQueryColumnProp->getPropertyValue(PROPERTY_TABLENAME) >>= sTableName;
1683
1684 for(;pTblColumnIter != pTblColumnEnd;++pTblColumnIter)
1685 {
1686 if(bCase(sRealName,*pTblColumnIter) && bCase(_rsUpdateTableName,sTableName) && o_rColumnNames.find(*pTblColumnIter) == o_rColumnNames.end())
1687 {
1688 sal_Int32 nType = 0;
1689 xQueryColumnProp->getPropertyValue(PROPERTY_TYPE) >>= nType;
1690 sal_Int32 nScale = 0;
1691 xQueryColumnProp->getPropertyValue(PROPERTY_SCALE) >>= nScale;
1692 ::rtl::OUString sColumnDefault;
1693 if ( xQueryColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_DEFAULTVALUE) )
1694 xQueryColumnProp->getPropertyValue(PROPERTY_DEFAULTVALUE) >>= sColumnDefault;
1695
1696 sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN;
1697 OSL_VERIFY( xQueryColumnProp->getPropertyValue( PROPERTY_ISNULLABLE ) >>= nNullable );
1698
1699 if ( i_bAppendTableName )
1700 {
1701 ::rtl::OUStringBuffer sName;
1702 sName.append(sTableName);
1703 sName.appendAscii(".");
1704 sName.append(sRealName);
1705 SelectColumnDescription aColDesc( nPos, nType,nScale,nNullable != sdbc::ColumnValue::NO_NULLS, sColumnDefault );
1706 aColDesc.sRealName = sRealName;
1707 aColDesc.sTableName = sTableName;
1708 o_rColumnNames[sName.makeStringAndClear()] = aColDesc;
1709 }
1710 else
1711 o_rColumnNames[sRealName] = SelectColumnDescription( nPos, nType,nScale,nNullable != sdbc::ColumnValue::NO_NULLS, sColumnDefault );
1712
1713 break;
1714 }
1715 }
1716 pTblColumnIter = _aColumnNames.getConstArray();
1717 }
1718 }
1719 }
1720 // -----------------------------------------------------------------------------
impl_convertValue_throw(const ORowSetRow & _rInsertRow,const SelectColumnDescription & i_aMetaData)1721 void OKeySet::impl_convertValue_throw(const ORowSetRow& _rInsertRow,const SelectColumnDescription& i_aMetaData)
1722 {
1723 ORowSetValue& aValue((_rInsertRow->get())[i_aMetaData.nPosition]);
1724 switch(i_aMetaData.nType)
1725 {
1726 case DataType::DECIMAL:
1727 case DataType::NUMERIC:
1728 {
1729 ::rtl::OUString sValue = aValue.getString();
1730 sal_Int32 nIndex = sValue.indexOf('.');
1731 if ( nIndex != -1 )
1732 {
1733 aValue = sValue.copy(0,::std::min(sValue.getLength(),nIndex + (i_aMetaData.nScale > 0 ? i_aMetaData.nScale + 1 : 0)));
1734 }
1735 }
1736 break;
1737 default:
1738 break;
1739 }
1740 }
1741
1742 /* vim: set noet sw=4 ts=4: */
1743