Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/ucbhelper/source/provider/resultsetmetadata.cxx
Line
Count
Source (jump to first uncovered line)
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 <osl/diagnose.h>
21
#include <com/sun/star/beans/Property.hpp>
22
#include <com/sun/star/beans/XPropertySetInfo.hpp>
23
#include <com/sun/star/io/XInputStream.hpp>
24
#include <com/sun/star/sdbc/ColumnValue.hpp>
25
#include <com/sun/star/sdbc/DataType.hpp>
26
#include <com/sun/star/sdbc/XArray.hpp>
27
#include <com/sun/star/sdbc/XBlob.hpp>
28
#include <com/sun/star/sdbc/XClob.hpp>
29
#include <com/sun/star/sdbc/XRef.hpp>
30
#include <com/sun/star/util/Date.hpp>
31
#include <com/sun/star/util/Time.hpp>
32
#include <com/sun/star/util/DateTime.hpp>
33
#include <com/sun/star/ucb/PropertiesManager.hpp>
34
#include <ucbhelper/resultsetmetadata.hxx>
35
#include <mutex>
36
37
using namespace com::sun::star::beans;
38
using namespace com::sun::star::io;
39
using namespace com::sun::star::lang;
40
using namespace com::sun::star::sdbc;
41
using namespace com::sun::star::ucb;
42
using namespace com::sun::star::uno;
43
using namespace com::sun::star::util;
44
45
46
namespace ucbhelper_impl {
47
48
struct ResultSetMetaData_Impl
49
{
50
    std::mutex                                  m_aMutex;
51
    std::vector< ::ucbhelper::ResultSetColumnData > m_aColumnData;
52
    bool                                        m_bObtainedTypes;
53
54
    explicit ResultSetMetaData_Impl( sal_Int32 nSize )
55
0
    : m_aColumnData( nSize ), m_bObtainedTypes( false ) {}
56
57
    explicit ResultSetMetaData_Impl(
58
        std::vector< ::ucbhelper::ResultSetColumnData >&& rColumnData )
59
58.8k
    : m_aColumnData( std::move(rColumnData) ), m_bObtainedTypes( false ) {}
60
};
61
62
}
63
64
using namespace ucbhelper_impl;
65
66
namespace ucbhelper {
67
68
69
// ResultSetMetaData Implementation.
70
71
72
ResultSetMetaData::ResultSetMetaData(
73
                        const Reference< XComponentContext >& rxContext,
74
                        const Sequence< Property >& rProps )
75
0
: m_pImpl( new ResultSetMetaData_Impl( rProps.getLength() ) ),
76
0
  m_xContext( rxContext ),
77
0
  m_aProps( rProps )
78
0
{
79
0
}
80
81
82
ResultSetMetaData::ResultSetMetaData(
83
                        const Reference< XComponentContext >& rxContext,
84
                        const Sequence< Property >& rProps,
85
                        std::vector< ResultSetColumnData >&& rColumnData )
86
58.8k
: m_pImpl( new ResultSetMetaData_Impl( std::move(rColumnData) ) ),
87
58.8k
  m_xContext( rxContext ),
88
58.8k
  m_aProps( rProps )
89
58.8k
{
90
58.8k
    OSL_ENSURE( m_pImpl->m_aColumnData.size() == sal_uInt32( rProps.getLength() ),
91
58.8k
                "ResultSetMetaData ctor - different array sizes!" );
92
58.8k
}
93
94
95
// virtual
96
ResultSetMetaData::~ResultSetMetaData()
97
58.8k
{
98
58.8k
}
99
100
101
// XResultSetMetaData methods.
102
103
104
// virtual
105
sal_Int32 SAL_CALL ResultSetMetaData::getColumnCount()
106
0
{
107
0
    return m_aProps.getLength();
108
0
}
109
110
111
// virtual
112
sal_Bool SAL_CALL ResultSetMetaData::isAutoIncrement( sal_Int32 /*column*/ )
113
0
{
114
    /*
115
        Checks whether column is automatically numbered, which makes it
116
        read-only.
117
     */
118
0
    return false;
119
0
}
120
121
122
// virtual
123
sal_Bool SAL_CALL ResultSetMetaData::isCaseSensitive( sal_Int32 column )
124
58.8k
{
125
58.8k
    if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
126
0
        return false;
127
128
58.8k
    return m_pImpl->m_aColumnData[ column - 1 ].isCaseSensitive;
129
58.8k
}
130
131
132
// virtual
133
sal_Bool SAL_CALL ResultSetMetaData::isSearchable( sal_Int32 /*column*/ )
134
0
{
135
0
    return false;
136
0
}
137
138
139
// virtual
140
sal_Bool SAL_CALL ResultSetMetaData::isCurrency( sal_Int32 /*column*/ )
141
0
{
142
0
    return false;
143
0
}
144
145
146
// virtual
147
sal_Int32 SAL_CALL ResultSetMetaData::isNullable( sal_Int32 /*column*/ )
148
0
{
149
0
    return ColumnValue::NULLABLE;
150
0
}
151
152
153
// virtual
154
sal_Bool SAL_CALL ResultSetMetaData::isSigned( sal_Int32 /*column*/ )
155
0
{
156
0
    return false;
157
0
}
158
159
160
// virtual
161
sal_Int32 SAL_CALL ResultSetMetaData::getColumnDisplaySize( sal_Int32 /*column*/ )
162
0
{
163
    /*
164
        Gets the normal maximum width in characters for column.
165
     */
166
0
    return 16;
167
0
}
168
169
170
// virtual
171
OUString SAL_CALL ResultSetMetaData::getColumnLabel( sal_Int32 column )
172
0
{
173
    /*
174
        Gets the suggested column title for column, to be used in print-
175
        outs and displays.
176
     */
177
178
0
    if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
179
0
        return OUString();
180
181
0
    return m_aProps.getConstArray()[ column - 1 ].Name;
182
0
}
183
184
185
// virtual
186
OUString SAL_CALL ResultSetMetaData::getColumnName( sal_Int32 column )
187
58.8k
{
188
    /*
189
        Gets the name of column.
190
     */
191
192
58.8k
    if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
193
0
        return OUString();
194
195
58.8k
    return m_aProps.getConstArray()[ column - 1 ].Name;
196
58.8k
}
197
198
199
// virtual
200
OUString SAL_CALL ResultSetMetaData::getSchemaName( sal_Int32 /*column*/ )
201
0
{
202
    /*
203
        Gets the schema name for the table from which column of this
204
        result set was derived.
205
        Because this feature is not widely supported, the return value
206
        for many DBMSs will be an empty string.
207
     */
208
0
    return OUString();
209
0
}
210
211
212
// virtual
213
sal_Int32 SAL_CALL ResultSetMetaData::getPrecision( sal_Int32 /*column*/ )
214
0
{
215
0
    return -1;
216
0
}
217
218
219
// virtual
220
sal_Int32 SAL_CALL ResultSetMetaData::getScale( sal_Int32 /*column*/ )
221
0
{
222
0
    return 0;
223
0
}
224
225
226
// virtual
227
OUString SAL_CALL ResultSetMetaData::getTableName( sal_Int32 /*column*/ )
228
0
{
229
    /*
230
        Gets the name of the table from which column of this result set
231
        was derived or "" if there is none (for example, for a join).
232
        Because this feature is not widely supported, the return value
233
        for many DBMSs will be an empty string.
234
     */
235
0
    return OUString();
236
0
}
237
238
239
// virtual
240
OUString SAL_CALL ResultSetMetaData::getCatalogName( sal_Int32 /*column*/ )
241
0
{
242
    /*
243
        Gets the catalog name for the table from which column of this
244
        result set was derived.
245
        Because this feature is not widely supported, the return value
246
        for many DBMSs will be an empty string.
247
     */
248
0
    return OUString();
249
0
}
250
251
252
// virtual
253
sal_Int32 SAL_CALL ResultSetMetaData::getColumnType( sal_Int32 column )
254
58.8k
{
255
    /*
256
        Gets the JDBC type for the value stored in column. ... The STRUCT
257
        and DISTINCT type codes are always returned for structured and
258
        distinct types, regardless of whether the value will be mapped
259
        according to the standard mapping or be a custom mapping.
260
     */
261
262
58.8k
    if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
263
0
        return DataType::SQLNULL;
264
265
58.8k
    if ( m_aProps.getConstArray()[ column - 1 ].Type
266
58.8k
            == cppu::UnoType<void>::get() )
267
58.8k
    {
268
        // No type given. Try UCB's Properties Manager...
269
270
58.8k
        std::unique_lock aGuard( m_pImpl->m_aMutex );
271
272
58.8k
        if ( !m_pImpl->m_bObtainedTypes )
273
58.8k
        {
274
58.8k
            try
275
58.8k
            {
276
58.8k
                Reference< XPropertySetInfo > xInfo = PropertiesManager::create( m_xContext );
277
    // Less (remote) calls...
278
279
58.8k
                const Sequence< Property > aProps = xInfo->getProperties();
280
281
58.8k
                for ( Property& rProp : asNonConstRange(m_aProps) )
282
58.8k
                {
283
58.8k
                    auto pProp = std::find_if(aProps.begin(), aProps.end(),
284
4.88M
                        [&rProp](const Property& rProp1) { return rProp.Name == rProp1.Name; });
285
58.8k
                    if (pProp != aProps.end())
286
58.8k
                    {
287
                        // Found...
288
58.8k
                        rProp.Type = pProp->Type;
289
58.8k
                    }
290
58.8k
                }
291
58.8k
            }
292
58.8k
            catch ( RuntimeException& )
293
58.8k
            {
294
0
                throw;
295
0
            }
296
58.8k
            catch ( Exception& )
297
58.8k
            {
298
                // createInstance
299
0
            }
300
301
58.8k
            m_pImpl->m_bObtainedTypes = true;
302
58.8k
        }
303
58.8k
    }
304
305
58.8k
    const Type& rType = m_aProps.getConstArray()[ column - 1 ].Type;
306
58.8k
    sal_Int32 nType = DataType::OTHER;
307
308
58.8k
    if ( rType == cppu::UnoType<OUString>::get() )
309
58.8k
        nType = DataType::VARCHAR;  // XRow::getString
310
0
    else if ( rType == cppu::UnoType<bool>::get() )
311
0
        nType = DataType::BIT;      // XRow::getBoolean
312
0
    else if ( rType == cppu::UnoType<sal_Int32>::get() )
313
0
        nType = DataType::INTEGER;  // XRow::getInt
314
0
    else if ( rType == cppu::UnoType<sal_Int64>::get() )
315
0
        nType = DataType::BIGINT;   // XRow::getLong
316
0
    else if ( rType == cppu::UnoType<sal_Int16>::get() )
317
0
        nType = DataType::SMALLINT; // XRow::getShort
318
0
    else if ( rType == cppu::UnoType<sal_Int8>::get() )
319
0
        nType = DataType::TINYINT;  // XRow::getByte
320
0
    else if ( rType == cppu::UnoType<float>::get() )
321
0
        nType = DataType::REAL;     // XRow::getFloat
322
0
    else if ( rType == cppu::UnoType<double>::get() )
323
0
        nType = DataType::DOUBLE;   // XRow::getDouble
324
0
    else if ( rType == cppu::UnoType<Sequence<sal_Int8>>::get() )
325
0
        nType = DataType::VARBINARY;// XRow::getBytes
326
0
    else if ( rType == cppu::UnoType<Date>::get() )
327
0
        nType = DataType::DATE;     // XRow::getDate
328
0
    else if ( rType == cppu::UnoType<Time>::get() )
329
0
        nType = DataType::TIME;     // XRow::getTime
330
0
    else if ( rType == cppu::UnoType<DateTime>::get() )
331
0
        nType = DataType::TIMESTAMP;// XRow::getTimestamp
332
0
    else if ( rType == cppu::UnoType<XInputStream>::get() )
333
0
        nType = DataType::LONGVARBINARY;    // XRow::getBinaryStream
334
//      nType = DataType::LONGVARCHAR;      // XRow::getCharacterStream
335
0
    else if ( rType == cppu::UnoType<XClob>::get() )
336
0
        nType = DataType::CLOB; // XRow::getClob
337
0
    else if ( rType == cppu::UnoType<XBlob>::get() )
338
0
        nType = DataType::BLOB; // XRow::getBlob
339
0
    else if ( rType == cppu::UnoType<XArray>::get() )
340
0
        nType = DataType::ARRAY;// XRow::getArray
341
0
    else if ( rType == cppu::UnoType<XRef>::get() )
342
0
        nType = DataType::REF;// XRow::getRef
343
0
    else
344
0
        nType = DataType::OBJECT;// XRow::getObject
345
346
58.8k
    return nType;
347
58.8k
}
348
349
350
// virtual
351
OUString SAL_CALL ResultSetMetaData::getColumnTypeName( sal_Int32 /*column*/ )
352
0
{
353
    /*
354
        Gets the type name used by this particular data source for the
355
        values stored in column. If the type code for the type of value
356
        stored in column is STRUCT, DISTINCT or JAVA_OBJECT, this method
357
        returns a fully-qualified SQL type name.
358
     */
359
0
    return OUString();
360
0
}
361
362
363
// virtual
364
sal_Bool SAL_CALL ResultSetMetaData::isReadOnly( sal_Int32 /*column*/ )
365
0
{
366
0
    return true;
367
0
}
368
369
370
// virtual
371
sal_Bool SAL_CALL ResultSetMetaData::isWritable( sal_Int32 /*column*/ )
372
0
{
373
0
    return false;
374
0
}
375
376
377
// virtual
378
sal_Bool SAL_CALL ResultSetMetaData::isDefinitelyWritable( sal_Int32 /*column*/ )
379
0
{
380
0
    return false;
381
0
}
382
383
384
// virtual
385
OUString SAL_CALL ResultSetMetaData::getColumnServiceName( sal_Int32 /*column*/ )
386
0
{
387
    /*
388
          Returns the fully-qualified name of the service whose instances
389
         are manufactured if XResultSet::getObject is called to retrieve
390
        a value from the column.
391
     */
392
0
    return OUString();
393
0
}
394
395
} // namespace ucbhelper
396
397
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */