Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/ucb/source/ucp/file/filrset.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <sal/config.h>
21
#include <sal/log.hxx>
22
23
#include <com/sun/star/sdbc/SQLException.hpp>
24
#include <com/sun/star/ucb/ListenerAlreadySetException.hpp>
25
#include <com/sun/star/ucb/ServiceNotFoundException.hpp>
26
#include <com/sun/star/ucb/WelcomeDynamicResultSetStruct.hpp>
27
#include "filid.hxx"
28
#include "filtask.hxx"
29
#include "filprp.hxx"
30
#include "filrset.hxx"
31
#include <com/sun/star/ucb/OpenMode.hpp>
32
#include "prov.hxx"
33
#include <com/sun/star/uno/Reference.h>
34
35
#include <com/sun/star/beans/PropertyAttribute.hpp>
36
#include <com/sun/star/ucb/ListActionType.hpp>
37
#include <com/sun/star/ucb/XSourceInitialization.hpp>
38
#include <com/sun/star/ucb/CachedDynamicResultSetStubFactory.hpp>
39
#include <ucbhelper/resultsetmetadata.hxx>
40
41
using namespace fileaccess;
42
using namespace com::sun::star;
43
44
XResultSet_impl::XResultSet_impl( TaskManager* pMyShell,
45
                                  const OUString& aUnqPath,
46
                                  sal_Int32 OpenMode,
47
                                  const uno::Sequence< beans::Property >& seq,
48
                                  const uno::Sequence< ucb::NumberedSortingInfo >& seqSort )
49
116k
    : m_pMyShell( pMyShell )
50
116k
    , m_nRow( -1 )
51
116k
    , m_nWasNull ( false )
52
116k
    , m_nOpenMode( OpenMode )
53
116k
    , m_bRowCountFinal( false )
54
116k
    , m_aBaseDirectory( aUnqPath )
55
116k
    , m_aFolder( aUnqPath )
56
116k
    , m_sProperty( seq )
57
116k
    , m_sSortingInfo( seqSort )
58
116k
    , m_nErrorCode( TaskHandlerErr::NO_ERROR )
59
116k
    , m_nMinorErrorCode( 0 )
60
116k
{
61
116k
    osl::FileBase::RC err = m_aFolder.open();
62
116k
    if(  err != osl::FileBase::E_None )
63
0
    {
64
0
        m_nIsOpen = false;
65
0
        m_aFolder.close();
66
67
0
        m_nErrorCode = TaskHandlerErr::OPEN_FOR_DIRECTORYLISTING;
68
0
        m_nMinorErrorCode = err;
69
0
    }
70
116k
    else
71
116k
        m_nIsOpen = true;
72
116k
}
73
74
75
XResultSet_impl::~XResultSet_impl()
76
116k
{
77
116k
    if( m_nIsOpen )
78
52.8k
        m_aFolder.close();
79
116k
}
80
81
82
void SAL_CALL
83
XResultSet_impl::disposing( const lang::EventObject& )
84
0
{
85
    // To do, but what
86
0
}
87
88
89
void SAL_CALL
90
XResultSet_impl::addEventListener(
91
    const uno::Reference< lang::XEventListener >& Listener )
92
0
{
93
0
    std::unique_lock aGuard( m_aMutex );
94
95
0
    m_aDisposeEventListeners.addInterface( aGuard, Listener );
96
0
}
97
98
99
void SAL_CALL
100
XResultSet_impl::removeEventListener(
101
    const uno::Reference< lang::XEventListener >& Listener )
