1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sfx2/bindings.hxx>
21 #include <sfx2/viewfrm.hxx>
22 #include <svl/stritem.hxx>
23 #include <svl/itemset.hxx>
24 #include <sfx2/request.hxx>
25 #include <com/sun/star/sdb/CommandType.hpp>
26 #include <com/sun/star/sdbc/XDataSource.hpp>
27 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
28 #include <comphelper/types.hxx>
29 #include <sfx2/frame.hxx>
33 #include <svx/dataaccessdescriptor.hxx>
34 #include <osl/diagnose.h>
36 #include <vcl/svapp.hxx>
40 #include <swtypes.hxx>
43 #include <swabstdlg.hxx>
45 using namespace ::svx
;
46 using namespace ::com::sun::star
;
47 using namespace ::com::sun::star::uno
;
48 using namespace ::com::sun::star::sdb
;
49 using namespace ::com::sun::star::sdbc
;
50 using namespace ::com::sun::star::sdbcx
;
51 using namespace ::com::sun::star::frame
;
53 struct DBTextStruct_Impl
56 Sequence
<Any
> aSelection
;
57 Reference
<XResultSet
> xCursor
;
58 Reference
<XConnection
> xConnection
;
61 void SwTextShell::ExecDB(SfxRequest
const &rReq
)
63 const SfxItemSet
*pArgs
= rReq
.GetArgs();
64 SwDBManager
* pDBManager
= GetShell().GetDBManager();
65 OUString sSourceArg
, sCommandArg
;
66 sal_Int32 nCommandTypeArg
= 0;
67 const SfxUnoAnyItem
* pSourceItem
= nullptr;
68 const SfxUnoAnyItem
* pCommandItem
= nullptr;
69 const SfxUnoAnyItem
* pCommandTypeItem
= nullptr;
70 const SfxUnoAnyItem
* pConnectionItem
= nullptr;
72 // first get the selection of rows to be inserted
74 Sequence
<Any
> aSelection
;
75 if(const SfxUnoAnyItem
* pSelectionItem
= pArgs
->GetItemIfSet(FN_DB_DATA_SELECTION_ANY
, false))
76 pSelectionItem
->GetValue() >>= aSelection
;
78 // get the data source name
79 pSourceItem
= pArgs
->GetItemIfSet(FN_DB_DATA_SOURCE_ANY
, false);
81 pSourceItem
->GetValue() >>= sSourceArg
;
84 pCommandItem
= pArgs
->GetItemIfSet(FN_DB_DATA_COMMAND_ANY
, false);
86 pCommandItem
->GetValue() >>= sCommandArg
;
88 // get the command type
89 pCommandTypeItem
= pArgs
->GetItemIfSet(FN_DB_DATA_COMMAND_TYPE_ANY
, false);
91 pCommandTypeItem
->GetValue() >>= nCommandTypeArg
;
93 Reference
<XConnection
> xConnection
;
94 pConnectionItem
= pArgs
->GetItemIfSet(FN_DB_CONNECTION_ANY
, false);
96 pConnectionItem
->GetValue() >>= xConnection
;
97 // may be we even get no connection
98 if ( !xConnection
.is() )
100 Reference
<XDataSource
> xSource
;
101 SwView
&rSwView
= GetView();
102 xConnection
= SwDBManager::GetConnection(sSourceArg
, xSource
, &rSwView
);
104 if(!xConnection
.is())
107 // get the cursor, we use to travel, may be NULL
108 Reference
<XResultSet
> xCursor
;
109 if ( const SfxUnoAnyItem
* pCursorItem
= pArgs
->GetItemIfSet(FN_DB_DATA_CURSOR_ANY
, false) )
110 pCursorItem
->GetValue() >>= xCursor
;
112 switch (rReq
.GetSlot())
116 if(pSourceItem
&& pCommandItem
&& pCommandTypeItem
)
118 DBTextStruct_Impl
* pNew
= new DBTextStruct_Impl
;
119 pNew
->aDBData
.sDataSource
= sSourceArg
;
120 pNew
->aDBData
.sCommand
= sCommandArg
;
121 pNew
->aDBData
.nCommandType
= nCommandTypeArg
;
122 pNew
->aSelection
= aSelection
;
123 //if the cursor is NULL, it must be created inside InsertDBTextHdl
124 // because it called via a PostUserEvent
125 pNew
->xCursor
= xCursor
;
126 pNew
->xConnection
= xConnection
;
128 Application::PostUserEvent( LINK( this, SwBaseShell
, InsertDBTextHdl
), pNew
);
129 // the pNew will be removed in InsertDBTextHdl !!
134 case FN_QRY_MERGE_FIELD
:
136 // we don't get any cursor, so we must create our own
137 bool bDisposeResultSet
= false;
140 SwView
&rSwView
= GetView();
141 xCursor
= SwDBManager::createCursor(sSourceArg
,sCommandArg
,nCommandTypeArg
,xConnection
,&rSwView
);
142 bDisposeResultSet
= xCursor
.is();
145 ODataAccessDescriptor aDescriptor
;
146 aDescriptor
.setDataSource(sSourceArg
);
147 aDescriptor
[DataAccessDescriptorProperty::Command
] <<= sCommandArg
;
148 aDescriptor
[DataAccessDescriptorProperty::Cursor
] <<= xCursor
;
149 aDescriptor
[DataAccessDescriptorProperty::Selection
] <<= aSelection
;
150 aDescriptor
[DataAccessDescriptorProperty::CommandType
] <<= nCommandTypeArg
;
152 SwMergeDescriptor
aMergeDesc( DBMGR_MERGE
, *GetShellPtr(), aDescriptor
);
153 pDBManager
->Merge(aMergeDesc
);
155 if ( bDisposeResultSet
)
156 ::comphelper::disposeComponent(xCursor
);
160 case FN_QRY_INSERT_FIELD
:
162 const SfxUnoAnyItem
* pColumnItem
= pArgs
->GetItemIfSet(FN_DB_COLUMN_ANY
, false);
163 const SfxUnoAnyItem
* pColumnNameItem
=
164 pArgs
->GetItemIfSet(FN_DB_DATA_COLUMN_NAME_ANY
, false);
166 OUString sColumnName
;
168 pColumnNameItem
->GetValue() >>= sColumnName
;
169 OUString sDBName
= sSourceArg
+ OUStringChar(DB_DELIM
)
170 + sCommandArg
+ OUStringChar(DB_DELIM
)
171 + OUString::number(nCommandTypeArg
)
172 + OUStringChar(DB_DELIM
) + sColumnName
;
174 SwFieldMgr
aFieldMgr(GetShellPtr());
175 SwInsertField_Data
aData(SwFieldTypesEnum::Database
, 0, sDBName
, OUString(), 0);
177 aData
.m_aDBConnection
= pConnectionItem
->GetValue();
179 aData
.m_aDBColumn
= pColumnItem
->GetValue();
180 aFieldMgr
.InsertField(aData
);
181 SfxViewFrame
& rViewFrame
= GetView().GetViewFrame();
182 uno::Reference
< XDispatchRecorder
> xRecorder
=
183 rViewFrame
.GetBindings().GetRecorder();
184 if ( xRecorder
.is() )
186 SfxRequest
aReq(rViewFrame
, FN_INSERT_DBFIELD
);
187 aReq
.AppendItem( SfxUInt16Item(FN_PARAM_FIELD_TYPE
, static_cast<sal_uInt16
>(SwFieldTypesEnum::Database
)));
188 aReq
.AppendItem( SfxStringItem( FN_INSERT_DBFIELD
, sDBName
));
189 aReq
.AppendItem( SfxStringItem( FN_PARAM_1
, sCommandArg
));
190 aReq
.AppendItem( SfxStringItem( FN_PARAM_2
, sColumnName
));
191 aReq
.AppendItem( SfxInt32Item( FN_PARAM_3
, nCommandTypeArg
));
198 OSL_ENSURE(false, "wrong dispatcher");
203 IMPL_LINK( SwBaseShell
, InsertDBTextHdl
, void*, p
, void )
205 std::shared_ptr
<DBTextStruct_Impl
> pDBStruct(static_cast<DBTextStruct_Impl
*>(p
));
209 bool bDispose
= false;
210 Reference
< sdbc::XConnection
> xConnection
= pDBStruct
->xConnection
;
211 Reference
<XDataSource
> xSource
= SwDBManager::getDataSourceAsParent(xConnection
,pDBStruct
->aDBData
.sDataSource
);
212 // #111987# the connection is disposed and so no parent has been found
213 if(xConnection
.is() && !xSource
.is())
216 if ( !xConnection
.is() )
218 SwView
&rSwView
= GetView();
219 xConnection
= SwDBManager::GetConnection(pDBStruct
->aDBData
.sDataSource
, xSource
, &rSwView
);
223 Reference
< XColumnsSupplier
> xColSupp
;
225 xColSupp
= SwDBManager::GetColumnSupplier(xConnection
,
226 pDBStruct
->aDBData
.sCommand
,
227 pDBStruct
->aDBData
.nCommandType
== CommandType::QUERY
?
228 SwDBSelect::QUERY
: SwDBSelect::TABLE
);
233 ::comphelper::disposeComponent(xConnection
);
237 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
238 VclPtr
<AbstractSwInsertDBColAutoPilot
>pDlg (pFact
->CreateSwInsertDBColAutoPilot(GetView(),
241 pDBStruct
->aDBData
));
242 pDlg
->StartExecuteAsync(
243 [pDlg
, pDBStruct2
=std::move(pDBStruct
), xSource
, xConnection
, bDispose
] (sal_Int32 nResult
) mutable
245 if (nResult
== RET_OK
)
246 pDlg
->DataToDoc(pDBStruct2
->aSelection
, xSource
, xConnection
, pDBStruct2
->xCursor
);
249 ::comphelper::disposeComponent(xConnection
);
254 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */