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