102
0
{
103
0
    std::unique_lock aGuard( m_aMutex );
104
105
0
    m_aDisposeEventListeners.removeInterface( aGuard, Listener );
106
0
}
107
108
109
void SAL_CALL
110
XResultSet_impl::dispose()
111
0
{
112
0
    std::unique_lock aGuard( m_aMutex );
113
114
0
    lang::EventObject aEvt;
115
0
    aEvt.Source = static_cast< lang::XComponent * >( this );
116
117
0
    m_aDisposeEventListeners.disposeAndClear( aGuard, aEvt );
118
0
    m_aRowCountListeners.disposeAndClear( aGuard, aEvt );
119
0
    m_aIsFinalListeners.disposeAndClear( aGuard, aEvt );
120
0
}
121
122
123
void XResultSet_impl::rowCountChanged(std::unique_lock<std::mutex>& rGuard)
124
105k
{
125
105k
    sal_Int32 aNewValue = m_aItems.size();
126
105k
    sal_Int32 aOldValue = aNewValue-1;
127
105k
    beans::PropertyChangeEvent aEv;
128
105k
    aEv.PropertyName = "RowCount";
129
105k
    aEv.Further = false;
130
105k
    aEv.PropertyHandle = -1;
131
105k
    aEv.OldValue <<= aOldValue;
132
105k
    aEv.NewValue <<= aNewValue;
133
105k
    m_aRowCountListeners.notifyEach(rGuard, &beans::XPropertyChangeListener::propertyChange, aEv);
134
105k
}
135
136
137
void XResultSet_impl::isFinalChanged(std::unique_lock<std::mutex>& rGuard)
138
63.3k
{
139
63.3k
    m_bRowCountFinal = true;
140
63.3k
    beans::PropertyChangeEvent aEv;
141
63.3k
    aEv.PropertyName = "IsRowCountFinal";
142
63.3k
    aEv.Further = false;
143
63.3k
    aEv.PropertyHandle = -1;
144
63.3k
    aEv.OldValue <<= false;
145
63.3k
    aEv.NewValue <<= true;
146
63.3k
    m_aIsFinalListeners.notifyEach(rGuard, &beans::XPropertyChangeListener::propertyChange, aEv);
147
63.3k
}
148
149
150
bool
151
XResultSet_impl::OneMore(std::unique_lock<std::mutex>& rGuard)
152
232k
{
153
232k
    if( ! m_nIsOpen )
154
63.3k
        return false;
155
156
168k
    osl::FileBase::RC err;
157
168k
    bool IsRegular;
158
168k
    OUString aUnqPath;
159
168k
    osl::DirectoryItem  aDirIte;
160
168k
    uno::Reference< sdbc::XRow > aRow;
161
162
168k
    while( true )
163
168k
    {
164
168k
        err = m_aFolder.getNextItem( aDirIte );
165
166
168k
        if( err == osl::FileBase::E_NOENT || err == osl::FileBase::E_INVAL )
167
63.3k
        {
168
63.3k
            m_aFolder.close();
169
63.3k
            isFinalChanged(rGuard);
170
63.3k
            m_nIsOpen = false;
171
63.3k
            return m_nIsOpen;
172
63.3k
        }
173
105k
        else if( err == osl::FileBase::E_None )
174
105k
        {
175
105k
            if (!m_pMyShell->getv( m_sProperty, aDirIte, aUnqPath, IsRegular, aRow ))
176
0
            {
177
0
                SAL_WARN(
178
0
                    "ucb.ucp.file",
179
0
                    "getting dir item in <" << m_aBaseDirectory << "> failed");
180
0
                continue;
181
0
            }
182
183
105k
            if( m_nOpenMode == ucb::OpenMode::DOCUMENTS && IsRegular )
184
105k
            {
185
105k
                m_aItems.push_back( aRow );
186
105k
                m_aIdents.emplace_back( );
187
105k
                m_aUnqPath.push_back( aUnqPath );
188
105k
                rowCountChanged(rGuard);
189
105k
                return true;
190
191
105k
            }
192
0
            else if( m_nOpenMode == ucb::OpenMode::DOCUMENTS && ! IsRegular )
193
0
            {
194
0
                continue;
195
0
            }
196
0
            else if( m_nOpenMode == ucb::OpenMode::FOLDERS && ! IsRegular )
197
0
            {
198
0
                m_aItems.push_back( aRow );
199
0
                m_aIdents.emplace_back( );
200
0
                m_aUnqPath.push_back( aUnqPath );
201
0
                rowCountChanged(rGuard);
202
0
                return true;
203
0
            }
204
0
            else if( m_nOpenMode == ucb::OpenMode::FOLDERS && IsRegular )
205
0
            {
206
0
                continue;
207
0
            }
208
0
            else
209
0
            {
210
0
                m_aItems.push_back( aRow );
211
0
                m_aIdents.emplace_back( );
212
0
                m_aUnqPath.push_back( aUnqPath );
213
0
                rowCountChanged(rGuard);
214
0
                return true;
215
0
            }
216
105k
        }
217
0
        else  // error fetching anything
218
0
        {
219
0
            throw sdbc::SQLException( u""_ustr, uno::Reference< uno::XInterface >(), OUString(), 0, uno::Any() );
220
0
        }
221
168k
    }
222
168k
}
223
224
225
sal_Bool SAL_CALL
226
XResultSet_impl::next()
227
42.2k
{
228
42.2k
    std::unique_lock aGuard( m_aMutex );
229
42.2k
    bool test;
230
42.2k
    if( ++m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) test = true;
231
42.2k
    else
232
42.2k
        test = OneMore(aGuard);
233
42.2k
    return test;
234
42.2k
}
235
236
237
sal_Bool SAL_CALL
238
XResultSet_impl::isBeforeFirst()
239
0
{
240
0
    return m_nRow == -1;
241
0
}
242
243
244
sal_Bool SAL_CALL
245
XResultSet_impl::isAfterLast()
246
0
{
247
0
    return m_nRow >= sal::static_int_cast<sal_Int32>(m_aItems.size());   // Cannot happen, if m_aFolder.isOpen()
248
0
}
249
250
251
sal_Bool SAL_CALL
252
XResultSet_impl::isFirst()
253
0
{
254
0
    return m_nRow == 0;
255
0
}
256
257
258
sal_Bool SAL_CALL
259
XResultSet_impl::isLast()
260
0
{
261
0
    std::unique_lock aGuard( m_aMutex );
262
0
    if( m_nRow ==  sal::static_int_cast<sal_Int32>(m_aItems.size()) - 1 )
263
0
        return ! OneMore(aGuard);
264
0
    else
265
0
        return false;
266
0
}
267
268
269
void SAL_CALL
270
XResultSet_impl::beforeFirst()
271
147k
{
272
147k
    m_nRow = -1;
273
147k
}
274
275
276
void SAL_CALL
277
XResultSet_impl::afterLast()
278
0
{
279
0
    std::unique_lock aGuard( m_aMutex );
280
0
    m_nRow = sal::static_int_cast<sal_Int32>(m_aItems.size());
281
0
    while( OneMore(aGuard) )
282
0
        ++m_nRow;
283
0
}
284
285
286
sal_Bool SAL_CALL
287
XResultSet_impl::first()
288
0
{
289
0
    m_nRow = -1;
290
0
    return next();
291
0
}
292
293
294
sal_Bool SAL_CALL
295
XResultSet_impl::last()
296
0
{
297
0
    std::unique_lock aGuard( m_aMutex );
298
0
    m_nRow = sal::static_int_cast<sal_Int32>(m_aItems.size()) - 1;
299
0
    while( OneMore(aGuard) )
300
0
        ++m_nRow;
301
0
    return true;
302
0
}
303
304
305
sal_Int32 SAL_CALL
306
XResultSet_impl::getRow()
307
0
{
308
    // Test, whether behind last row
309
0
    if( -1 == m_nRow || m_nRow >= sal::static_int_cast<sal_Int32>(m_aItems.size()) )
310
0
        return 0;
311
0
    else
312
0
        return m_nRow+1;
313
0
}
314
315
316
sal_Bool SAL_CALL XResultSet_impl::absolute( sal_Int32 row )
317
189k
{
318
189k
    std::unique_lock aGuard( m_aMutex );
319
189k
    if( row >= 0 )
320
189k
    {
321
189k
        m_nRow = row - 1;
322
189k
        if( row >= sal::static_int_cast<sal_Int32>(m_aItems.size()) )
323
253k
            while( row-- && OneMore(aGuard) )
324
63.3k
                ;
325
189k
    }
326
0
    else
327
0
    {
328
0
        last();
329
0
        m_nRow += ( row + 1 );
330
0
        if( m_nRow < -1 )
331
0
            m_nRow = -1;
332
0
    }
333
334
189k
    return 0<= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size());
335
189k
}
336
337
338
sal_Bool SAL_CALL
339
XResultSet_impl::relative( sal_Int32 row )
340
0
{
341
0
    if( isAfterLast() || isBeforeFirst() )
342
0
        throw sdbc::SQLException( u""_ustr, uno::Reference< uno::XInterface >(), OUString(), 0, uno::Any() );
343
0
    if( row > 0 )
344
0
        while( row-- ) next();
345
0
    else if( row < 0 )
346
0
        while( row++ && m_nRow > - 1 ) previous();
347
348
0
    return 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size());
349
0
}
350
351
352
sal_Bool SAL_CALL
353
XResultSet_impl::previous()
354
0
{
355
0
    if( m_nRow > sal::static_int_cast<sal_Int32>(m_aItems.size()) )
356
0
        m_nRow = sal::static_int_cast<sal_Int32>(m_aItems.size());  // Correct Handling of afterLast
357
0
    if( 0 <= m_nRow ) -- m_nRow;
358
359
0
    return 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size());
360
0
}
361
362
363
void SAL_CALL
364
XResultSet_impl::refreshRow()
365
0
{
366
    // get the row from the filesystem
367
0
}
368
369
370
sal_Bool SAL_CALL
371
XResultSet_impl::rowUpdated()
372
0
{
373
0
    return false;
374
0
}
375
376
sal_Bool SAL_CALL
377
XResultSet_impl::rowInserted()
378
0
{
379
0
    return false;
380
0
}
381
382
sal_Bool SAL_CALL
383
XResultSet_impl::rowDeleted()
384
0
{
385
0
    return false;
386
0
}
387
388
389
uno::Reference< uno::XInterface > SAL_CALL
390
XResultSet_impl::getStatement()
391
0
{
392
0
    return uno::Reference< uno::XInterface >();
393
0
}
394
395
396
// XCloseable
397
398
void SAL_CALL
399
XResultSet_impl::close()
400
0
{
401
0
    std::unique_lock aGuard( m_aMutex );
402
0
    if( m_nIsOpen )
403
0
    {
404
0
        m_aFolder.close();
405
0
        isFinalChanged(aGuard);
406
0
        m_nIsOpen = false;
407
0
    }
408
0
}
409
410
411
OUString SAL_CALL
412
XResultSet_impl::queryContentIdentifierString()
413
42.2k
{
414
42.2k
    uno::Reference< ucb::XContentIdentifier > xContentId
415
42.2k
        = queryContentIdentifier();
416
417
42.2k
    if( xContentId.is() )
418
42.2k
        return xContentId->getContentIdentifier();
419
0
    else
420
0
        return OUString();
421
42.2k
}
422
423
424
uno::Reference< ucb::XContentIdentifier > SAL_CALL
425
XResultSet_impl::queryContentIdentifier()
426
42.2k
{
427
42.2k
    std::unique_lock aGuard( m_aMutex );
428
42.2k
    if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
429
42.2k
    {
430
42.2k
        if( ! m_aIdents[m_nRow].is() )
431
42.2k
        {
432
42.2k
            m_aIdents[m_nRow].set( new FileContentIdentifier( m_aUnqPath[  m_nRow ] ) );
433
42.2k
        }
434
42.2k
        return m_aIdents[m_nRow];
435
42.2k
    }
436
0
    return uno::Reference< ucb::XContentIdentifier >();
437
42.2k
}
438
439
440
uno::Reference< ucb::XContent > SAL_CALL
441
XResultSet_impl::queryContent()
442
0
{
443
0
    if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
444
0
        return m_pMyShell->m_pProvider->queryContent( queryContentIdentifier() );
445
0
    else
446
0
        return uno::Reference< ucb::XContent >();
447
0
}
448
449
450
// XDynamicResultSet
451
452
453
// virtual
454
uno::Reference< sdbc::XResultSet > SAL_CALL
455
XResultSet_impl::getStaticResultSet()
456
105k
{
457
105k
    std::unique_lock aGuard( m_aMutex );
458
459
105k
    if ( m_xListener.is() )
460
0
        throw ucb::ListenerAlreadySetException();
461
462
105k
    return uno::Reference< sdbc::XResultSet >( this );
463
105k
}
464
465
466
// virtual
467
void SAL_CALL
468
XResultSet_impl::setListener(
469
    const uno::Reference< ucb::XDynamicResultSetListener >& Listener )
