Coverage Report

Created: 2025-12-31 10:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/inc/dbmgr.hxx
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
#pragma once
20
21
#include <rtl/ustring.hxx>
22
#include <tools/solar.h>
23
#include <tools/long.hxx>
24
#include <i18nlangtag/lang.h>
25
#include <com/sun/star/util/Date.hpp>
26
#include "swdllapi.h"
27
#include "swdbdata.hxx"
28
#include <com/sun/star/uno/Reference.h>
29
#include <com/sun/star/uno/Sequence.hxx>
30
#include <com/sun/star/lang/Locale.hpp>
31
#include <com/sun/star/beans/PropertyValue.hpp>
32
33
#include <memory>
34
#include <utility>
35
#include <vector>
36
37
namespace com::sun::star{
38
    namespace sdbc{
39
        class XConnection;
40
        class XStatement;
41
        class XDataSource;
42
        class XResultSet;
43
    }
44
    namespace beans{
45
46
        class XPropertySet;
47
    }
48
    namespace sdbcx{
49
        class XColumnsSupplier;
50
    }
51
    namespace util{
52
        class XNumberFormatter;
53
    }
54
    namespace mail{
55
        class XSmtpService;
56
    }
57
    namespace embed { class XStorage; }
58
    namespace frame { class XStorable; }
59
}
60
namespace svx {
61
    class ODataAccessDescriptor;
62
}
63
64
struct SwDBFormatData
65
{
66
    css::util::Date aNullDate;
67
    css::uno::Reference< css::util::XNumberFormatter> xFormatter;
68
    css::lang::Locale aLocale;
69
};
70
71
namespace weld {
72
    class ComboBox;
73
    class Window;
74
}
75
76
class SwView;
77
class SwWrtShell;
78
class SvNumberFormatter;
79
class SwXMailMerge;
80
class SwMailMergeConfigItem;
81
class SwCalc;
82
class INetURLObject;
83
class SwDocShell;
84
85
enum DBManagerOptions
86
{
87
    DBMGR_MERGE,             ///< Data records in fields.
88
    DBMGR_MERGE_PRINTER,     ///< Print mail merge.
89
    DBMGR_MERGE_EMAIL,       ///< Send mail merge as email.
90
    DBMGR_MERGE_FILE,        ///< Save mail merge as files.
91
    DBMGR_MERGE_SHELL        ///< Create merge doc and keep the doc shell.
92
};
93
94
// Administration of (new) logical databases.
95
enum class SwDBSelect
96
{
97
    UNKNOWN, TABLE, QUERY
98
};
99
100
struct SwDSParam : public SwDBData
101
{
102
    css::util::Date  aNullDate;
103
104
    css::uno::Reference<css::util::XNumberFormatter>    xFormatter;
105
    css::uno::Reference< css::sdbc::XConnection>       xConnection;
106
    css::uno::Reference< css::sdbc::XStatement>        xStatement;
107
    css::uno::Reference< css::sdbc::XResultSet>        xResultSet;
108
    css::uno::Sequence<  css::uno::Any >               aSelection;
109
    bool bScrollable;
110
    bool bEndOfDB;
111
    tools::Long nSelectionIndex;
112
113
    SwDSParam(const SwDBData& rData) :
114
0
        SwDBData(rData),
115
0
        bScrollable(false),
116
0
        bEndOfDB(false),
117
0
        nSelectionIndex(0)
118
0
        {}
119
120
    SwDSParam(const SwDBData& rData,
121
        css::uno::Reference< css::sdbc::XResultSet> xResSet,
122
        const css::uno::Sequence<  css::uno::Any >&   rSelection) :
123
0
        SwDBData(rData),
124
0
        xResultSet(std::move(xResSet)),
125
0
        aSelection(rSelection),
126
0
        bScrollable(true),
127
0
        bEndOfDB(false),
128
0
        nSelectionIndex(0)
129
0
        {}
130
131
    bool HasValidRecord() const
132
0
        { return( !bEndOfDB && xResultSet.is() ); }
133
};
134
135
typedef std::vector<std::unique_ptr<SwDSParam>> SwDSParams_t;
136
137
struct SwMergeDescriptor
138
{
139
    const DBManagerOptions                              nMergeType;
140
    SwWrtShell&                                         rSh;
141
    const svx::ODataAccessDescriptor&                   rDescriptor;
142
143
    /**
144
     * Create a single or multiple results
145
     *
146
     * This currently just affects FILE, as EMAIL is always
147
     * multiple and SHELL and PRINTER are always single.
148
     */
149
    bool                                                bCreateSingleFile;
150
151
    /**
152
     * @defgroup save Export filter settings
153
     * @addtogroup save
154
     * @{ */
155
    OUString                                            sSaveToFilter;
156
    OUString                                            sSaveToFilterOptions;
157
    css::uno::Sequence< css::beans::PropertyValue >     aSaveToFilterData;
158
    /** @} */
159
160
    /**
161
     * @defgroup file Mail merge as File settings
162
     * @addtogroup file
163
     * @{ */
164
165
    /**
166
     * Basename incl. the path for the generated files.
167
     *
168
     * The final filename will be created by concatenating a number to prevent
169
     * overwriting an existing file and the extension based on the filter
170
     * settings.
171
     */
172
    OUString                                            sPrefix;
173
    /**
174
     * Use the sPrefix as the target filename also overwriting an existing
175
     * target file.
176
     *
177
     * Just used for the internal mail merge dialogs as mail merge never
178
     * overwrites existing files (see SwDBManager::ExecuteFormLetter).
179
     */
180
    bool                                                bPrefixIsFilename;
181
    /** @} */
182
183
    /**
184
     * @defgroup email Mail merge as eMail settings
185
     * @addtogroup email
186
     * @{ */
187
    OUString                                            sSubject;
188
    OUString                                            sMailBody;
189
    OUString                                            sAttachmentName;
190
    css::uno::Sequence< OUString >                      aCopiesTo;
191
    css::uno::Sequence< OUString >                      aBlindCopiesTo;
192
    css::uno::Reference< css::mail::XSmtpService >      xSmtpServer;
193
    bool                                                bSendAsHTML;
194
    bool                                                bSendAsAttachment;
195
    /** @} */
196
197
    /**
198
     * @addtogroup file email
199
     * @{ */
200
201
    /** DB column to fetch EMail of Filename from
202
     */
203
    OUString                                            sDBcolumn;
204
205
    /** DB column to fetch password
206
     */
207
    OUString                                            sDBPasswordColumn;
208
209
    /** @} */
210
211
    /**
212
     * @defgroup print Mail merge to Printer
213
     * @addtogroup print
214
     * @{ */
215
    css::uno::Sequence<  css::beans::PropertyValue >    aPrintOptions;
216
    /** @} */
217
218
    SwMailMergeConfigItem*                              pMailMergeConfigItem;
219
220
    SwMergeDescriptor( const DBManagerOptions nType,
221
                       SwWrtShell& rShell,
222
                       const svx::ODataAccessDescriptor& rDesc ) :
223
0
        nMergeType(nType),
224
0
        rSh(rShell),
225
0
        rDescriptor(rDesc),
226
0
        bCreateSingleFile( false ),
227
0
        bPrefixIsFilename( false ),
228
0
        bSendAsHTML( true ),
229
0
        bSendAsAttachment( false ),
230
0
        pMailMergeConfigItem( nullptr )
231
0
    {
232
0
        if( nType == DBMGR_MERGE_SHELL || nType == DBMGR_MERGE_PRINTER )
233
0
            bCreateSingleFile = true;
234
0
    }
235
};
236
237
class SwDoc;
238
239
class SwDBManager
240
{
241
    struct SwDBManager_Impl;
242
    class ConnectionDisposedListener_Impl;
243
    class MailDispatcherListener_Impl;
244
245
    enum class MergeStatus
246
    {
247
        Ok = 0, Cancel, Error
248
    };
249
250
    MergeStatus     m_aMergeStatus;     ///< current / last merge status
251
    bool            m_bInitDBFields : 1;
252
    bool            m_bInMerge    : 1;    ///< merge process active
253
    bool            m_bMergeSilent : 1;   ///< suppress display of dialogs/boxes (used when called over API)
254
    SwDSParams_t    m_DataSourceParams;
255
    std::unique_ptr<SwDBManager_Impl>  m_pImpl;
256
    const SwXMailMerge* m_pMergeEvtSrc;   ///< != 0 if mail merge events are to be send
257
    /// Name of the embedded database that's included in the current document.
258
    OUString     m_sEmbeddedName;
259
260
    /// Store last registrations to revoke or commit
261
    static std::vector<std::pair<SwDocShell*, OUString>> s_aUncommittedRegistrations;
262
263
    /// Not used connections.
264
    std::vector<OUString> m_aNotUsedConnections;
265
266
    /// Set connection as used.
267
    void SetAsUsed(const OUString& rName);
268
269
    /// The document that owns this manager.
270
    SwDoc* m_pDoc;
271
272
    SwDSParam*          FindDSData(const SwDBData& rData, bool bCreate);
273
    SwDSParam*          FindDSConnection(const OUString& rSource, bool bCreate);
274
275
    /// Insert data record as text into document.
276
    void ImportFromConnection( SwWrtShell* pSh);
277
278
    /// Insert a single data record as text into document.
279
    void ImportDBEntry(SwWrtShell* pSh);
280
281
    /// Run the mail merge for defined modes, except DBMGR_MERGE
282
    bool MergeMailFiles( SwWrtShell* pSh,
283
                                        const SwMergeDescriptor& rMergeDescriptor );
284
285
    bool ToNextMergeRecord();
286
    bool IsValidMergeRecord() const;
287
    void ImplDestroy();
288
289
    SwDBManager(SwDBManager const&) = delete;
290
    SwDBManager& operator=(SwDBManager const&) = delete;
291
292
public:
293
    SwDBManager(SwDoc* pDoc);
294
    ~SwDBManager();
295
296
    /// MailMergeEvent source
297
0
    const SwXMailMerge *    GetMailMergeEvtSrc() const  { return m_pMergeEvtSrc; }
298
0
    void SetMailMergeEvtSrc( const SwXMailMerge *pSrc ) { m_pMergeEvtSrc = pSrc; }
299
300
0
    bool     IsMergeSilent() const           { return m_bMergeSilent; }
301
0
    void     SetMergeSilent( bool bVal )     { m_bMergeSilent = bVal; }
302
303
    /// Merging of data records into fields.
304
    bool            Merge( const SwMergeDescriptor& rMergeDesc );
305
    void            MergeCancel();
306
307
0
    bool     IsMergeOk() const     { return MergeStatus::Ok     == m_aMergeStatus; }
308
0
    bool     IsMergeError() const  { return MergeStatus::Error  <= m_aMergeStatus; }
309
310
    SW_DLLPUBLIC static std::shared_ptr<SwMailMergeConfigItem> PerformMailMerge(SwView const * pView);
311
312
    /// Initialize data fields that lack name of database.
313
0
    bool     IsInitDBFields() const  { return m_bInitDBFields; }
314
0
    void     SetInitDBFields(bool b) { m_bInitDBFields = b;    }
315
316
    /// Fill listbox with all table names of a database.
317
    SW_DLLPUBLIC bool GetTableNames(weld::ComboBox& rBox, const OUString& rDBName);
318
319
    /// Fill listbox with all column names of a database table.
320
    SW_DLLPUBLIC void GetColumnNames(weld::ComboBox& rBox,
321
                            const OUString& rDBName, const OUString& rTableName);
322
    SW_DLLPUBLIC static void GetColumnNames(weld::ComboBox& rBox,
323
                            css::uno::Reference< css::sdbc::XConnection> const & xConnection,
324
                            const OUString& rTableName);
325
326
    static sal_uInt32 GetColumnFormat( css::uno::Reference< css::sdbc::XDataSource> const & xSource,
327
                            css::uno::Reference< css::sdbc::XConnection> const & xConnection,
328
                            css::uno::Reference< css::beans::XPropertySet> const & xColumn,
329
                            SvNumberFormatter* pNFormatr,
330
                            LanguageType nLanguage );
331
332
    sal_uInt32 GetColumnFormat( const OUString& rDBName,
333
                            const OUString& rTableName,
334
                            const OUString& rColNm,
335
                            SvNumberFormatter* pNFormatr,
336
                            LanguageType nLanguage );
337
    sal_Int32 GetColumnType( const OUString& rDBName,
338
                          const OUString& rTableName,
339
                          const OUString& rColNm );
340
341
0
    bool     IsInMerge() const   { return m_bInMerge; }
342
343
    void            ExecuteFormLetter(SwWrtShell& rSh,
344
                        const css::uno::Sequence< css::beans::PropertyValue>& rProperties);
345
346
    static void     InsertText(SwWrtShell& rSh,
347
                        const css::uno::Sequence< css::beans::PropertyValue>& rProperties);
348
349
    /// check if a data source is open
350
    bool            IsDataSourceOpen(const OUString& rDataSource,
351
                                    const OUString& rTableOrQuery, bool bMergeShell);
352
353
    /// open the source while fields are updated - for the calculator only!
354
    bool            OpenDataSource(const OUString& rDataSource, const OUString& rTableOrQuery);
355
    sal_uInt32      GetSelectedRecordId(const OUString& rDataSource, const OUString& rTableOrQuery, sal_Int32 nCommandType = -1);
356
    bool            GetColumnCnt(const OUString& rSourceName, const OUString& rTableName,
357
                            const OUString& rColumnName, sal_uInt32 nAbsRecordId, LanguageType nLanguage,
358
                            OUString& rResult, double* pNumber);
359
    /** create and store or find an already stored connection to a data source for use
360
    in SwFieldMgr and SwDBTreeList */
361
    SW_DLLPUBLIC css::uno::Reference<css::sdbc::XConnection> const&
362
                    RegisterConnection(OUString const& rSource);
363
364
    void            CreateDSData(const SwDBData& rData)
365
0
                        { FindDSData(rData, true); }
366
0
    const SwDSParams_t& GetDSParamArray() const { return m_DataSourceParams; }
367
368
    /// close all data sources - after fields were updated
369
    void            CloseAll(bool bIncludingMerge = true);
370
371
    bool            GetMergeColumnCnt(const OUString& rColumnName, LanguageType nLanguage,
372
                                      OUString &rResult, double *pNumber);
373
    bool            FillCalcWithMergeData(SvNumberFormatter *pDocFormatter,
374
                                          LanguageType nLanguage, SwCalc &aCalc);
375
    void            ToNextRecord(const OUString& rDataSource, const OUString& rTableOrQuery);
376
377
    sal_uInt32      GetSelectedRecordId();
378
    bool            ToRecordId(sal_Int32 nSet);
379
380
    static const SwDBData& GetAddressDBName();
381
382
    SW_DLLPUBLIC static OUString GetDBField(
383
                    css::uno::Reference< css::beans::XPropertySet > const & xColumnProp,
384
                    const SwDBFormatData& rDBFormatData,
385
                    double *pNumber = nullptr);
386
387
    static css::uno::Reference< css::sdbc::XConnection>
388
            GetConnection(const OUString& rDataSource,
389
                css::uno::Reference< css::sdbc::XDataSource>& rxSource,
390
                const SwView* pView);
391
392
    SW_DLLPUBLIC static css::uno::Reference< css::sdbcx::XColumnsSupplier>
393
            GetColumnSupplier(css::uno::Reference< css::sdbc::XConnection> const & xConnection,
394
                                    const OUString& rTableOrQuery,
395
                                    SwDBSelect eTableOrQuery = SwDBSelect::UNKNOWN);
396
397
    SW_DLLPUBLIC static css::uno::Sequence<OUString> GetExistingDatabaseNames();
398
399
    /**
400
     Loads a data source from file and registers it.
401
402
     This function requires GUI interaction, as it loads the data source from
403
     the filename returned by a file picker and additional settings dialog.
404
     In case of success it returns the registered name, otherwise an empty string.
405
     */
406
    SW_DLLPUBLIC static OUString LoadAndRegisterDataSource(weld::Window* pParent, SwDocShell* pDocShell = nullptr);
407
408
    /**
409
     Loads a data source from file and registers it.
410
411
     Convenience function, which calls GetDBunoURI and has just one mandatory parameter.
412
     In case of success it returns the registered name, otherwise an empty string.
413
     */
414
    SW_DLLPUBLIC static OUString LoadAndRegisterDataSource(std::u16string_view rURI, const OUString *pDestDir);
415
416
    /// Load the embedded data source of the document and also register it.
417
    void LoadAndRegisterEmbeddedDataSource(const SwDBData& rData, const SwDocShell& rDocShell);
418
419
    /// Unregister a data source.
420
    SW_DLLPUBLIC static void RevokeDataSource(const OUString& rName);
421
422
    /** try to get the data source from the given connection through the XChild interface.
423
        If this is not possible, the data source will be created through its name.
424
        @param _xConnection
425
            The connection which should support the XChild interface. (not a must)
426
        @param _sDataSourceName
427
            The data source name will be used to create the data source when the connection can not be used for it.
428
        @return
429
            The data source.
430
    */
431
    static css::uno::Reference< css::sdbc::XDataSource>
432
            getDataSourceAsParent(const css::uno::Reference< css::sdbc::XConnection>& _xConnection,const OUString& _sDataSourceName);
433
434
    /** creates a RowSet, which must be disposed after use.
435
        @param  _sDataSourceName
436
            The data source name
437
        @param  _sCommand
438
            The command.
439
        @param  _nCommandType
440
            The type of the command.
441
        @param  _xConnection
442
            The active connection which may be <NULL/>.
443
        @return
444
            The new created RowSet.
445
446
    */
447
    SW_DLLPUBLIC static css::uno::Reference< css::sdbc::XResultSet>
448
            createCursor(const OUString& _sDataSourceName,
449
                         const OUString& _sCommand,
450
                         sal_Int32 _nCommandType,
451
                         const css::uno::Reference< css::sdbc::XConnection>& _xConnection,
452
                         const SwView* pView);
453
454
    void setEmbeddedName(const OUString& rEmbeddedName, SwDocShell& rDocShell);
455
    const OUString& getEmbeddedName() const;
456
457
    // rOwnURL should be taken using INetURLObject::GetMainURL(INetURLObject::DecodeMechanism::NONE)
458
    static void StoreEmbeddedDataSource(const css::uno::Reference<css::frame::XStorable>& xStorable,
459
                                        const css::uno::Reference<css::embed::XStorage>& xStorage,
460
                                        const OUString& rStreamRelPath,
461
                                        const OUString& rOwnURL, bool bCopyTo = false);
462
463
    SwDoc* getDoc() const;
464
    /// Stop reacting to removed database registrations.
465
    void releaseRevokeListener();
466
467
    /// Revoke not committed registrations in case of mail merge cancel
468
    SW_DLLPUBLIC void RevokeLastRegistrations();
469
470
    /// Accept not committed registrations
471
    SW_DLLPUBLIC void CommitLastRegistrations();
472
473
    /// Remove not used connections.
474
    void RevokeNotUsedConnections();
475
};
476
477
namespace sw
478
{
479
enum class DBConnURIType
480
{
481
    UNKNOWN = 0,
482
    ODB,
483
    CALC,
484
    DBASE,
485
    FLAT,
486
    MSACE,
487
    WRITER
488
};
489
490
DBConnURIType SW_DLLPUBLIC GetDBunoType(const INetURLObject &rURL);
491
}
492
493
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */