Bump for 3.6-28
[LibreOffice.git] / connectivity / source / drivers / postgresql / pq_xtable.cxx
blobe0eb97b03b7a355115ce88ae9d791410a6a2ce42
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * Effective License of whole file:
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License version 2.1, as published by the Free Software Foundation.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA
20 * Parts "Copyright by Sun Microsystems, Inc" prior to August 2011:
22 * The Contents of this file are made available subject to the terms of
23 * the GNU Lesser General Public License Version 2.1
25 * Copyright: 2000 by Sun Microsystems, Inc.
27 * Contributor(s): Joerg Budischewski
29 * All parts contributed on or after August 2011:
31 * Version: MPL 1.1 / GPLv3+ / LGPLv2.1+
33 * The contents of this file are subject to the Mozilla Public License Version
34 * 1.1 (the "License"); you may not use this file except in compliance with
35 * the License or as specified alternatively below. You may obtain a copy of
36 * the License at http://www.mozilla.org/MPL/
38 * Software distributed under the License is distributed on an "AS IS" basis,
39 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
40 * for the specific language governing rights and limitations under the
41 * License.
43 * Major Contributor(s):
44 * [ Copyright (C) 2011 Lionel Elie Mamane <lionel@mamane.lu> ]
46 * All Rights Reserved.
48 * For minor contributions see the git repository.
50 * Alternatively, the contents of this file may be used under the terms of
51 * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
52 * the GNU Lesser General Public License Version 2.1 or later (the "LGPLv2.1+"),
53 * in which case the provisions of the GPLv3+ or the LGPLv2.1+ are applicable
54 * instead of those above.
56 ************************************************************************/
58 #include <rtl/ustrbuf.hxx>
60 #include <cppuhelper/typeprovider.hxx>
61 #include <cppuhelper/queryinterface.hxx>
63 #include <com/sun/star/beans/PropertyAttribute.hpp>
65 #include <com/sun/star/sdbc/XRow.hpp>
66 #include <com/sun/star/sdbc/XParameters.hpp>
68 #include "pq_xtable.hxx"
69 #include "pq_xtables.hxx"
70 #include "pq_xviews.hxx"
71 #include "pq_xindexes.hxx"
72 #include "pq_xkeys.hxx"
73 #include "pq_xcolumns.hxx"
74 #include "pq_tools.hxx"
75 #include "pq_statics.hxx"
77 using osl::MutexGuard;
78 using osl::Mutex;
80 using rtl::OUString;
81 using rtl::OUStringBuffer;
82 using rtl::OUStringToOString;
84 using com::sun::star::container::XNameAccess;
85 using com::sun::star::container::XIndexAccess;
86 using com::sun::star::container::ElementExistException;
87 using com::sun::star::container::NoSuchElementException;
89 using com::sun::star::uno::Reference;
90 using com::sun::star::uno::Exception;
91 using com::sun::star::uno::UNO_QUERY;
92 using com::sun::star::uno::XInterface;
93 using com::sun::star::uno::Sequence;
94 using com::sun::star::uno::Any;
95 using com::sun::star::uno::makeAny;
96 using com::sun::star::uno::Type;
97 using com::sun::star::uno::RuntimeException;
99 using com::sun::star::lang::IllegalArgumentException;
100 using com::sun::star::lang::IndexOutOfBoundsException;
102 using com::sun::star::beans::XPropertySetInfo;
103 using com::sun::star::beans::XFastPropertySet;
104 using com::sun::star::beans::XMultiPropertySet;
105 using com::sun::star::beans::XPropertySet;
106 using com::sun::star::beans::Property;
108 using com::sun::star::sdbc::XResultSet;
109 using com::sun::star::sdbc::XPreparedStatement;
110 using com::sun::star::sdbc::XStatement;
111 using com::sun::star::sdbc::XParameters;
112 using com::sun::star::sdbc::XRow;
113 using com::sun::star::sdbc::SQLException;
115 namespace pq_sdbc_driver
117 Table::Table( const ::rtl::Reference< RefCountedMutex > & refMutex,
118 const Reference< com::sun::star::sdbc::XConnection > & connection,
119 ConnectionSettings *pSettings)
120 : ReflectionBase(
121 getStatics().refl.table.implName,
122 getStatics().refl.table.serviceNames,
123 refMutex,
124 connection,
125 pSettings,
126 * getStatics().refl.table.pProps ),
127 m_pColumns( 0 )
130 Reference< XPropertySet > Table::createDataDescriptor( ) throw (RuntimeException)
132 TableDescriptor * pTable = new TableDescriptor(
133 m_refMutex, m_conn, m_pSettings );
134 pTable->copyValuesFrom( this );
136 return Reference< XPropertySet > ( pTable );
139 Reference< XNameAccess > Table::getColumns( ) throw (::com::sun::star::uno::RuntimeException)
141 if( ! m_columns.is() )
143 m_columns = Columns::create(
144 m_refMutex,
145 m_conn,
146 m_pSettings,
147 extractStringProperty( this, getStatics().SCHEMA_NAME ),
148 extractStringProperty( this, getStatics().NAME ),
149 &m_pColumns);
151 return m_columns;
154 Reference< XNameAccess > Table::getIndexes() throw (::com::sun::star::uno::RuntimeException)
156 if( ! m_indexes.is() )
158 m_indexes = ::pq_sdbc_driver::Indexes::create(
159 m_refMutex,
160 m_conn,
161 m_pSettings,
162 extractStringProperty( this, getStatics().SCHEMA_NAME ),
163 extractStringProperty( this, getStatics().NAME ) );
165 return m_indexes;
168 Reference< XIndexAccess > Table::getKeys( ) throw (::com::sun::star::uno::RuntimeException)
170 if( ! m_keys.is() )
172 m_keys = ::pq_sdbc_driver::Keys::create(
173 m_refMutex,
174 m_conn,
175 m_pSettings,
176 extractStringProperty( this, getStatics().SCHEMA_NAME ),
177 extractStringProperty( this, getStatics().NAME ) );
179 return m_keys;
182 void Table::rename( const ::rtl::OUString& newName )
183 throw (::com::sun::star::sdbc::SQLException,
184 ::com::sun::star::container::ElementExistException,
185 ::com::sun::star::uno::RuntimeException)
187 MutexGuard guard( m_refMutex->mutex );
188 Statics & st = getStatics();
190 ::rtl::OUString oldName = extractStringProperty(this,st.NAME );
191 ::rtl::OUString schema = extractStringProperty(this,st.SCHEMA_NAME );
192 ::rtl::OUString fullOldName = concatQualified( schema, oldName );
194 OUString newTableName;
195 OUString newSchemaName;
196 // OOo2.0 passes schema + dot + new-table-name while
197 // OO1.1.x passes new Name without schema
198 // in case name contains a dot, it is interpreted as schema.tablename
199 if( newName.indexOf( '.' ) >= 0 )
201 splitConcatenatedIdentifier( newName, &newSchemaName, &newTableName );
203 else
205 newTableName = newName;
206 newSchemaName = schema;
208 ::rtl::OUString fullNewName = concatQualified( newSchemaName, newTableName );
210 if( extractStringProperty( this, st.TYPE ).equals( st.VIEW ) && m_pSettings->views.is() )
212 // maintain view list (really strange API !)
213 Any a = m_pSettings->pViewsImpl->getByName( fullOldName );
214 Reference< com::sun::star::sdbcx::XRename > Xrename;
215 a >>= Xrename;
216 if( Xrename.is() )
218 Xrename->rename( newName );
219 setPropertyValue_NoBroadcast_public( st.SCHEMA_NAME, makeAny(newSchemaName) );
222 else
224 if( ! newSchemaName.equals(schema) )
226 // try new schema name first
229 OUStringBuffer buf(128);
230 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) );
231 bufferQuoteQualifiedIdentifier(buf, schema, oldName, m_pSettings );
232 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("SET SCHEMA" ) );
233 bufferQuoteIdentifier( buf, newSchemaName, m_pSettings );
234 Reference< XStatement > statement = m_conn->createStatement();
235 statement->executeUpdate( buf.makeStringAndClear() );
236 setPropertyValue_NoBroadcast_public( st.SCHEMA_NAME, makeAny(newSchemaName) );
237 disposeNoThrow( statement );
238 schema = newSchemaName;
240 catch( com::sun::star::sdbc::SQLException &e )
242 OUStringBuffer buf( e.Message );
243 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "(NOTE: Only postgresql server >= V8.1 support changing a table's schema)" ) );
244 e.Message = buf.makeStringAndClear();
245 throw;
249 if( ! newTableName.equals( oldName ) ) // might also be just the change of a schema name
251 OUStringBuffer buf(128);
252 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) );
253 bufferQuoteQualifiedIdentifier(buf, schema, oldName, m_pSettings );
254 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("RENAME TO" ) );
255 bufferQuoteIdentifier( buf, newTableName, m_pSettings );
256 Reference< XStatement > statement = m_conn->createStatement();
257 statement->executeUpdate( buf.makeStringAndClear() );
258 disposeNoThrow( statement );
261 setPropertyValue_NoBroadcast_public( st.NAME, makeAny(newTableName) );
262 // inform the container of the name change !
263 if( m_pSettings->tables.is() )
265 m_pSettings->pTablesImpl->rename( fullOldName, fullNewName );
269 void Table::alterColumnByName(
270 const ::rtl::OUString& colName,
271 const Reference< XPropertySet >& descriptor )
272 throw (SQLException,NoSuchElementException,RuntimeException)
274 Reference< com::sun::star::container::XNameAccess > colums =
275 Reference< com::sun::star::container::XNameAccess > ( getColumns(), UNO_QUERY );
277 OUString newName = extractStringProperty(descriptor, getStatics().NAME );
278 ::pq_sdbc_driver::alterColumnByDescriptor(
279 extractStringProperty( this, getStatics().SCHEMA_NAME ),
280 extractStringProperty( this, getStatics().NAME ),
281 m_pSettings,
282 m_conn->createStatement(),
283 Reference< com::sun::star::beans::XPropertySet>( colums->getByName( colName ), UNO_QUERY) ,
284 descriptor );
286 if( colName != newName )
288 // m_pColumns->rename( colName, newName );
289 m_pColumns->refresh();
293 void Table::alterColumnByIndex(
294 sal_Int32 index,
295 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor )
296 throw (SQLException,IndexOutOfBoundsException,RuntimeException)
298 Reference< com::sun::star::container::XIndexAccess > colums =
299 Reference< com::sun::star::container::XIndexAccess>( getColumns(), UNO_QUERY );
300 Reference< com::sun::star::beans::XPropertySet> column(colums->getByIndex( index ), UNO_QUERY );
301 OUString oldName = extractStringProperty( column, getStatics().NAME );
302 OUString newName = extractStringProperty( descriptor, getStatics().NAME );
303 ::pq_sdbc_driver::alterColumnByDescriptor(
304 extractStringProperty( this, getStatics().SCHEMA_NAME ),
305 extractStringProperty( this, getStatics().NAME ),
306 m_pSettings,
307 m_conn->createStatement(),
308 column,
309 descriptor );
310 // m_pColumns->rename( oldName, newName );
311 m_pColumns->refresh();
314 Sequence<Type > Table::getTypes() throw( RuntimeException )
316 static cppu::OTypeCollection *pCollection;
317 if( ! pCollection )
319 MutexGuard guard( osl::Mutex::getGlobalMutex() );
320 if( !pCollection )
322 static cppu::OTypeCollection collection(
323 getCppuType( (Reference< com::sun::star::sdbcx::XIndexesSupplier> *) 0 ),
324 getCppuType( (Reference< com::sun::star::sdbcx::XKeysSupplier> *) 0 ),
325 getCppuType( (Reference< com::sun::star::sdbcx::XColumnsSupplier> *) 0 ),
326 getCppuType( (Reference< com::sun::star::sdbcx::XRename> *) 0 ),
327 getCppuType( (Reference< com::sun::star::sdbcx::XAlterTable> *) 0 ),
328 ReflectionBase::getTypes());
329 pCollection = &collection;
332 return pCollection->getTypes();
335 Sequence< sal_Int8> Table::getImplementationId() throw( RuntimeException )
337 return getStatics().refl.table.implementationId;
340 Any Table::queryInterface( const Type & reqType ) throw (RuntimeException)
342 Any ret;
344 ret = ReflectionBase::queryInterface( reqType );
345 if( ! ret.hasValue() )
346 ret = ::cppu::queryInterface(
347 reqType,
348 static_cast< com::sun::star::sdbcx::XIndexesSupplier * > ( this ),
349 static_cast< com::sun::star::sdbcx::XKeysSupplier * > ( this ),
350 static_cast< com::sun::star::sdbcx::XColumnsSupplier * > ( this ),
351 static_cast< com::sun::star::sdbcx::XRename * > ( this ),
352 static_cast< com::sun::star::sdbcx::XAlterTable * > ( this )
354 return ret;
357 ::com::sun::star::uno::Any Table::getPropertyValue(const ::rtl::OUString& aPropertyName)
358 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
360 return ReflectionBase::getPropertyValue( aPropertyName );
364 ::rtl::OUString Table::getName( ) throw (::com::sun::star::uno::RuntimeException)
366 Statics & st = getStatics();
367 return concatQualified(
368 extractStringProperty( this, st.SCHEMA_NAME ),
369 extractStringProperty( this, st.NAME ) );
372 void Table::setName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException)
374 rename( aName );
379 //________________________________________________________________________
380 TableDescriptor::TableDescriptor(
381 const ::rtl::Reference< RefCountedMutex > & refMutex,
382 const Reference< com::sun::star::sdbc::XConnection > & connection,
383 ConnectionSettings *pSettings)
384 : ReflectionBase(
385 getStatics().refl.tableDescriptor.implName,
386 getStatics().refl.tableDescriptor.serviceNames,
387 refMutex,
388 connection,
389 pSettings,
390 * getStatics().refl.tableDescriptor.pProps )
394 Reference< XNameAccess > TableDescriptor::getColumns( ) throw (::com::sun::star::uno::RuntimeException)
396 if( ! m_columns.is() )
398 m_columns = new ColumnDescriptors(m_refMutex, m_conn, m_pSettings );
400 return m_columns;
403 Reference< XNameAccess > TableDescriptor::getIndexes() throw (::com::sun::star::uno::RuntimeException)
405 if( ! m_indexes.is() )
407 m_indexes = ::pq_sdbc_driver::IndexDescriptors::create(
408 m_refMutex,
409 m_conn,
410 m_pSettings);
412 return m_indexes;
415 Reference< XIndexAccess > TableDescriptor::getKeys( ) throw (::com::sun::star::uno::RuntimeException)
417 if( ! m_keys.is() )
419 m_keys = ::pq_sdbc_driver::KeyDescriptors::create(
420 m_refMutex,
421 m_conn,
422 m_pSettings );
424 return m_keys;
428 Sequence<Type > TableDescriptor::getTypes() throw( RuntimeException )
430 static cppu::OTypeCollection *pCollection;
431 if( ! pCollection )
433 MutexGuard guard( osl::Mutex::getGlobalMutex() );
434 if( !pCollection )
436 static cppu::OTypeCollection collection(
437 getCppuType( (Reference< com::sun::star::sdbcx::XIndexesSupplier> *) 0 ),
438 getCppuType( (Reference< com::sun::star::sdbcx::XKeysSupplier> *) 0 ),
439 getCppuType( (Reference< com::sun::star::sdbcx::XColumnsSupplier> *) 0 ),
440 ReflectionBase::getTypes());
441 pCollection = &collection;
444 return pCollection->getTypes();
447 Sequence< sal_Int8> TableDescriptor::getImplementationId() throw( RuntimeException )
449 return getStatics().refl.tableDescriptor.implementationId;
452 Any TableDescriptor::queryInterface( const Type & reqType ) throw (RuntimeException)
454 Any ret;
456 ret = ReflectionBase::queryInterface( reqType );
457 if( ! ret.hasValue() )
458 ret = ::cppu::queryInterface(
459 reqType,
460 static_cast< com::sun::star::sdbcx::XIndexesSupplier * > ( this ),
461 static_cast< com::sun::star::sdbcx::XKeysSupplier * > ( this ),
462 static_cast< com::sun::star::sdbcx::XColumnsSupplier * > ( this ));
463 return ret;
467 Reference< XPropertySet > TableDescriptor::createDataDescriptor( ) throw (RuntimeException)
469 TableDescriptor * pTable = new TableDescriptor(
470 m_refMutex, m_conn, m_pSettings );
472 // TODO: deep copies
473 pTable->m_values = m_values;
475 return Reference< XPropertySet > ( pTable );