24#include <com/sun/star/sdb/tools/XTableRename.hpp>
25#include <com/sun/star/sdb/tools/XTableAlteration.hpp>
26#include <com/sun/star/sdb/tools/XKeyAlteration.hpp>
27#include <com/sun/star/sdb/tools/XIndexAlteration.hpp>
29#include <com/sun/star/sdbc/XRow.hpp>
30#include <com/sun/star/sdbc/XResultSet.hpp>
31#include <com/sun/star/sdbcx/KeyType.hpp>
33#include <com/sun/star/lang/XMultiServiceFactory.hpp>
57class OTableContainerListener:
58 public ::cppu::WeakImplHelper< XContainerListener >
61 std::map< OUString,bool> m_aRefNames;
64 virtual ~OTableContainerListener()
override {}
66 explicit OTableContainerListener(
OTableHelper* _pComponent) : m_pComponent(_pComponent){}
68 OTableContainerListener(
const OTableContainerListener&) =
delete;
69 const OTableContainerListener& operator=(
const OTableContainerListener&) =
delete;
70 virtual void SAL_CALL
elementInserted(
const css::container::ContainerEvent& )
override
73 virtual void SAL_CALL
elementRemoved(
const css::container::ContainerEvent& Event )
override
77 if (m_pComponent ==
nullptr)
81 Event.Accessor >>=
sName;
82 if ( m_aRefNames.find(sName) != m_aRefNames.end() )
85 virtual void SAL_CALL
elementReplaced(
const css::container::ContainerEvent& Event )
override
87 OUString sOldComposedName,sNewComposedName;
88 Event.ReplacedElement >>= sOldComposedName;
89 Event.Accessor >>= sNewComposedName;
90 if ( sOldComposedName != sNewComposedName && m_aRefNames.find(sOldComposedName) != m_aRefNames.end() )
94 virtual void SAL_CALL disposing(
const EventObject& )
override
97 void clear() { m_pComponent =
nullptr; }
98 void add(
const OUString& _sRefName) { m_aRefNames.emplace(_sRefName,
true); }
105 OUString sSupportService;
109 aValue >>= sSupportService;
111 return sSupportService;
118 Reference< css::sdb::tools::XTableAlteration>
m_xAlter;
132 Reference<XMultiServiceFactory> xFac(_xConnection,UNO_QUERY);
149 const Reference< XConnection >& _xConnection,
157 const Reference< XConnection >& _xConnection,
159 const OUString& Name,
160 const OUString&
Type,
161 const OUString& Description ,
162 const OUString& SchemaName,
163 const OUString& CatalogName
182 if (
m_pImpl->m_xTablePropertyListener.is() )
185 m_pImpl->m_xTablePropertyListener->clear();
186 m_pImpl->m_xTablePropertyListener.clear();
190 m_pImpl->m_xConnection =
nullptr;
191 m_pImpl->m_xMetaData =
nullptr;
200 void lcl_collectColumnDescs_throw(
const Reference< XResultSet >& _rxResult, std::vector< ColumnDesc >& _out_rColumns )
202 Reference< XRow > xRow( _rxResult, UNO_QUERY_THROW );
205 while ( _rxResult->next() )
207 sName = xRow->getString( 4 );
208 sal_Int32 nField5 = xRow->getInt(5);
209 OUString aField6 = xRow->getString(6);
210 sal_Int32 nField7 = xRow->getInt(7)
211 , nField9 = xRow->getInt(9)
212 , nField11= xRow->getInt(11);
213 OUString sField12 = xRow->getString(12)
214 ,sField13 = xRow->getString(13);
215 nOrdinalPosition = xRow->getInt( 17 );
216 _out_rColumns.push_back(
ColumnDesc( sName,nField5,aField6,nField7,nField9,nField11,sField12,sField13, nOrdinalPosition ) );
223 void lcl_sanitizeColumnDescs( std::vector< ColumnDesc >& _rColumns )
225 if ( _rColumns.empty() )
229 std::set< OrdinalPosition > aUsedOrdinals;
230 for (
const auto& collect : _rColumns )
231 aUsedOrdinals.insert( collect.nOrdinalPosition );
234 bool bDuplicates = aUsedOrdinals.size() != _rColumns.size();
236 size_t nOrdinalsRange = *aUsedOrdinals.rbegin() - *aUsedOrdinals.begin() + 1;
237 bool bGaps = nOrdinalsRange != _rColumns.size();
240 if ( bGaps || bDuplicates )
242 OSL_FAIL(
"lcl_sanitizeColumnDescs: database did provide invalid ORDINAL_POSITION values!" );
245 for (
auto& normalize : _rColumns )
246 normalize.nOrdinalPosition = nNormalizedPosition++;
252 size_t nOffset = *aUsedOrdinals.begin() - 1;
253 for (
auto& offset : _rColumns )
254 offset.nOrdinalPosition -= nOffset;
261 ::std::vector< OUString> aVector;
276 m_pImpl->m_aColumnDesc.clear();
277 lcl_collectColumnDescs_throw( xResult,
m_pImpl->m_aColumnDesc );
280 lcl_sanitizeColumnDescs(
m_pImpl->m_aColumnDesc );
283 std::map< OrdinalPosition, OUString > aSortedColumns;
285 aSortedColumns[
copy.nOrdinalPosition ] =
copy.sName;
289 aSortedColumns.begin(),
290 aSortedColumns.end(),
291 std::insert_iterator< ::std::vector< OUString> >( aVector, aVector.begin() ),
305 auto aIter = std::find_if(
m_pImpl->m_aColumnDesc.begin(),
m_pImpl->m_aColumnDesc.end(),
306 [&_sName](
const ColumnDesc& rColumnDesc) { return rColumnDesc.sName == _sName; });
307 if (aIter !=
m_pImpl->m_aColumnDesc.end())
321 auto pKeyProps = std::make_shared<sdbcx::KeyProperties>(OUString(),KeyType::PRIMARY,0,0);
323 bool bAlreadyFetched =
false;
324 const Reference< XRow > xRow(xResult,UNO_QUERY);
325 while ( xResult->next() )
327 pKeyProps->m_aKeyColumnNames.push_back(xRow->getString(4));
328 if ( !bAlreadyFetched )
330 aPkName = xRow->getString(6);
331 SAL_WARN_IF(xRow->wasNull(),
"connectivity.commontools",
"NULL Primary Key name");
332 SAL_WARN_IF(aPkName.isEmpty(),
"connectivity.commontools",
"empty Primary Key name");
333 bAlreadyFetched =
true;
339 SAL_WARN_IF(aPkName.isEmpty(),
"connectivity.commontools",
"empty Primary Key name");
340 SAL_WARN_IF(pKeyProps->m_aKeyColumnNames.empty(),
"connectivity.commontools",
"Primary Key has no columns");
341 m_pImpl->m_aKeys.emplace(aPkName,pKeyProps);
342 _rNames.push_back(aPkName);
345 ::comphelper::disposeComponent(xResult);
354 Reference< XRow > xRow(xResult,UNO_QUERY);
359 std::shared_ptr<sdbcx::KeyProperties> pKeyProps;
361 while( xResult->next() )
365 if ( xRow->wasNull() )
367 aSchema = xRow->getString(2);
368 aName = xRow->getString(3);
370 const OUString sForeignKeyColumn = xRow->getString(8);
371 const sal_Int32 nUpdateRule = xRow->getInt(10);
372 const sal_Int32 nDeleteRule = xRow->getInt(11);
373 const OUString sFkName = xRow->getString(12);
375 if ( !sFkName.isEmpty() && !xRow->wasNull() )
377 if ( sOldFKName != sFkName )
380 m_pImpl->m_aKeys.emplace(sOldFKName,pKeyProps);
383 pKeyProps = std::make_shared<sdbcx::KeyProperties>(sReferencedName,KeyType::FOREIGN,nUpdateRule,nDeleteRule);
384 pKeyProps->m_aKeyColumnNames.push_back(sForeignKeyColumn);
385 _rNames.push_back(sFkName);
388 if ( !
m_pImpl->m_xTablePropertyListener.is() )
389 m_pImpl->m_xTablePropertyListener =
new OTableContainerListener(
this);
391 m_pImpl->m_xTablePropertyListener->add(sReferencedName);
393 sOldFKName = sFkName;
395 else if ( pKeyProps )
397 pKeyProps->m_aKeyColumnNames.push_back(sForeignKeyColumn);
402 m_pImpl->m_aKeys.emplace(sOldFKName,pKeyProps);
403 ::comphelper::disposeComponent(xResult);
410 ::std::vector< OUString> aNames;
428 ::std::vector< OUString> aVector;
439 Reference< XRow > xRow(xResult,UNO_QUERY);
440 OUString sCatalogSep =
getMetaData()->getCatalogSeparator();
441 OUString sPreviousRoundName;
442 while( xResult->next() )
444 OUString
aName = xRow->getString(5);
446 aName += sCatalogSep;
447 aName += xRow->getString(6);
448 if ( !
aName.isEmpty() )
451 if (sPreviousRoundName !=
aName)
452 aVector.push_back(
aName);
454 sPreviousRoundName =
aName;
456 ::comphelper::disposeComponent(xResult);
468 OUString sSql(
"RENAME ");
483 ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
509 Reference< XStatement > xStmt =
m_pImpl->m_xConnection->createStatement( );
512 xStmt->execute(sSql);
513 ::comphelper::disposeComponent(xStmt);
533 ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
539 Reference< XPropertySet > xOld(
559 std::shared_ptr<sdbcx::KeyProperties> pKeyProps;
560 TKeyMap::const_iterator aFind =
m_pImpl->m_aKeys.find(_sName);
561 if ( aFind !=
m_pImpl->m_aKeys.end() )
563 pKeyProps = aFind->second;
567 OSL_FAIL(
"No key with the given name found");
568 pKeyProps = std::make_shared<sdbcx::KeyProperties>();
576 m_pImpl->m_aKeys.emplace(_sName,_aKeyProperties);
OptionalString sComposedName
::std::unique_ptr< OTableHelperImpl > m_pImpl
virtual sdbcx::OCollection * createIndexes(const ::std::vector< OUString > &_rNames)=0
creates the index collection for the table
virtual void refreshIndexes() override
virtual sdbcx::OCollection * createKeys(const ::std::vector< OUString > &_rNames)=0
creates the key collection for the table
css::uno::Reference< css::sdbc::XConnection > const & getConnection() const
OTableHelper(sdbcx::OCollection *_pTables, const css::uno::Reference< css::sdbc::XConnection > &_xConnection, bool _bCase)
const OUString & getTableName()
virtual void SAL_CALL alterColumnByIndex(sal_Int32 index, const css::uno::Reference< css::beans::XPropertySet > &descriptor) override
virtual void SAL_CALL disposing() override
this function is called upon disposing the component
virtual void SAL_CALL rename(const OUString &newName) override
const ColumnDesc * getColumnDescription(const OUString &_sName) const
void addKey(const OUString &_sName, const std::shared_ptr< sdbcx::KeyProperties > &_aKeyProperties)
css::uno::Reference< css::sdb::tools::XTableRename > const & getRenameService() const
virtual OUString getTypeCreatePattern() const
virtual css::uno::Reference< css::sdbc::XDatabaseMetaData > getMetaData() const override
void refreshForeignKeys(::std::vector< OUString > &_rKeys)
css::uno::Reference< css::sdb::tools::XIndexAlteration > const & getIndexService() const
virtual void refreshColumns() override
virtual OUString getRenameStart() const
The default returns "RENAME TABLE " or "RENAME VIEW " depending on the type.
virtual OUString SAL_CALL getName() override
void refreshPrimaryKeys(::std::vector< OUString > &_rKeys)
virtual ~OTableHelper() override
virtual sdbcx::OCollection * createColumns(const ::std::vector< OUString > &_rNames)=0
creates the column collection for the table
std::shared_ptr< sdbcx::KeyProperties > getKeyProperties(const OUString &_sName) const
css::uno::Reference< css::sdb::tools::XKeyAlteration > const & getKeyService() const
virtual void refreshKeys() override
css::uno::Reference< css::sdb::tools::XTableAlteration > const & getAlterService() const
virtual void SAL_CALL removeContainerListener(const css::uno::Reference< css::container::XContainerListener > &xListener) override
virtual void SAL_CALL addContainerListener(const css::uno::Reference< css::container::XContainerListener > &xListener) override
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
std::unique_ptr< OCollection > m_xIndexes
virtual void SAL_CALL alterColumnByName(const OUString &colName, const css::uno::Reference< css::beans::XPropertySet > &descriptor) override
virtual css::uno::Reference< css::container::XNameAccess > SAL_CALL getColumns() override
std::unique_ptr< OCollection > m_xKeys
std::unique_ptr< OCollection > m_xColumns
virtual void SAL_CALL rename(const OUString &newName) override
virtual void SAL_CALL disposing() override
mutable::osl::Mutex m_aMutex
void SAL_CALL elementReplaced(const css::container::ContainerEvent &Event) override
void SAL_CALL elementRemoved(const css::container::ContainerEvent &Event) override
DECL_LISTENERMULTIPLEXER_END void SAL_CALL elementInserted(const css::container::ContainerEvent &Event) override
#define SAL_WARN_IF(condition, area, stream)
bool normalize(sal_uInt16 &rDay, sal_uInt16 &rMonth, sal_Int16 &rYear)
OUString getString(const Any &_rAny)
sal_Int32 OrdinalPosition
static OUString lcl_getServiceNameForSetting(const Reference< css::sdbc::XConnection > &_xConnection, const OUString &i_sSetting)
std::map< OUString, std::shared_ptr< sdbcx::KeyProperties > > TKeyMap
void checkDisposed(bool _bThrow)
OUString newName(std::u16string_view aNewPrefix, std::u16string_view aOldPrefix, std::u16string_view old_Name)
void copy(const fs::path &src, const fs::path &dest)
std::vector< ColumnDesc > m_aColumnDesc
Reference< css::sdb::tools::XKeyAlteration > m_xKeyAlter
OTableHelperImpl(const Reference< css::sdbc::XConnection > &_xConnection)
Reference< css::sdb::tools::XIndexAlteration > m_xIndexAlter
Reference< css::sdb::tools::XTableRename > m_xRename
Reference< css::sdbc::XDatabaseMetaData > m_xMetaData
Reference< css::sdbc::XConnection > m_xConnection
rtl::Reference< OTableContainerListener > m_xTablePropertyListener
Reference< css::sdb::tools::XTableAlteration > m_xAlter