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