470
0
{
471
0
    std::unique_lock aGuard( m_aMutex );
472
473
0
    if ( m_xListener.is() )
474
0
        throw ucb::ListenerAlreadySetException();
475
476
0
    m_xListener = Listener;
477
478
479
    // Create "welcome event" and send it to listener.
480
481
482
    // Note: We only have the implementation for a static result set at the
483
    //       moment (src590). The dynamic result sets passed to the listener
484
    //       are a fake. This implementation will never call "notify" at the
485
    //       listener to propagate any changes!!!
486
487
0
    uno::Any aInfo;
488
0
    aInfo <<= ucb::WelcomeDynamicResultSetStruct( this, /* "old" */
489
0
                                                  this /* "new" */ );
490
491
0
    uno::Sequence< ucb::ListAction > aActions( 1 );
492
0
    aActions.getArray()[ 0 ] = ucb::ListAction( 0, // Position; not used
493
0
                                                0, // Count; not used
494
0
                                                ucb::ListActionType::WELCOME,
495
0
                                                aInfo );
496
0
    aGuard.unlock();
497
498
0
    Listener->notify(
499
0
        ucb::ListEvent(
500
0
            getXWeak(), aActions ) );
501
0
}
502
503
504
// virtual
505
void SAL_CALL
506
XResultSet_impl::connectToCache(
507
    const uno::Reference< ucb::XDynamicResultSet > & xCache )
508
0
{
509
0
    {
510
0
        std::unique_lock aGuard( m_aMutex );
511
0
        if( m_xListener.is() )
512
0
            throw ucb::ListenerAlreadySetException();
513
0
    }
514
0
    uno::Reference< ucb::XSourceInitialization > xTarget(
515
0
        xCache, uno::UNO_QUERY );
516
0
    if( xTarget.is() && m_pMyShell->m_xContext.is() )
517
0
    {
518
0
        uno::Reference< ucb::XCachedDynamicResultSetStubFactory > xStubFactory;
519
0
        try
520
0
        {
521
0
            xStubFactory
522
0
                = ucb::CachedDynamicResultSetStubFactory::create(
523
0
                    m_pMyShell->m_xContext );
524
0
        }
525
0
        catch ( uno::Exception const & )
526
0
        {
527
0
        }
528
529
0
        if( xStubFactory.is() )
530
0
        {
531
0
            xStubFactory->connectToCache(
532
0
                this, xCache,m_sSortingInfo, nullptr );
533
0
            return;
534
0
        }
535
0
    }
536
0
    throw ucb::ServiceNotFoundException();
537
0
}
538
539
540
// virtual
541
sal_Int16 SAL_CALL
542
XResultSet_impl::getCapabilities()
543
0
{
544
    // Never set ucb::ContentResultSetCapability::SORTED
545
    //  - Underlying content cannot provide sorted data...
546
0
    return 0;
547
0
}
548
549
// XResultSetMetaDataSupplier
550
uno::Reference< sdbc::XResultSetMetaData > SAL_CALL
551
XResultSet_impl::getMetaData()
552
63.3k
{
553
63.3k
    auto pProp = std::find_if(std::cbegin(m_sProperty), std::cend(m_sProperty),
554
63.3k
        [](const beans::Property& rProp) { return rProp.Name == "Title"; });
555
63.3k
    if (pProp != std::cend(m_sProperty))
556
63.3k
    {
557
63.3k
        std::vector< ::ucbhelper::ResultSetColumnData >
558
63.3k
                                aColumnData( m_sProperty.getLength() );
559
63.3k
        auto n = std::distance(std::cbegin(m_sProperty), pProp);
560
        // @@@ #82177# - Determine correct value!
561
63.3k
        aColumnData[ n ].isCaseSensitive = false;
562
563
63.3k
        return new ::ucbhelper::ResultSetMetaData(
564
63.3k
                m_pMyShell->m_xContext,
565
63.3k
                m_sProperty,
566
63.3k
                std::move(aColumnData) );
567
63.3k
    }
568
569
0
    return new ::ucbhelper::ResultSetMetaData( m_pMyShell->m_xContext, m_sProperty );
570
63.3k
}
571
572
573
// XPropertySet
574
uno::Reference< beans::XPropertySetInfo > SAL_CALL
575
XResultSet_impl::getPropertySetInfo()
576
0
{
577
578
0
    uno::Sequence< beans::Property > seq
579
0
    {
580
0
        { u"RowCount"_ustr, -1, cppu::UnoType<sal_Int32>::get(), beans::PropertyAttribute::READONLY },
581
0
        { u"IsRowCountFinal"_ustr, -1, cppu::UnoType<sal_Bool>::get(), beans::PropertyAttribute::READONLY }
582
0
    };
583
584
0
    return new XPropertySetInfo_impl( m_pMyShell, seq );
585
0
}
586
587
588
void SAL_CALL XResultSet_impl::setPropertyValue(
589
    const OUString& aPropertyName, const uno::Any& )
