Branch data Line data Source code
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 : :
21 : : #include "directsql.hxx"
22 : : #include "directsql.hrc"
23 : : #include "dbu_dlg.hrc"
24 : : #include <vcl/msgbox.hxx>
25 : : #include <comphelper/types.hxx>
26 : : #include <vcl/svapp.hxx>
27 : : #include <osl/mutex.hxx>
28 : : #include <tools/diagnose_ex.h>
29 : : #include <rtl/strbuf.hxx>
30 : : #include <com/sun/star/sdbc/XRow.hpp>
31 : :
32 : : //........................................................................
33 : : namespace dbaui
34 : : {
35 : : //........................................................................
36 : :
37 : : using namespace ::com::sun::star::uno;
38 : : using namespace ::com::sun::star::sdbc;
39 : : using namespace ::com::sun::star::lang;
40 : :
41 : : using ::rtl::OStringBuffer;
42 : :
43 : : //====================================================================
44 : : //= LargeEntryListBox
45 : : //====================================================================
46 [ # # ]: 0 : class LargeEntryListBox : public ListBox
47 : : {
48 : : public:
49 : : LargeEntryListBox( Window* _pParent, const ResId& _rId );
50 : :
51 : : protected:
52 : : virtual void UserDraw( const UserDrawEvent& rUDEvt );
53 : : };
54 : :
55 : : //--------------------------------------------------------------------
56 : 0 : LargeEntryListBox::LargeEntryListBox( Window* _pParent, const ResId& _rId )
57 : 0 : :ListBox(_pParent, _rId )
58 : : {
59 [ # # ]: 0 : EnableUserDraw(sal_True);
60 : 0 : }
61 : :
62 : : //--------------------------------------------------------------------
63 : 0 : void LargeEntryListBox::UserDraw( const UserDrawEvent& _rUDEvt )
64 : : {
65 [ # # ]: 0 : if (LISTBOX_ENTRY_NOTFOUND == _rUDEvt.GetItemId())
66 : 0 : ListBox::UserDraw( _rUDEvt );
67 : : else
68 [ # # ]: 0 : _rUDEvt.GetDevice()->DrawText( _rUDEvt.GetRect(), GetEntry( _rUDEvt.GetItemId() ), TEXT_DRAW_LEFT | TEXT_DRAW_VCENTER | TEXT_DRAW_ENDELLIPSIS);
69 : 0 : }
70 : :
71 : : //====================================================================
72 : : //= DirectSQLDialog
73 : : //====================================================================
74 : : DBG_NAME(DirectSQLDialog)
75 : : //--------------------------------------------------------------------
76 : 0 : DirectSQLDialog::DirectSQLDialog( Window* _pParent, const Reference< XConnection >& _rxConn )
77 : : :ModalDialog(_pParent, ModuleRes(DLG_DIRECTSQL))
78 : : ,m_aFrame (this, ModuleRes(FL_SQL))
79 : : ,m_aSQLLabel (this, ModuleRes(FT_SQL))
80 : : ,m_aSQL (this, ModuleRes(ME_SQL))
81 : : ,m_aExecute (this, ModuleRes(PB_EXECUTE))
82 : : ,m_aHistoryLabel (this, ModuleRes(FT_HISTORY))
83 [ # # ]: 0 : ,m_pSQLHistory(new LargeEntryListBox(this, ModuleRes(LB_HISTORY)))
84 : : ,m_aStatusFrame (this, ModuleRes(FL_STATUS))
85 : : ,m_aStatus (this, ModuleRes(ME_STATUS))
86 [ # # ]: 0 : ,m_pShowOutput(new CheckBox(this, ModuleRes(CB_SHOWOUTPUT)))
87 : : ,m_aOutputFrame (this, ModuleRes(FL_OUTPUT))
88 : : ,m_aOutput (this, ModuleRes(ME_OUTPUT))
89 : : ,m_aButtonSeparator (this, ModuleRes(FL_BUTTONS))
90 : : ,m_aHelp (this, ModuleRes(PB_HELP))
91 : : ,m_aClose (this, ModuleRes(PB_CLOSE))
92 : : ,m_nHistoryLimit(20)
93 : : ,m_nStatusCount(1)
94 [ # # ][ # # ]: 0 : ,m_xConnection(_rxConn)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
95 : : {
96 : : DBG_CTOR(DirectSQLDialog,NULL);
97 : :
98 [ # # ]: 0 : FreeResource();
99 : :
100 [ # # ]: 0 : m_aSQL.GrabFocus();
101 : :
102 [ # # ]: 0 : m_aExecute.SetClickHdl(LINK(this, DirectSQLDialog, OnExecute));
103 [ # # ]: 0 : m_aClose.SetClickHdl(LINK(this, DirectSQLDialog, OnClose));
104 [ # # ]: 0 : m_pSQLHistory->SetSelectHdl(LINK(this, DirectSQLDialog, OnListEntrySelected));
105 [ # # ]: 0 : m_pSQLHistory->SetDropDownLineCount(10);
106 : :
107 : : // add a dispose listener to the connection
108 [ # # ]: 0 : Reference< XComponent > xConnComp(m_xConnection, UNO_QUERY);
109 : : OSL_ENSURE(xConnComp.is(), "DirectSQLDialog::DirectSQLDialog: invalid connection!");
110 [ # # ]: 0 : if (xConnComp.is())
111 [ # # ]: 0 : startComponentListening(xConnComp);
112 : :
113 [ # # ]: 0 : m_aSQL.SetModifyHdl(LINK(this, DirectSQLDialog, OnStatementModified));
114 [ # # ]: 0 : OnStatementModified(&m_aSQL);
115 : 0 : }
116 : :
117 : : //--------------------------------------------------------------------
118 [ # # ][ # # ]: 0 : DirectSQLDialog::~DirectSQLDialog()
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
119 : : {
120 : : {
121 [ # # ]: 0 : ::osl::MutexGuard aGuard(m_aMutex);
122 [ # # ][ # # ]: 0 : stopAllComponentListening();
123 : : }
124 [ # # ][ # # ]: 0 : delete m_pSQLHistory;
125 : :
126 : : DBG_DTOR(DirectSQLDialog,NULL);
127 [ # # ]: 0 : }
128 : :
129 : : //--------------------------------------------------------------------
130 : 0 : void DirectSQLDialog::_disposing( const EventObject& _rSource )
131 : : {
132 [ # # ]: 0 : SolarMutexGuard aSolarGuard;
133 [ # # ]: 0 : ::osl::MutexGuard aGuard(m_aMutex);
134 : :
135 : : OSL_ENSURE(Reference< XConnection >(_rSource.Source, UNO_QUERY).get() == m_xConnection.get(),
136 : : "DirectSQLDialog::_disposing: where does this come from?");
137 : : (void)_rSource;
138 : :
139 : : {
140 [ # # ][ # # ]: 0 : String sMessage(ModuleRes(STR_DIRECTSQL_CONNECTIONLOST));
141 [ # # ]: 0 : ErrorBox aError(this, WB_OK, sMessage);
142 [ # # ][ # # ]: 0 : aError.Execute();
[ # # ]
143 : : }
144 : :
145 [ # # ][ # # ]: 0 : PostUserEvent(LINK(this, DirectSQLDialog, OnClose));
[ # # ][ # # ]
146 : 0 : }
147 : :
148 : : //--------------------------------------------------------------------
149 : 0 : sal_Int32 DirectSQLDialog::getHistorySize() const
150 : : {
151 : : CHECK_INVARIANTS("DirectSQLDialog::getHistorySize");
152 : 0 : return m_aStatementHistory.size();
153 : : }
154 : :
155 : : //--------------------------------------------------------------------
156 : 0 : void DirectSQLDialog::implEnsureHistoryLimit()
157 : : {
158 : : CHECK_INVARIANTS("DirectSQLDialog::implEnsureHistoryLimit");
159 : :
160 [ # # ]: 0 : if (getHistorySize() <= m_nHistoryLimit)
161 : : // nothing to do
162 : 0 : return;
163 : :
164 : 0 : sal_Int32 nRemoveEntries = getHistorySize() - m_nHistoryLimit;
165 [ # # ]: 0 : while (nRemoveEntries--)
166 : : {
167 : 0 : m_aStatementHistory.pop_front();
168 : 0 : m_aNormalizedHistory.pop_front();
169 : 0 : m_pSQLHistory->RemoveEntry((sal_uInt16)0);
170 : : }
171 : : }
172 : :
173 : : //--------------------------------------------------------------------
174 : 0 : void DirectSQLDialog::implAddToStatementHistory(const String& _rStatement)
175 : : {
176 : : CHECK_INVARIANTS("DirectSQLDialog::implAddToStatementHistory");
177 : :
178 : : // add the statement to the history
179 [ # # ]: 0 : m_aStatementHistory.push_back(_rStatement);
180 : :
181 : : // normalize the statement, and remember the normalized form, too
182 [ # # ]: 0 : String sNormalized(_rStatement);
183 [ # # ]: 0 : sNormalized.SearchAndReplaceAll((sal_Unicode)'\n', ' ');
184 [ # # ]: 0 : m_aNormalizedHistory.push_back(sNormalized);
185 : :
186 : : // add the normalized version to the list box
187 [ # # ]: 0 : m_pSQLHistory->InsertEntry(sNormalized);
188 : :
189 : : // ensure that we don't exceed the history limit
190 [ # # ][ # # ]: 0 : implEnsureHistoryLimit();
191 : 0 : }
192 : :
193 : : #ifdef DBG_UTIL
194 : : //--------------------------------------------------------------------
195 : : const sal_Char* DirectSQLDialog::impl_CheckInvariants() const
196 : : {
197 : : if (m_aStatementHistory.size() != m_aNormalizedHistory.size())
198 : : return "statement history is inconsistent!";
199 : :
200 : : if (!m_pSQLHistory)
201 : : return "invalid listbox!";
202 : :
203 : : if (m_aStatementHistory.size() != m_pSQLHistory->GetEntryCount())
204 : : return "invalid listbox entry count!";
205 : :
206 : : if (!m_xConnection.is())
207 : : return "have no connection!";
208 : :
209 : : return NULL;
210 : : }
211 : : #endif
212 : :
213 : : //--------------------------------------------------------------------
214 : 0 : void DirectSQLDialog::implExecuteStatement(const String& _rStatement)
215 : : {
216 : : CHECK_INVARIANTS("DirectSQLDialog::implExecuteStatement");
217 : :
218 [ # # ]: 0 : ::osl::MutexGuard aGuard(m_aMutex);
219 : :
220 [ # # ]: 0 : String sStatus;
221 : 0 : ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > xResultSet;
222 : : try
223 : : {
224 : : // create a statement
225 [ # # ][ # # ]: 0 : Reference< XStatement > xStatement = m_xConnection->createStatement();
226 : : OSL_ENSURE(xStatement.is(), "DirectSQLDialog::implExecuteStatement: no statement returned by the connection!");
227 : :
228 : : // clear the output box
229 [ # # ][ # # ]: 0 : m_aOutput.SetText(rtl::OUString());
[ # # ]
230 [ # # ]: 0 : if (xStatement.is())
231 : : {
232 [ # # ][ # # ]: 0 : if (::rtl::OUString(_rStatement).toAsciiUpperCase().compareTo(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT")),6)==0 && m_pShowOutput->IsChecked())
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # # # ]
233 : : {
234 : : // execute it as a query
235 [ # # ][ # # ]: 0 : xResultSet = xStatement->executeQuery(_rStatement);
[ # # ][ # # ]
236 : : // get a handle for the rows
237 [ # # ]: 0 : ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow > xRow( xResultSet, ::com::sun::star::uno::UNO_QUERY );
238 : : // work through each of the rows
239 [ # # ][ # # ]: 0 : while (xResultSet->next())
[ # # ]
240 : : {
241 : : // initialise the output line for each row
242 [ # # ][ # # ]: 0 : String out = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(""));
243 : : // work along the columns until that are none left
244 : 0 : int i = 1;
245 : : try
246 : : {
247 : 0 : for (;;)
248 : : {
249 : : // be dumb, treat everything as a string
250 [ # # ][ # # ]: 0 : out += xRow->getString(i) + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(","));
[ # # ][ # # ]
[ # # ]
251 : 0 : i++;
252 : : }
253 : : }
254 : : // trap for when we fall off the end of the row
255 [ # # ]: 0 : catch (const SQLException&)
256 : : {
257 : : }
258 : : // report the output
259 [ # # # # : 0 : addOutputText(::rtl::OUString(out));
# # # # ]
260 [ # # ]: 0 : }
261 : : } else {
262 : : // execute it
263 [ # # ][ # # ]: 0 : xStatement->execute(_rStatement);
[ # # ]
264 : : }
265 : : }
266 : :
267 : : // successfull
268 [ # # ][ # # ]: 0 : sStatus = String(ModuleRes(STR_COMMAND_EXECUTED_SUCCESSFULLY));
[ # # ][ # # ]
269 : :
270 : : // dispose the statement
271 [ # # ]: 0 : ::comphelper::disposeComponent(xStatement);
272 : : }
273 [ # # # # : 0 : catch(const SQLException& e)
# ]
274 : : {
275 [ # # ]: 0 : sStatus = e.Message;
276 : : }
277 [ # # ]: 0 : catch( const Exception& )
278 : : {
279 : : DBG_UNHANDLED_EXCEPTION();
280 : : }
281 : :
282 : : // add the status text
283 [ # # ][ # # ]: 0 : addStatusText(sStatus);
[ # # ]
284 : 0 : }
285 : :
286 : : //--------------------------------------------------------------------
287 : 0 : void DirectSQLDialog::addStatusText(const String& _rMessage)
288 : : {
289 [ # # ]: 0 : String sAppendMessage = String::CreateFromInt32(m_nStatusCount++);
290 [ # # ]: 0 : sAppendMessage += rtl::OUString(": ");
291 [ # # ]: 0 : sAppendMessage += _rMessage;
292 [ # # ]: 0 : sAppendMessage += rtl::OUString("\n\n");
293 : :
294 [ # # ]: 0 : String sCompleteMessage = m_aStatus.GetText();
295 [ # # ]: 0 : sCompleteMessage += sAppendMessage;
296 [ # # ]: 0 : m_aStatus.SetText(sCompleteMessage);
297 : :
298 [ # # ][ # # ]: 0 : m_aStatus.SetSelection(Selection(sCompleteMessage.Len(), sCompleteMessage.Len()));
[ # # ]
299 : 0 : }
300 : :
301 : : //--------------------------------------------------------------------
302 : 0 : void DirectSQLDialog::addOutputText(const String& _rMessage)
303 : : {
304 [ # # ]: 0 : String sAppendMessage = _rMessage;
305 [ # # ]: 0 : sAppendMessage += rtl::OUString("\n");
306 : :
307 [ # # ]: 0 : String sCompleteMessage = m_aOutput.GetText();
308 [ # # ]: 0 : sCompleteMessage += sAppendMessage;
309 [ # # ][ # # ]: 0 : m_aOutput.SetText(sCompleteMessage);
[ # # ]
310 : 0 : }
311 : :
312 : : //--------------------------------------------------------------------
313 : 0 : void DirectSQLDialog::executeCurrent()
314 : : {
315 : : CHECK_INVARIANTS("DirectSQLDialog::executeCurrent");
316 : :
317 [ # # ]: 0 : String sStatement = m_aSQL.GetText();
318 : :
319 : : // execute
320 [ # # ]: 0 : implExecuteStatement(sStatement);
321 : :
322 : : // add the statement to the history
323 [ # # ]: 0 : implAddToStatementHistory(sStatement);
324 : :
325 [ # # ]: 0 : m_aSQL.SetSelection(Selection());
326 [ # # ][ # # ]: 0 : m_aSQL.GrabFocus();
327 : 0 : }
328 : :
329 : : //--------------------------------------------------------------------
330 : 0 : void DirectSQLDialog::switchToHistory(sal_Int32 _nHistoryPos, sal_Bool _bUpdateListBox)
331 : : {
332 : : CHECK_INVARIANTS("DirectSQLDialog::switchToHistory");
333 : :
334 [ # # ][ # # ]: 0 : if ((_nHistoryPos >= 0) && (_nHistoryPos < getHistorySize()))
[ # # ]
335 : : {
336 : : // set the text in the statement editor
337 [ # # ][ # # ]: 0 : String sStatement = m_aStatementHistory[_nHistoryPos];
338 [ # # ]: 0 : m_aSQL.SetText(sStatement);
339 [ # # ]: 0 : OnStatementModified(&m_aSQL);
340 : :
341 [ # # ]: 0 : if (_bUpdateListBox)
342 : : {
343 : : // selecte the normalized statement in the list box
344 [ # # ]: 0 : m_pSQLHistory->SelectEntryPos((sal_uInt16)_nHistoryPos);
345 : : OSL_ENSURE(m_pSQLHistory->GetSelectEntry() == m_aNormalizedHistory[_nHistoryPos],
346 : : "DirectSQLDialog::switchToHistory: inconsistent listbox entries!");
347 : : }
348 : :
349 [ # # ]: 0 : m_aSQL.GrabFocus();
350 [ # # ][ # # ]: 0 : m_aSQL.SetSelection(Selection(sStatement.Len(), sStatement.Len()));
351 : : }
352 : : else
353 : : OSL_FAIL("DirectSQLDialog::switchToHistory: invalid position!");
354 : 0 : }
355 : :
356 : : //--------------------------------------------------------------------
357 : 0 : IMPL_LINK( DirectSQLDialog, OnStatementModified, void*, /*NOTINTERESTEDIN*/ )
358 : : {
359 [ # # ]: 0 : m_aExecute.Enable(0 != m_aSQL.GetText().Len());
360 : 0 : return 0L;
361 : : }
362 : :
363 : : //--------------------------------------------------------------------
364 : 0 : IMPL_LINK( DirectSQLDialog, OnClose, void*, /*NOTINTERESTEDIN*/ )
365 : : {
366 : 0 : EndDialog( RET_OK );
367 : 0 : return 0L;
368 : : }
369 : :
370 : : //--------------------------------------------------------------------
371 : 0 : IMPL_LINK( DirectSQLDialog, OnExecute, void*, /*NOTINTERESTEDIN*/ )
372 : : {
373 : 0 : executeCurrent();
374 : 0 : return 0L;
375 : : }
376 : :
377 : : //--------------------------------------------------------------------
378 : 0 : IMPL_LINK( DirectSQLDialog, OnListEntrySelected, void*, /*NOTINTERESTEDIN*/ )
379 : : {
380 [ # # ]: 0 : if (!m_pSQLHistory->IsTravelSelect())
381 : : {
382 : 0 : const sal_uInt16 nSelected = m_pSQLHistory->GetSelectEntryPos();
383 [ # # ]: 0 : if (LISTBOX_ENTRY_NOTFOUND != nSelected)
384 : 0 : switchToHistory(nSelected, sal_False);
385 : : }
386 : 0 : return 0L;
387 : : }
388 : :
389 : : //........................................................................
390 : : } // namespace dbaui
391 : : //........................................................................
392 : :
393 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|