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