590
0
{
591
0
    if( aPropertyName == "IsRowCountFinal" ||
592
0
        aPropertyName == "RowCount" )
593
0
        return;
594
0
    throw beans::UnknownPropertyException( aPropertyName );
595
0
}
596
597
598
uno::Any SAL_CALL XResultSet_impl::getPropertyValue(
599
    const OUString& PropertyName )
600
0
{
601
0
    std::unique_lock aGuard( m_aMutex );
602
0
    if( PropertyName == "IsRowCountFinal" )
603
0
    {
604
0
        return uno::Any(m_bRowCountFinal);
605
0
    }
606
0
    else if ( PropertyName == "RowCount" )
607
0
    {
608
0
        sal_Int32 count = sal::static_int_cast<sal_Int32>(m_aItems.size());
609
0
        return uno::Any(count);
610
0
    }
611
0
    else
612
0
        throw beans::UnknownPropertyException( PropertyName );
613
0
}
614
615
616
void SAL_CALL XResultSet_impl::addPropertyChangeListener(
617
    const OUString& aPropertyName,
618
    const uno::Reference< beans::XPropertyChangeListener >& xListener )
619
0
{
620
0
    if( aPropertyName == "IsRowCountFinal" )
621
0
    {
622
0
        std::unique_lock aGuard( m_aMutex );
623
624
0
        m_aIsFinalListeners.addInterface( aGuard, xListener );
625
0
    }
626
0
    else if ( aPropertyName == "RowCount" )
627
0
    {
628
0
        std::unique_lock aGuard( m_aMutex );
629
630
0
        m_aRowCountListeners.addInterface( aGuard, xListener );
631
0
    }
632
0
    else
633
0
        throw beans::UnknownPropertyException( aPropertyName );
634
0
}
635
636
637
void SAL_CALL XResultSet_impl::removePropertyChangeListener(
638
    const OUString& aPropertyName,
639
    const uno::Reference< beans::XPropertyChangeListener >& aListener )
640
0
{
641
0
    if( aPropertyName == "IsRowCountFinal" )
642
0
    {
643
0
        std::unique_lock aGuard( m_aMutex );
644
645
0
        m_aIsFinalListeners.removeInterface( aGuard, aListener );
646
0
    }
647
0
    else if ( aPropertyName == "RowCount" )
648
0
    {
649
0
        std::unique_lock aGuard( m_aMutex );
650
651
0
        m_aRowCountListeners.removeInterface( aGuard, aListener );
652
0
    }
653
0
    else
654
0
        throw beans::UnknownPropertyException( aPropertyName );
655
0
}
656
657
void SAL_CALL XResultSet_impl::addVetoableChangeListener(
658
    const OUString&,
659
    const uno::Reference< beans::XVetoableChangeListener >& )
660
0
{
661
0
}
662
663
664
void SAL_CALL XResultSet_impl::removeVetoableChangeListener(
665
    const OUString&,
666
    const uno::Reference< beans::XVetoableChangeListener >& )
667
0
{
668
0
}
669
670
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */