LibreOffice Module connectivity (master) 1
HTable.cxx
Go to the documentation of this file.
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 <hsqldb/HTable.hxx>
21#include <com/sun/star/beans/PropertyAttribute.hpp>
22#include <com/sun/star/sdbcx/Privilege.hpp>
25#include <comphelper/types.hxx>
29#include <hsqldb/HColumns.hxx>
30#include <TConnection.hxx>
31
33
34
35using namespace ::comphelper;
36using namespace connectivity::hsqldb;
37using namespace connectivity::sdbcx;
38using namespace connectivity;
39using namespace ::com::sun::star::uno;
40using namespace ::com::sun::star::beans;
41using namespace ::com::sun::star::sdbcx;
42using namespace ::com::sun::star::sdbc;
43using namespace ::com::sun::star::container;
44using namespace ::com::sun::star::lang;
45
46OHSQLTable::OHSQLTable( sdbcx::OCollection* _pTables,
47 const Reference< XConnection >& _xConnection)
48 :OTableHelper(_pTables,_xConnection,true)
49{
50 // we create a new table here, so we should have all the rights or ;-)
51 m_nPrivileges = Privilege::DROP |
52 Privilege::REFERENCE |
53 Privilege::ALTER |
54 Privilege::CREATE |
55 Privilege::READ |
56 Privilege::DELETE |
57 Privilege::UPDATE |
58 Privilege::INSERT |
59 Privilege::SELECT;
60 construct();
61}
62
63OHSQLTable::OHSQLTable( sdbcx::OCollection* _pTables,
64 const Reference< XConnection >& _xConnection,
65 const OUString& Name,
66 const OUString& Type,
67 const OUString& Description ,
68 const OUString& SchemaName,
69 const OUString& CatalogName,
70 sal_Int32 _nPrivileges
71 ) : OTableHelper( _pTables,
72 _xConnection,
73 true,
74 Name,
75 Type,
76 Description,
77 SchemaName,
78 CatalogName)
79 , m_nPrivileges(_nPrivileges)
80{
81 construct();
82}
83
84void OHSQLTable::construct()
85{
87 if ( !isNew() )
89}
90
92{
93 return doCreateArrayHelper();
94}
95
97{
98 return *static_cast<OHSQLTable_PROP*>(this)->getArrayHelper(isNew() ? 1 : 0);
99}
100
101sdbcx::OCollection* OHSQLTable::createColumns(const ::std::vector< OUString>& _rNames)
102{
103 OHSQLColumns* pColumns = new OHSQLColumns(*this,m_aMutex,_rNames);
104 pColumns->setParent(this);
105 return pColumns;
106}
107
108sdbcx::OCollection* OHSQLTable::createKeys(const ::std::vector< OUString>& _rNames)
109{
110 return new OKeysHelper(this,m_aMutex,_rNames);
111}
112
113sdbcx::OCollection* OHSQLTable::createIndexes(const ::std::vector< OUString>& _rNames)
114{
115 return new OIndexesHelper(this,m_aMutex,_rNames);
116}
117
118
119// XAlterTable
120void SAL_CALL OHSQLTable::alterColumnByName( const OUString& colName, const Reference< XPropertySet >& descriptor )
121{
122 ::osl::MutexGuard aGuard(m_aMutex);
124#ifdef __GNUC__
125 ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
126#else
127 rBHelper.bDisposed
128#endif
129 );
130
131 if ( !m_xColumns || !m_xColumns->hasByName(colName) )
132 throw NoSuchElementException(colName,*this);
133
134
135 if ( !isNew() )
136 {
137 // first we have to check what should be altered
138 Reference<XPropertySet> xProp;
139 m_xColumns->getByName(colName) >>= xProp;
140 // first check the types
141 sal_Int32 nOldType = 0,nNewType = 0,nOldPrec = 0,nNewPrec = 0,nOldScale = 0,nNewScale = 0;
142 OUString sOldTypeName, sNewTypeName;
143
145
146 // type/typename
147 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPE)) >>= nOldType;
148 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPE)) >>= nNewType;
149 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPENAME)) >>= sOldTypeName;
150 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPENAME))>>= sNewTypeName;
151
152 // and precision and scale
153 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_PRECISION)) >>= nOldPrec;
154 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_PRECISION))>>= nNewPrec;
155 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_SCALE)) >>= nOldScale;
156 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_SCALE)) >>= nNewScale;
157
158 // second: check the "is nullable" value
159 sal_Int32 nOldNullable = 0,nNewNullable = 0;
160 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISNULLABLE)) >>= nOldNullable;
161 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISNULLABLE)) >>= nNewNullable;
162
163 // check also the auto_increment
164 bool bOldAutoIncrement = false,bAutoIncrement = false;
165 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT)) >>= bOldAutoIncrement;
166 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT)) >>= bAutoIncrement;
167
168 // now we should look if the name of the column changed
169 OUString sNewColumnName;
170 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_NAME)) >>= sNewColumnName;
171 if ( sNewColumnName != colName )
172 {
173 const OUString sQuote = getMetaData()->getIdentifierQuoteString( );
174
175 OUString sSql = getAlterTableColumnPart() +
176 " ALTER COLUMN " +
178 " RENAME TO " +
179 ::dbtools::quoteName(sQuote,sNewColumnName);
180
181 executeStatement(sSql);
182 }
183
184 if ( nOldType != nNewType
185 || sOldTypeName != sNewTypeName
186 || nOldPrec != nNewPrec
187 || nOldScale != nNewScale
188 || nNewNullable != nOldNullable
189 || bOldAutoIncrement != bAutoIncrement )
190 {
191 // special handling because they change the type names to distinguish
192 // if a column should be an auto_increment one
193 if ( bOldAutoIncrement != bAutoIncrement )
194 {
196 }
197 alterColumnType(nNewType,sNewColumnName,descriptor);
198 }
199
200 // third: check the default values
201 OUString sNewDefault,sOldDefault;
202 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_DEFAULTVALUE)) >>= sOldDefault;
203 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_DEFAULTVALUE)) >>= sNewDefault;
204
205 if(!sOldDefault.isEmpty())
206 {
207 dropDefaultValue(colName);
208 if(!sNewDefault.isEmpty() && sOldDefault != sNewDefault)
209 alterDefaultValue(sNewDefault,sNewColumnName);
210 }
211 else if(sOldDefault.isEmpty() && !sNewDefault.isEmpty())
212 alterDefaultValue(sNewDefault,sNewColumnName);
213
214 m_xColumns->refresh();
215 }
216 else
217 {
218 if(m_xColumns)
219 {
220 m_xColumns->dropByName(colName);
221 m_xColumns->appendByDescriptor(descriptor);
222 }
223 }
224
225}
226
227void OHSQLTable::alterColumnType(sal_Int32 nNewType,const OUString& _rColName, const Reference<XPropertySet>& _xDescriptor)
228{
229 OUString sSql = getAlterTableColumnPart() + " ALTER COLUMN ";
230#if OSL_DEBUG_LEVEL > 0
231 try
232 {
233 OUString sDescriptorName;
234 OSL_ENSURE( _xDescriptor.is()
235 && ( _xDescriptor->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_NAME ) ) >>= sDescriptorName )
236 && ( sDescriptorName == _rColName ),
237 "OHSQLTable::alterColumnType: unexpected column name!" );
238 }
239 catch( const Exception& )
240 {
241 DBG_UNHANDLED_EXCEPTION("connectivity.hsqldb");
242 }
243#else
244 (void)_rColName;
245#endif
246
248 ::comphelper::copyProperties(_xDescriptor,pColumn);
249 pColumn->setPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE),Any(nNewType));
250
252 executeStatement(sSql);
253}
254
255void OHSQLTable::alterDefaultValue(std::u16string_view _sNewDefault,const OUString& _rColName)
256{
257 const OUString sQuote = getMetaData()->getIdentifierQuoteString( );
258 OUString sSql = getAlterTableColumnPart() +
259 " ALTER COLUMN " +
260 ::dbtools::quoteName(sQuote,_rColName) +
261 " SET DEFAULT '" + _sNewDefault + "'";
262
263 executeStatement(sSql);
264}
265
266void OHSQLTable::dropDefaultValue(const OUString& _rColName)
267{
268 const OUString sQuote = getMetaData()->getIdentifierQuoteString( );
269 OUString sSql = getAlterTableColumnPart() +
270 " ALTER COLUMN " +
271 ::dbtools::quoteName(sQuote,_rColName) +
272 " DROP DEFAULT";
273
274 executeStatement(sSql);
275}
276
278{
279 OUString sSql( "ALTER TABLE " );
280
281 OUString sComposedName( ::dbtools::composeTableName( getMetaData(), m_CatalogName, m_SchemaName, m_Name, true, ::dbtools::EComposeRule::InTableDefinitions ) );
282 sSql += sComposedName;
283
284 return sSql;
285}
286
287void OHSQLTable::executeStatement(const OUString& _rStatement )
288{
289 OUString sSQL = _rStatement;
290 if(sSQL.endsWith(","))
291 sSQL = sSQL.replaceAt(sSQL.getLength()-1, 1, u")");
292
293 Reference< XStatement > xStmt = getConnection()->createStatement( );
294 if ( xStmt.is() )
295 {
296 try { xStmt->execute(sSQL); }
297 catch( const Exception& )
298 {
299 ::comphelper::disposeComponent(xStmt);
300 throw;
301 }
302 ::comphelper::disposeComponent(xStmt);
303 }
304}
305
306Sequence< Type > SAL_CALL OHSQLTable::getTypes( )
307{
308 if ( m_Type == "VIEW" )
309 {
310 Sequence< Type > aTypes = OTableHelper::getTypes();
311 std::vector<Type> aOwnTypes;
312 aOwnTypes.reserve(aTypes.getLength());
313 const Type* pIter = aTypes.getConstArray();
314 const Type* pEnd = pIter + aTypes.getLength();
315 for(;pIter != pEnd;++pIter)
316 {
317 if( *pIter != cppu::UnoType<XRename>::get())
318 {
319 aOwnTypes.push_back(*pIter);
320 }
321 }
322 return Sequence< Type >(aOwnTypes.data(), aOwnTypes.size());
323 }
324 return OTableHelper::getTypes();
325}
326
327// XRename
328void SAL_CALL OHSQLTable::rename( const OUString& newName )
329{
330 ::osl::MutexGuard aGuard(m_aMutex);
332#ifdef __GNUC__
333 ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
334#else
335 rBHelper.bDisposed
336#endif
337 );
338
339 if(!isNew())
340 {
341 OUString sSql = "ALTER ";
342 if ( m_Type == "VIEW" )
343 sSql += " VIEW ";
344 else
345 sSql += " TABLE ";
346
347 OUString sCatalog,sSchema,sTable;
348 ::dbtools::qualifiedNameComponents(getMetaData(),newName,sCatalog,sSchema,sTable,::dbtools::EComposeRule::InDataManipulation);
349
350 sSql +=
351 ::dbtools::composeTableName( getMetaData(), m_CatalogName, m_SchemaName, m_Name, true, ::dbtools::EComposeRule::InDataManipulation )
352 + " RENAME TO "
353 + ::dbtools::composeTableName( getMetaData(), sCatalog, sSchema, sTable, true, ::dbtools::EComposeRule::InDataManipulation );
354
355 executeStatement(sSql);
356
358 }
359 else
360 ::dbtools::qualifiedNameComponents(getMetaData(),newName,m_CatalogName,m_SchemaName,m_Name,::dbtools::EComposeRule::InTableDefinitions);
361}
362
363
364Any SAL_CALL OHSQLTable::queryInterface( const Type & rType )
365{
366 if( m_Type == "VIEW" && rType == cppu::UnoType<XRename>::get())
367 return Any();
368
369 return OTableHelper::queryInterface(rType);
370}
371
372
373/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sSchema
OptionalString sCatalog
OptionalString sComposedName
::cppu::IPropertyArrayHelper * getArrayHelper(sal_Int32 nId)
void registerProperty(const OUString &_rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, void *_pPointerToMember, const css::uno::Type &_rMemberType)
void setParent(OTableHelper *_pTable)
set the parent of the columns.
::dbtools::OPropertyMap & getPropMap()
Definition: TConnection.cxx:68
css::uno::Reference< css::sdbc::XConnection > const & getConnection() const
virtual css::uno::Reference< css::sdbc::XDatabaseMetaData > getMetaData() const override
void alterColumnType(sal_Int32 nNewType, const OUString &_rColName, const css::uno::Reference< css::beans::XPropertySet > &_xDescriptor)
Definition: HTable.cxx:227
virtual sdbcx::OCollection * createIndexes(const ::std::vector< OUString > &_rNames) override
creates the index collection for the table
Definition: HTable.cxx:113
virtual void SAL_CALL alterColumnByName(const OUString &colName, const css::uno::Reference< css::beans::XPropertySet > &descriptor) override
Definition: HTable.cxx:120
OUString getAlterTableColumnPart() const
returns the ALTER TABLE XXX COLUMN statement
Definition: HTable.cxx:277
void dropDefaultValue(const OUString &_sNewDefault)
Definition: HTable.cxx:266
virtual sdbcx::OCollection * createColumns(const ::std::vector< OUString > &_rNames) override
creates the column collection for the table
Definition: HTable.cxx:101
virtual void SAL_CALL rename(const OUString &newName) override
Definition: HTable.cxx:328
virtual ::cppu::IPropertyArrayHelper &SAL_CALL getInfoHelper() override
Definition: HTable.cxx:96
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: HTable.cxx:306
virtual sdbcx::OCollection * createKeys(const ::std::vector< OUString > &_rNames) override
creates the key collection for the table
Definition: HTable.cxx:108
virtual ::cppu::IPropertyArrayHelper * createArrayHelper(sal_Int32 nId) const override
used to implement the creation of the array helper which is shared amongst all instances of the class...
Definition: HTable.cxx:91
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
Definition: HTable.cxx:364
void alterDefaultValue(std::u16string_view _sNewDefault, const OUString &_rColName)
Definition: HTable.cxx:255
void executeStatement(const OUString &_rStatement)
executes the statement.
Definition: HTable.cxx:287
::cppu::IPropertyArrayHelper * doCreateArrayHelper() const
helper for derived classes to implement OPropertyArrayUsageHelper::createArrayHelper
Definition: VDescriptor.cxx:66
std::unique_ptr< OCollection > m_xColumns
Definition: VTable.hxx:77
virtual void SAL_CALL rename(const OUString &newName) override
Definition: VTable.cxx:244
virtual void construct() override
Definition: VTable.cxx:86
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: VTable.cxx:124
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
Definition: VTable.cxx:109
mutable::osl::Mutex m_aMutex
const OUString & getNameByIndex(sal_Int32 _nIndex) const
Definition: propertyids.cxx:95
#define DBG_UNHANDLED_EXCEPTION(...)
float u
const char sQuote[]
bool bAutoIncrement
@ Exception
Type
void checkDisposed(bool _bThrow)
Definition: dbtools.cxx:1951
OUString composeTableName(const Reference< XDatabaseMetaData > &_rxMetaData, const OUString &_rCatalog, const OUString &_rSchema, const OUString &_rName, bool _bQuote, EComposeRule _eComposeRule)
Definition: dbtools.cxx:1286
OUString createStandardColumnPart(const Reference< XPropertySet > &xColProp, const Reference< XConnection > &_xConnection, ISQLStatementHelper *_pHelper, std::u16string_view _sCreatePattern)
Definition: dbtools2.cxx:169
void qualifiedNameComponents(const Reference< XDatabaseMetaData > &_rxConnMetaData, const OUString &_rQualifiedName, OUString &_rCatalog, OUString &_rSchema, OUString &_rName, EComposeRule _eComposeRule)
Definition: dbtools.cxx:862
OUString quoteName(std::u16string_view _rQuote, const OUString &_rName)
quote the given name with the given quote string.
OUString newName(std::u16string_view aNewPrefix, std::u16string_view aOldPrefix, std::u16string_view old_Name)
#define PROPERTY_ID_NAME
Definition: propertyids.hxx:50
#define PROPERTY_ID_TYPE
Definition: propertyids.hxx:51
#define PROPERTY_ID_PRIVILEGES
Definition: propertyids.hxx:94
#define PROPERTY_ID_ISNULLABLE
Definition: propertyids.hxx:55
#define PROPERTY_ID_PRECISION
Definition: propertyids.hxx:53
#define PROPERTY_ID_ISAUTOINCREMENT
Definition: propertyids.hxx:56
#define PROPERTY_ID_TYPENAME
Definition: propertyids.hxx:52
#define PROPERTY_ID_DEFAULTVALUE
Definition: propertyids.hxx:59
#define PROPERTY_ID_SCALE
Definition: propertyids.hxx:54
OUString Name
const SvXMLTokenMapEntry aTypes[]