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 : #include "tabletree.hxx"
21 : #include "imageprovider.hxx"
22 : #include "moduledbu.hxx"
23 : #include "dbu_control.hrc"
24 : #include <vcl/layout.hxx>
25 : #include <vcl/menu.hxx>
26 : #include <vcl/builderfactory.hxx>
27 : #include <connectivity/dbtools.hxx>
28 : #include <comphelper/types.hxx>
29 : #include "dbustrings.hrc"
30 : #include <com/sun/star/sdb/application/DatabaseObject.hpp>
31 : #include <com/sun/star/sdb/application/DatabaseObjectContainer.hpp>
32 : #include <com/sun/star/sdbc/XDriverAccess.hpp>
33 : #include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
34 : #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
35 : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
36 : #include <com/sun/star/sdb/SQLContext.hpp>
37 : #include <com/sun/star/sdbc/XRow.hpp>
38 : #include <com/sun/star/beans/XPropertySet.hpp>
39 : #include "commontypes.hxx"
40 : #include "listviewitems.hxx"
41 : #include <tools/diagnose_ex.h>
42 : #include <osl/diagnose.h>
43 : #include <rtl/ustrbuf.hxx>
44 : #include <connectivity/dbmetadata.hxx>
45 : #include "svtools/treelistentry.hxx"
46 :
47 : #include <algorithm>
48 : #include <o3tl/compat_functional.hxx>
49 :
50 : namespace dbaui
51 : {
52 :
53 : using namespace ::com::sun::star::uno;
54 : using namespace ::com::sun::star::sdb;
55 : using namespace ::com::sun::star::lang;
56 : using namespace ::com::sun::star::sdbc;
57 : using namespace ::com::sun::star::sdbcx;
58 : using namespace ::com::sun::star::beans;
59 : using namespace ::com::sun::star::container;
60 : using namespace ::com::sun::star::sdb::application;
61 :
62 : using namespace ::dbtools;
63 : using namespace ::comphelper;
64 :
65 : namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject;
66 : namespace DatabaseObjectContainer = ::com::sun::star::sdb::application::DatabaseObjectContainer;
67 :
68 : // OTableTreeListBox
69 0 : OTableTreeListBox::OTableTreeListBox(vcl::Window* pParent, WinBits nWinStyle)
70 : :OMarkableTreeListBox(pParent, nWinStyle)
71 0 : ,m_xImageProvider( new ImageProvider )
72 : ,m_bVirtualRoot(false)
73 0 : ,m_bNoEmptyFolders( false )
74 : {
75 0 : implSetDefaultImages();
76 0 : }
77 :
78 0 : VCL_BUILDER_DECL_FACTORY(OTableTreeListBox)
79 : {
80 0 : WinBits nWinStyle = 0;
81 0 : OString sBorder = VclBuilder::extractCustomProperty(rMap);
82 0 : if (!sBorder.isEmpty())
83 0 : nWinStyle |= WB_BORDER;
84 0 : rRet = VclPtr<OTableTreeListBox>::Create(pParent, nWinStyle);
85 0 : }
86 :
87 0 : void OTableTreeListBox::implSetDefaultImages()
88 : {
89 0 : ImageProvider aImageProvider;
90 0 : SetDefaultExpandedEntryBmp( ImageProvider::getFolderImage( DatabaseObject::TABLE ) );
91 0 : SetDefaultCollapsedEntryBmp( ImageProvider::getFolderImage( DatabaseObject::TABLE ) );
92 0 : }
93 :
94 0 : bool OTableTreeListBox::isFolderEntry( const SvTreeListEntry* _pEntry )
95 : {
96 0 : sal_Int32 nEntryType = reinterpret_cast< sal_IntPtr >( _pEntry->GetUserData() );
97 0 : if ( ( nEntryType == DatabaseObjectContainer::TABLES )
98 0 : || ( nEntryType == DatabaseObjectContainer::CATALOG )
99 0 : || ( nEntryType == DatabaseObjectContainer::SCHEMA )
100 : )
101 0 : return true;
102 0 : return false;
103 : }
104 :
105 0 : void OTableTreeListBox::notifyHiContrastChanged()
106 : {
107 0 : implSetDefaultImages();
108 :
109 0 : SvTreeListEntry* pEntryLoop = First();
110 0 : while (pEntryLoop)
111 : {
112 0 : size_t nCount = pEntryLoop->ItemCount();
113 0 : for (size_t i=0;i<nCount;++i)
114 : {
115 0 : SvLBoxItem* pItem = pEntryLoop->GetItem(i);
116 0 : if (pItem && pItem->GetType() == SV_ITEM_ID_LBOXCONTEXTBMP)
117 : {
118 0 : SvLBoxContextBmp* pContextBitmapItem = static_cast< SvLBoxContextBmp* >( pItem );
119 :
120 0 : Image aImage;
121 0 : if ( isFolderEntry( pEntryLoop ) )
122 : {
123 0 : aImage = ImageProvider::getFolderImage( DatabaseObject::TABLE );
124 : }
125 : else
126 : {
127 0 : OUString sCompleteName( getQualifiedTableName( pEntryLoop ) );
128 0 : m_xImageProvider->getImages( sCompleteName, DatabaseObject::TABLE, aImage );
129 : }
130 :
131 0 : pContextBitmapItem->SetBitmap1( aImage );
132 0 : pContextBitmapItem->SetBitmap2( aImage );
133 0 : break;
134 : }
135 : }
136 0 : pEntryLoop = Next(pEntryLoop);
137 : }
138 0 : }
139 :
140 0 : void OTableTreeListBox::implOnNewConnection( const Reference< XConnection >& _rxConnection )
141 : {
142 0 : m_xConnection = _rxConnection;
143 0 : m_xImageProvider.reset( new ImageProvider( m_xConnection ) );
144 0 : }
145 :
146 0 : void OTableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConnection ) throw(SQLException)
147 : {
148 0 : Sequence< OUString > sTables, sViews;
149 :
150 0 : OUString sCurrentActionError;
151 : try
152 : {
153 0 : Reference< XTablesSupplier > xTableSupp( _rxConnection, UNO_QUERY_THROW );
154 0 : sCurrentActionError = ModuleRes(STR_NOTABLEINFO);
155 :
156 0 : Reference< XNameAccess > xTables,xViews;
157 :
158 0 : Reference< XViewsSupplier > xViewSupp( _rxConnection, UNO_QUERY );
159 0 : if ( xViewSupp.is() )
160 : {
161 0 : xViews = xViewSupp->getViews();
162 0 : if (xViews.is())
163 0 : sViews = xViews->getElementNames();
164 : }
165 :
166 0 : xTables = xTableSupp->getTables();
167 0 : if (xTables.is())
168 0 : sTables = xTables->getElementNames();
169 : }
170 0 : catch(RuntimeException&)
171 : {
172 : OSL_FAIL("OTableTreeListBox::UpdateTableList : caught an RuntimeException!");
173 : }
174 0 : catch ( const SQLException& )
175 : {
176 0 : throw;
177 : }
178 0 : catch(Exception&)
179 : {
180 : // a non-SQLException exception occurred ... simply throw an SQLException
181 0 : SQLException aInfo;
182 0 : aInfo.Message = sCurrentActionError;
183 0 : throw aInfo;
184 : }
185 :
186 0 : UpdateTableList( _rxConnection, sTables, sViews );
187 0 : }
188 :
189 : namespace
190 : {
191 0 : struct OViewSetter : public ::std::unary_function< OTableTreeListBox::TNames::value_type, bool>
192 : {
193 : const Sequence< OUString> m_aViews;
194 : ::comphelper::UStringMixEqual m_aEqualFunctor;
195 :
196 0 : OViewSetter(const Sequence< OUString>& _rViews,bool _bCase) : m_aViews(_rViews),m_aEqualFunctor(_bCase){}
197 0 : OTableTreeListBox::TNames::value_type operator() (const OUString& lhs)
198 : {
199 0 : OTableTreeListBox::TNames::value_type aRet;
200 0 : aRet.first = lhs;
201 0 : const OUString* pIter = m_aViews.getConstArray();
202 0 : const OUString* pEnd = m_aViews.getConstArray() + m_aViews.getLength();
203 0 : aRet.second = ::std::any_of(pIter,pEnd,::std::bind2nd(m_aEqualFunctor,lhs));
204 :
205 0 : return aRet;
206 : }
207 : };
208 :
209 : }
210 :
211 0 : void OTableTreeListBox::UpdateTableList(
212 : const Reference< XConnection >& _rxConnection,
213 : const Sequence< OUString>& _rTables,
214 : const Sequence< OUString>& _rViews
215 : )
216 : {
217 0 : TNames aTables;
218 0 : aTables.resize(_rTables.getLength());
219 0 : const OUString* pIter = _rTables.getConstArray();
220 0 : const OUString* pEnd = _rTables.getConstArray() + _rTables.getLength();
221 : try
222 : {
223 0 : Reference< XDatabaseMetaData > xMeta( _rxConnection->getMetaData(), UNO_QUERY_THROW );
224 : ::std::transform( pIter, pEnd,
225 0 : aTables.begin(), OViewSetter( _rViews, xMeta->supportsMixedCaseQuotedIdentifiers() ) );
226 : }
227 0 : catch(Exception&)
228 : {
229 : DBG_UNHANDLED_EXCEPTION();
230 : }
231 0 : UpdateTableList( _rxConnection, aTables );
232 0 : }
233 :
234 : namespace
235 : {
236 0 : ::std::vector< OUString > lcl_getMetaDataStrings_throw( const Reference< XResultSet >& _rxMetaDataResult, sal_Int32 _nColumnIndex )
237 : {
238 0 : ::std::vector< OUString > aStrings;
239 0 : Reference< XRow > xRow( _rxMetaDataResult, UNO_QUERY_THROW );
240 0 : while ( _rxMetaDataResult->next() )
241 0 : aStrings.push_back( xRow->getString( _nColumnIndex ) );
242 0 : return aStrings;
243 : }
244 :
245 0 : bool lcl_shouldDisplayEmptySchemasAndCatalogs( const Reference< XConnection >& _rxConnection )
246 : {
247 0 : ::dbtools::DatabaseMetaData aMetaData( _rxConnection );
248 0 : return aMetaData.displayEmptyTableFolders();
249 : }
250 : }
251 :
252 0 : void OTableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConnection, const TNames& _rTables )
253 : {
254 0 : implOnNewConnection( _rxConnection );
255 :
256 : // throw away all the old stuff
257 0 : Clear();
258 :
259 : try
260 : {
261 0 : if (haveVirtualRoot())
262 : {
263 0 : OUString sRootEntryText;
264 0 : if ( ::std::none_of(_rTables.begin(),_rTables.end(),
265 0 : ::o3tl::compose1(::std::bind2nd(::std::equal_to<sal_Bool>(),sal_False),::o3tl::select2nd<TNames::value_type>())) )
266 0 : sRootEntryText = ModuleRes(STR_ALL_TABLES);
267 0 : else if ( ::std::none_of(_rTables.begin(),_rTables.end(),
268 0 : ::o3tl::compose1(::std::bind2nd(::std::equal_to<sal_Bool>(),sal_True),::o3tl::select2nd<TNames::value_type>())) )
269 0 : sRootEntryText = ModuleRes(STR_ALL_VIEWS);
270 : else
271 0 : sRootEntryText = ModuleRes(STR_ALL_TABLES_AND_VIEWS);
272 0 : InsertEntry( sRootEntryText, NULL, false, TREELIST_APPEND, reinterpret_cast< void* >( DatabaseObjectContainer::TABLES ) );
273 : }
274 :
275 0 : if ( _rTables.empty() )
276 : // nothing to do (besides inserting the root entry)
277 0 : return;
278 :
279 : // get the table/view names
280 0 : TNames::const_iterator aIter = _rTables.begin();
281 0 : TNames::const_iterator aEnd = _rTables.end();
282 :
283 0 : Reference< XDatabaseMetaData > xMeta( _rxConnection->getMetaData(), UNO_QUERY_THROW );
284 0 : for ( ; aIter != aEnd; ++aIter )
285 : {
286 : // add the entry
287 : implAddEntry(
288 : xMeta,
289 0 : aIter->first,
290 : false
291 0 : );
292 : }
293 :
294 0 : if ( !m_bNoEmptyFolders && lcl_shouldDisplayEmptySchemasAndCatalogs( _rxConnection ) )
295 : {
296 0 : bool bSupportsCatalogs = xMeta->supportsCatalogsInDataManipulation();
297 0 : bool bSupportsSchemas = xMeta->supportsSchemasInDataManipulation();
298 :
299 0 : if ( bSupportsCatalogs || bSupportsSchemas )
300 : {
301 : // we display empty catalogs if the DB supports catalogs, and they're noted at the beginning of a
302 : // composed name. Otherwise, we display empty schematas. (also see the tree structure explained in
303 : // implAddEntry)
304 0 : bool bCatalogs = bSupportsCatalogs && xMeta->isCatalogAtStart();
305 :
306 : ::std::vector< OUString > aFolderNames( lcl_getMetaDataStrings_throw(
307 0 : bCatalogs ? xMeta->getCatalogs() : xMeta->getSchemas(), 1 ) );
308 0 : sal_Int32 nFolderType = bCatalogs ? DatabaseObjectContainer::CATALOG : DatabaseObjectContainer::SCHEMA;
309 :
310 0 : SvTreeListEntry* pRootEntry = getAllObjectsEntry();
311 0 : for ( ::std::vector< OUString >::const_iterator folder = aFolderNames.begin();
312 0 : folder != aFolderNames.end();
313 : ++folder
314 : )
315 : {
316 0 : SvTreeListEntry* pFolder = GetEntryPosByName( *folder, pRootEntry );
317 0 : if ( !pFolder )
318 0 : pFolder = InsertEntry( *folder, pRootEntry, false, TREELIST_APPEND, reinterpret_cast< void* >( nFolderType ) );
319 0 : }
320 : }
321 0 : }
322 : }
323 0 : catch ( const Exception& )
324 : {
325 : DBG_UNHANDLED_EXCEPTION();
326 : }
327 : }
328 :
329 0 : bool OTableTreeListBox::isWildcardChecked(SvTreeListEntry* _pEntry)
330 : {
331 0 : if (_pEntry)
332 : {
333 0 : OBoldListboxString* pTextItem = static_cast<OBoldListboxString*>(_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING));
334 0 : if (pTextItem)
335 0 : return pTextItem->isEmphasized();
336 : }
337 0 : return false;
338 : }
339 :
340 0 : void OTableTreeListBox::checkWildcard(SvTreeListEntry* _pEntry)
341 : {
342 0 : SetCheckButtonState(_pEntry, SV_BUTTON_CHECKED);
343 0 : checkedButton_noBroadcast(_pEntry);
344 0 : }
345 :
346 0 : SvTreeListEntry* OTableTreeListBox::getAllObjectsEntry() const
347 : {
348 0 : return haveVirtualRoot() ? First() : NULL;
349 : }
350 :
351 0 : void OTableTreeListBox::checkedButton_noBroadcast(SvTreeListEntry* _pEntry)
352 : {
353 0 : OMarkableTreeListBox::checkedButton_noBroadcast(_pEntry);
354 :
355 : // if an entry has children, it makes a difference if the entry is checked
356 : // because all children are checked or if the user checked it explicitly.
357 : // So we track explicit (un)checking
358 :
359 0 : SvButtonState eState = GetCheckButtonState(_pEntry);
360 : OSL_ENSURE(SV_BUTTON_TRISTATE != eState, "OTableTreeListBox::CheckButtonHdl: user action which lead to TRISTATE?");
361 0 : implEmphasize(_pEntry, SV_BUTTON_CHECKED == eState);
362 0 : }
363 :
364 0 : void OTableTreeListBox::implEmphasize(SvTreeListEntry* _pEntry, bool _bChecked, bool _bUpdateDescendants, bool _bUpdateAncestors)
365 : {
366 : OSL_ENSURE(_pEntry, "OTableTreeListBox::implEmphasize: invalid entry (NULL)!");
367 :
368 : // special emphasizing handling for the "all objects" entry
369 0 : bool bAllObjectsEntryAffected = haveVirtualRoot() && (getAllObjectsEntry() == _pEntry);
370 0 : if ( GetModel()->HasChildren(_pEntry) // the entry has children
371 0 : || bAllObjectsEntryAffected // or it is the "all objects" entry
372 : )
373 : {
374 0 : OBoldListboxString* pTextItem = static_cast<OBoldListboxString*>(_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING));
375 0 : if (pTextItem)
376 0 : pTextItem->emphasize(_bChecked);
377 :
378 0 : if (bAllObjectsEntryAffected)
379 0 : InvalidateEntry(_pEntry);
380 : }
381 :
382 0 : if (_bUpdateDescendants)
383 : {
384 : // remove the mark for all children of the checked entry
385 0 : SvTreeListEntry* pChildLoop = FirstChild(_pEntry);
386 0 : while (pChildLoop)
387 : {
388 0 : if (GetModel()->HasChildren(pChildLoop))
389 0 : implEmphasize(pChildLoop, false, true, false);
390 0 : pChildLoop = NextSibling(pChildLoop);
391 : }
392 : }
393 :
394 0 : if (_bUpdateAncestors)
395 : {
396 : // remove the mark for all ancestors of the entry
397 0 : if (GetModel()->HasParent(_pEntry))
398 0 : implEmphasize(GetParent(_pEntry), false, false, true);
399 : }
400 0 : }
401 :
402 0 : void OTableTreeListBox::InitEntry(SvTreeListEntry* _pEntry, const OUString& _rString, const Image& _rCollapsedBitmap, const Image& _rExpandedBitmap, SvLBoxButtonKind _eButtonKind)
403 : {
404 0 : OMarkableTreeListBox::InitEntry(_pEntry, _rString, _rCollapsedBitmap, _rExpandedBitmap, _eButtonKind);
405 :
406 : // replace the text item with our own one
407 0 : SvLBoxItem* pTextItem = _pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING);
408 : OSL_ENSURE(pTextItem, "OTableTreeListBox::InitEntry: no text item!?");
409 0 : size_t nTextPos = _pEntry->GetPos(pTextItem);
410 : OSL_ENSURE(SvTreeListEntry::ITEM_NOT_FOUND != nTextPos, "OTableTreeListBox::InitEntry: no text item pos!");
411 :
412 0 : _pEntry->ReplaceItem(new OBoldListboxString(_pEntry, 0, _rString), nTextPos);
413 0 : }
414 :
415 0 : SvTreeListEntry* OTableTreeListBox::implAddEntry(
416 : const Reference< XDatabaseMetaData >& _rxMeta,
417 : const OUString& _rTableName,
418 : bool _bCheckName
419 : )
420 : {
421 : OSL_PRECOND( _rxMeta.is(), "OTableTreeListBox::implAddEntry: invalid meta data!" );
422 0 : if ( !_rxMeta.is() )
423 0 : return NULL;
424 :
425 : // split the complete name into it's components
426 0 : OUString sCatalog, sSchema, sName;
427 0 : qualifiedNameComponents( _rxMeta, _rTableName, sCatalog, sSchema, sName, ::dbtools::eInDataManipulation );
428 :
429 0 : SvTreeListEntry* pParentEntry = getAllObjectsEntry();
430 :
431 : // if the DB uses catalog at the start of identifiers, then our hierarchy is
432 : // catalog
433 : // +- schema
434 : // +- table
435 : // else it is
436 : // schema
437 : // +- catalog
438 : // +- table
439 0 : bool bCatalogAtStart = _rxMeta->isCatalogAtStart();
440 0 : const OUString& rFirstName = bCatalogAtStart ? sCatalog : sSchema;
441 0 : const sal_Int32 nFirstFolderType = bCatalogAtStart ? DatabaseObjectContainer::CATALOG : DatabaseObjectContainer::SCHEMA;
442 0 : const OUString& rSecondName = bCatalogAtStart ? sSchema : sCatalog;
443 0 : const sal_Int32 nSecondFolderType = bCatalogAtStart ? DatabaseObjectContainer::SCHEMA : DatabaseObjectContainer::CATALOG;
444 :
445 0 : if ( !rFirstName.isEmpty() )
446 : {
447 0 : SvTreeListEntry* pFolder = GetEntryPosByName( rFirstName, pParentEntry );
448 0 : if ( !pFolder )
449 0 : pFolder = InsertEntry( rFirstName, pParentEntry, false, TREELIST_APPEND, reinterpret_cast< void* >( nFirstFolderType ) );
450 0 : pParentEntry = pFolder;
451 : }
452 :
453 0 : if ( !rSecondName.isEmpty() )
454 : {
455 0 : SvTreeListEntry* pFolder = GetEntryPosByName( rSecondName, pParentEntry );
456 0 : if ( !pFolder )
457 0 : pFolder = InsertEntry( rSecondName, pParentEntry, false, TREELIST_APPEND, reinterpret_cast< void* >( nSecondFolderType ) );
458 0 : pParentEntry = pFolder;
459 : }
460 :
461 0 : SvTreeListEntry* pRet = NULL;
462 0 : if ( !_bCheckName || !GetEntryPosByName( sName, pParentEntry ) )
463 : {
464 0 : pRet = InsertEntry( sName, pParentEntry, false, TREELIST_APPEND );
465 :
466 0 : Image aImage;
467 0 : m_xImageProvider->getImages( _rTableName, DatabaseObject::TABLE, aImage );
468 :
469 0 : SetExpandedEntryBmp( pRet, aImage );
470 0 : SetCollapsedEntryBmp( pRet, aImage );
471 : }
472 0 : return pRet;
473 : }
474 :
475 0 : NamedDatabaseObject OTableTreeListBox::describeObject( SvTreeListEntry* _pEntry )
476 : {
477 0 : NamedDatabaseObject aObject;
478 :
479 0 : sal_Int32 nEntryType = reinterpret_cast< sal_IntPtr >( _pEntry->GetUserData() );
480 :
481 0 : if ( nEntryType == DatabaseObjectContainer::TABLES )
482 : {
483 0 : aObject.Type = DatabaseObjectContainer::TABLES;
484 : }
485 0 : else if ( ( nEntryType == DatabaseObjectContainer::CATALOG )
486 0 : || ( nEntryType == DatabaseObjectContainer::SCHEMA )
487 : )
488 : {
489 0 : SvTreeListEntry* pParent = GetParent( _pEntry );
490 0 : sal_Int32 nParentEntryType = pParent ? reinterpret_cast< sal_IntPtr >( pParent->GetUserData() ) : -1;
491 :
492 0 : OUStringBuffer buffer;
493 0 : if ( nEntryType == DatabaseObjectContainer::CATALOG )
494 : {
495 0 : if ( nParentEntryType == DatabaseObjectContainer::SCHEMA )
496 : {
497 0 : buffer.append( GetEntryText( pParent ) );
498 0 : buffer.append( '.' );
499 : }
500 0 : buffer.append( GetEntryText( _pEntry ) );
501 : }
502 0 : else if ( nEntryType == DatabaseObjectContainer::SCHEMA )
503 : {
504 0 : if ( nParentEntryType == DatabaseObjectContainer::CATALOG )
505 : {
506 0 : buffer.append( GetEntryText( pParent ) );
507 0 : buffer.append( '.' );
508 : }
509 0 : buffer.append( GetEntryText( _pEntry ) );
510 0 : }
511 : }
512 : else
513 : {
514 0 : aObject.Type = DatabaseObject::TABLE;
515 0 : aObject.Name = getQualifiedTableName( _pEntry );
516 : }
517 :
518 0 : return aObject;
519 : }
520 :
521 0 : SvTreeListEntry* OTableTreeListBox::addedTable( const OUString& _rName )
522 : {
523 : try
524 : {
525 0 : Reference< XDatabaseMetaData > xMeta;
526 0 : if ( impl_getAndAssertMetaData( xMeta ) )
527 0 : return implAddEntry( xMeta, _rName );
528 : }
529 0 : catch( const Exception& )
530 : {
531 : DBG_UNHANDLED_EXCEPTION();
532 : }
533 0 : return NULL;
534 : }
535 :
536 0 : bool OTableTreeListBox::impl_getAndAssertMetaData( Reference< XDatabaseMetaData >& _out_rMetaData ) const
537 : {
538 0 : if ( m_xConnection.is() )
539 0 : _out_rMetaData = m_xConnection->getMetaData();
540 : OSL_PRECOND( _out_rMetaData.is(), "OTableTreeListBox::impl_getAndAssertMetaData: invalid current connection!" );
541 0 : return _out_rMetaData.is();
542 : }
543 :
544 0 : OUString OTableTreeListBox::getQualifiedTableName( SvTreeListEntry* _pEntry ) const
545 : {
546 : OSL_PRECOND( !isFolderEntry( _pEntry ), "OTableTreeListBox::getQualifiedTableName: folder entries not allowed here!" );
547 :
548 : try
549 : {
550 0 : Reference< XDatabaseMetaData > xMeta;
551 0 : if ( !impl_getAndAssertMetaData( xMeta ) )
552 0 : return OUString();
553 :
554 0 : OUString sCatalog;
555 0 : OUString sSchema;
556 0 : OUString sTable;
557 :
558 0 : SvTreeListEntry* pSchema = GetParent( _pEntry );
559 0 : if ( pSchema )
560 : {
561 0 : SvTreeListEntry* pCatalog = GetParent( pSchema );
562 0 : if ( pCatalog
563 0 : || ( xMeta->supportsCatalogsInDataManipulation()
564 0 : && !xMeta->supportsSchemasInDataManipulation()
565 : ) // here we support catalog but no schema
566 : )
567 : {
568 0 : if ( pCatalog == NULL )
569 : {
570 0 : pCatalog = pSchema;
571 0 : pSchema = NULL;
572 : }
573 0 : sCatalog = GetEntryText( pCatalog );
574 : }
575 0 : if ( pSchema )
576 0 : sSchema = GetEntryText(pSchema);
577 : }
578 0 : sTable = GetEntryText( _pEntry );
579 :
580 0 : return ::dbtools::composeTableName( xMeta, sCatalog, sSchema, sTable, false, ::dbtools::eInDataManipulation );
581 : }
582 0 : catch( const Exception& )
583 : {
584 : DBG_UNHANDLED_EXCEPTION();
585 : }
586 0 : return OUString();
587 : }
588 :
589 0 : SvTreeListEntry* OTableTreeListBox::getEntryByQualifiedName( const OUString& _rName )
590 : {
591 : try
592 : {
593 0 : Reference< XDatabaseMetaData > xMeta;
594 0 : if ( !impl_getAndAssertMetaData( xMeta ) )
595 0 : return NULL;
596 :
597 : // split the complete name into it's components
598 0 : OUString sCatalog, sSchema, sName;
599 0 : qualifiedNameComponents(xMeta, _rName, sCatalog, sSchema, sName,::dbtools::eInDataManipulation);
600 :
601 0 : SvTreeListEntry* pParent = getAllObjectsEntry();
602 0 : SvTreeListEntry* pCat = NULL;
603 0 : SvTreeListEntry* pSchema = NULL;
604 0 : if ( !sCatalog.isEmpty() )
605 : {
606 0 : pCat = GetEntryPosByName(sCatalog, pParent);
607 0 : if ( pCat )
608 0 : pParent = pCat;
609 : }
610 :
611 0 : if ( !sSchema.isEmpty() )
612 : {
613 0 : pSchema = GetEntryPosByName(sSchema, pParent);
614 0 : if ( pSchema )
615 0 : pParent = pSchema;
616 : }
617 :
618 0 : return GetEntryPosByName(sName, pParent);
619 : }
620 0 : catch( const Exception& )
621 : {
622 : DBG_UNHANDLED_EXCEPTION();
623 : }
624 0 : return NULL;
625 : }
626 :
627 0 : void OTableTreeListBox::removedTable( const OUString& _rName )
628 : {
629 : try
630 : {
631 0 : SvTreeListEntry* pEntry = getEntryByQualifiedName( _rName );
632 0 : if ( pEntry )
633 0 : GetModel()->Remove( pEntry );
634 : }
635 0 : catch( const Exception& )
636 : {
637 : DBG_UNHANDLED_EXCEPTION();
638 : }
639 0 : }
640 :
641 36 : } // namespace dbaui
642 :
643 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|