bump product version to 7.2.5.1
[LibreOffice.git] / connectivity / source / drivers / hsqldb / HTable.cxx
blob89d75fac7e3da59abe770ac0b1e8a8b4f7607229
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <hsqldb/HTable.hxx>
21 #include <cppuhelper/typeprovider.hxx>
22 #include <com/sun/star/beans/PropertyAttribute.hpp>
23 #include <com/sun/star/sdbcx/Privilege.hpp>
24 #include <comphelper/property.hxx>
25 #include <comphelper/servicehelper.hxx>
26 #include <comphelper/types.hxx>
27 #include <connectivity/dbtools.hxx>
28 #include <connectivity/TKeys.hxx>
29 #include <connectivity/TIndexes.hxx>
30 #include <hsqldb/HColumns.hxx>
31 #include <TConnection.hxx>
33 #include <tools/diagnose_ex.h>
36 using namespace ::comphelper;
37 using namespace connectivity::hsqldb;
38 using namespace connectivity::sdbcx;
39 using namespace connectivity;
40 using namespace ::com::sun::star::uno;
41 using namespace ::com::sun::star::beans;
42 using namespace ::com::sun::star::sdbcx;
43 using namespace ::com::sun::star::sdbc;
44 using namespace ::com::sun::star::container;
45 using namespace ::com::sun::star::lang;
47 OHSQLTable::OHSQLTable( sdbcx::OCollection* _pTables,
48 const Reference< XConnection >& _xConnection)
49 :OTableHelper(_pTables,_xConnection,true)
51 // we create a new table here, so we should have all the rights or ;-)
52 m_nPrivileges = Privilege::DROP |
53 Privilege::REFERENCE |
54 Privilege::ALTER |
55 Privilege::CREATE |
56 Privilege::READ |
57 Privilege::DELETE |
58 Privilege::UPDATE |
59 Privilege::INSERT |
60 Privilege::SELECT;
61 construct();
64 OHSQLTable::OHSQLTable( sdbcx::OCollection* _pTables,
65 const Reference< XConnection >& _xConnection,
66 const OUString& Name,
67 const OUString& Type,
68 const OUString& Description ,
69 const OUString& SchemaName,
70 const OUString& CatalogName,
71 sal_Int32 _nPrivileges
72 ) : OTableHelper( _pTables,
73 _xConnection,
74 true,
75 Name,
76 Type,
77 Description,
78 SchemaName,
79 CatalogName)
80 , m_nPrivileges(_nPrivileges)
82 construct();
85 void OHSQLTable::construct()
87 OTableHelper::construct();
88 if ( !isNew() )
89 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRIVILEGES), PROPERTY_ID_PRIVILEGES,PropertyAttribute::READONLY,&m_nPrivileges, cppu::UnoType<decltype(m_nPrivileges)>::get());
92 ::cppu::IPropertyArrayHelper* OHSQLTable::createArrayHelper( sal_Int32 /*_nId*/ ) const
94 return doCreateArrayHelper();
97 ::cppu::IPropertyArrayHelper & OHSQLTable::getInfoHelper()
99 return *static_cast<OHSQLTable_PROP*>(this)->getArrayHelper(isNew() ? 1 : 0);
102 sdbcx::OCollection* OHSQLTable::createColumns(const ::std::vector< OUString>& _rNames)
104 OHSQLColumns* pColumns = new OHSQLColumns(*this,m_aMutex,_rNames);
105 pColumns->setParent(this);
106 return pColumns;
109 sdbcx::OCollection* OHSQLTable::createKeys(const ::std::vector< OUString>& _rNames)
111 return new OKeysHelper(this,m_aMutex,_rNames);
114 sdbcx::OCollection* OHSQLTable::createIndexes(const ::std::vector< OUString>& _rNames)
116 return new OIndexesHelper(this,m_aMutex,_rNames);
119 Sequence< sal_Int8 > OHSQLTable::getUnoTunnelId()
121 static ::cppu::OImplementationId implId;
123 return implId.getImplementationId();
126 // css::lang::XUnoTunnel
128 sal_Int64 OHSQLTable::getSomething( const Sequence< sal_Int8 > & rId )
130 return (isUnoTunnelId<OHSQLTable>(rId))
131 ? reinterpret_cast< sal_Int64 >( this )
132 : OTable_TYPEDEF::getSomething(rId);
135 // XAlterTable
136 void SAL_CALL OHSQLTable::alterColumnByName( const OUString& colName, const Reference< XPropertySet >& descriptor )
138 ::osl::MutexGuard aGuard(m_aMutex);
139 checkDisposed(
140 #ifdef __GNUC__
141 ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
142 #else
143 rBHelper.bDisposed
144 #endif
147 if ( !m_xColumns || !m_xColumns->hasByName(colName) )
148 throw NoSuchElementException(colName,*this);
151 if ( !isNew() )
153 // first we have to check what should be altered
154 Reference<XPropertySet> xProp;
155 m_xColumns->getByName(colName) >>= xProp;
156 // first check the types
157 sal_Int32 nOldType = 0,nNewType = 0,nOldPrec = 0,nNewPrec = 0,nOldScale = 0,nNewScale = 0;
158 OUString sOldTypeName, sNewTypeName;
160 ::dbtools::OPropertyMap& rProp = OMetaConnection::getPropMap();
162 // type/typename
163 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPE)) >>= nOldType;
164 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPE)) >>= nNewType;
165 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPENAME)) >>= sOldTypeName;
166 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPENAME))>>= sNewTypeName;
168 // and precision and scale
169 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_PRECISION)) >>= nOldPrec;
170 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_PRECISION))>>= nNewPrec;
171 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_SCALE)) >>= nOldScale;
172 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_SCALE)) >>= nNewScale;
174 // second: check the "is nullable" value
175 sal_Int32 nOldNullable = 0,nNewNullable = 0;
176 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISNULLABLE)) >>= nOldNullable;
177 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISNULLABLE)) >>= nNewNullable;
179 // check also the auto_increment
180 bool bOldAutoIncrement = false,bAutoIncrement = false;
181 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT)) >>= bOldAutoIncrement;
182 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT)) >>= bAutoIncrement;
184 // now we should look if the name of the column changed
185 OUString sNewColumnName;
186 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_NAME)) >>= sNewColumnName;
187 if ( sNewColumnName != colName )
189 const OUString sQuote = getMetaData()->getIdentifierQuoteString( );
191 OUString sSql = getAlterTableColumnPart() +
192 " ALTER COLUMN " +
193 ::dbtools::quoteName(sQuote,colName) +
194 " RENAME TO " +
195 ::dbtools::quoteName(sQuote,sNewColumnName);
197 executeStatement(sSql);
200 if ( nOldType != nNewType
201 || sOldTypeName != sNewTypeName
202 || nOldPrec != nNewPrec
203 || nOldScale != nNewScale
204 || nNewNullable != nOldNullable
205 || bOldAutoIncrement != bAutoIncrement )
207 // special handling because they change the type names to distinguish
208 // if a column should be an auto_increment one
209 if ( bOldAutoIncrement != bAutoIncrement )
211 /// TODO: insert special handling for auto increment "IDENTITY" and primary key
213 alterColumnType(nNewType,sNewColumnName,descriptor);
216 // third: check the default values
217 OUString sNewDefault,sOldDefault;
218 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_DEFAULTVALUE)) >>= sOldDefault;
219 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_DEFAULTVALUE)) >>= sNewDefault;
221 if(!sOldDefault.isEmpty())
223 dropDefaultValue(colName);
224 if(!sNewDefault.isEmpty() && sOldDefault != sNewDefault)
225 alterDefaultValue(sNewDefault,sNewColumnName);
227 else if(sOldDefault.isEmpty() && !sNewDefault.isEmpty())
228 alterDefaultValue(sNewDefault,sNewColumnName);
230 m_xColumns->refresh();
232 else
234 if(m_xColumns)
236 m_xColumns->dropByName(colName);
237 m_xColumns->appendByDescriptor(descriptor);
243 void OHSQLTable::alterColumnType(sal_Int32 nNewType,const OUString& _rColName, const Reference<XPropertySet>& _xDescriptor)
245 OUString sSql = getAlterTableColumnPart() + " ALTER COLUMN ";
246 #if OSL_DEBUG_LEVEL > 0
249 OUString sDescriptorName;
250 OSL_ENSURE( _xDescriptor.is()
251 && ( _xDescriptor->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_NAME ) ) >>= sDescriptorName )
252 && ( sDescriptorName == _rColName ),
253 "OHSQLTable::alterColumnType: unexpected column name!" );
255 catch( const Exception& )
257 DBG_UNHANDLED_EXCEPTION("connectivity.hsqldb");
259 #else
260 (void)_rColName;
261 #endif
263 rtl::Reference<OHSQLColumn> pColumn = new OHSQLColumn;
264 ::comphelper::copyProperties(_xDescriptor,pColumn);
265 pColumn->setPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE),makeAny(nNewType));
267 sSql += ::dbtools::createStandardColumnPart(pColumn,getConnection());
268 executeStatement(sSql);
271 void OHSQLTable::alterDefaultValue(std::u16string_view _sNewDefault,const OUString& _rColName)
273 const OUString sQuote = getMetaData()->getIdentifierQuoteString( );
274 OUString sSql = getAlterTableColumnPart() +
275 " ALTER COLUMN " +
276 ::dbtools::quoteName(sQuote,_rColName) +
277 " SET DEFAULT '" + _sNewDefault + "'";
279 executeStatement(sSql);
282 void OHSQLTable::dropDefaultValue(const OUString& _rColName)
284 const OUString sQuote = getMetaData()->getIdentifierQuoteString( );
285 OUString sSql = getAlterTableColumnPart() +
286 " ALTER COLUMN " +
287 ::dbtools::quoteName(sQuote,_rColName) +
288 " DROP DEFAULT";
290 executeStatement(sSql);
293 OUString OHSQLTable::getAlterTableColumnPart() const
295 OUString sSql( "ALTER TABLE " );
297 OUString sComposedName( ::dbtools::composeTableName( getMetaData(), m_CatalogName, m_SchemaName, m_Name, true, ::dbtools::EComposeRule::InTableDefinitions ) );
298 sSql += sComposedName;
300 return sSql;
303 void OHSQLTable::executeStatement(const OUString& _rStatement )
305 OUString sSQL = _rStatement;
306 if(sSQL.endsWith(","))
307 sSQL = sSQL.replaceAt(sSQL.getLength()-1, 1, ")");
309 Reference< XStatement > xStmt = getConnection()->createStatement( );
310 if ( xStmt.is() )
312 try { xStmt->execute(sSQL); }
313 catch( const Exception& )
315 ::comphelper::disposeComponent(xStmt);
316 throw;
318 ::comphelper::disposeComponent(xStmt);
322 Sequence< Type > SAL_CALL OHSQLTable::getTypes( )
324 if ( m_Type == "VIEW" )
326 Sequence< Type > aTypes = OTableHelper::getTypes();
327 std::vector<Type> aOwnTypes;
328 aOwnTypes.reserve(aTypes.getLength());
329 const Type* pIter = aTypes.getConstArray();
330 const Type* pEnd = pIter + aTypes.getLength();
331 for(;pIter != pEnd;++pIter)
333 if( *pIter != cppu::UnoType<XRename>::get())
335 aOwnTypes.push_back(*pIter);
338 return Sequence< Type >(aOwnTypes.data(), aOwnTypes.size());
340 return OTableHelper::getTypes();
343 // XRename
344 void SAL_CALL OHSQLTable::rename( const OUString& newName )
346 ::osl::MutexGuard aGuard(m_aMutex);
347 checkDisposed(
348 #ifdef __GNUC__
349 ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
350 #else
351 rBHelper.bDisposed
352 #endif
355 if(!isNew())
357 OUString sSql = "ALTER ";
358 if ( m_Type == "VIEW" )
359 sSql += " VIEW ";
360 else
361 sSql += " TABLE ";
363 OUString sCatalog,sSchema,sTable;
364 ::dbtools::qualifiedNameComponents(getMetaData(),newName,sCatalog,sSchema,sTable,::dbtools::EComposeRule::InDataManipulation);
366 sSql +=
367 ::dbtools::composeTableName( getMetaData(), m_CatalogName, m_SchemaName, m_Name, true, ::dbtools::EComposeRule::InDataManipulation )
368 + " RENAME TO "
369 + ::dbtools::composeTableName( getMetaData(), sCatalog, sSchema, sTable, true, ::dbtools::EComposeRule::InDataManipulation );
371 executeStatement(sSql);
373 ::connectivity::OTable_TYPEDEF::rename(newName);
375 else
376 ::dbtools::qualifiedNameComponents(getMetaData(),newName,m_CatalogName,m_SchemaName,m_Name,::dbtools::EComposeRule::InTableDefinitions);
380 Any SAL_CALL OHSQLTable::queryInterface( const Type & rType )
382 if( m_Type == "VIEW" && rType == cppu::UnoType<XRename>::get())
383 return Any();
385 return OTableHelper::queryInterface(rType);
389 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */