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,
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
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
;
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
)
121 getStatics().refl
.table
.implName
,
122 getStatics().refl
.table
.serviceNames
,
126 * getStatics().refl
.table
.pProps
),
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(
147 extractStringProperty( this, getStatics().SCHEMA_NAME
),
148 extractStringProperty( this, getStatics().NAME
),
154 Reference
< XNameAccess
> Table::getIndexes() throw (::com::sun::star::uno::RuntimeException
)
156 if( ! m_indexes
.is() )
158 m_indexes
= ::pq_sdbc_driver::Indexes::create(
162 extractStringProperty( this, getStatics().SCHEMA_NAME
),
163 extractStringProperty( this, getStatics().NAME
) );
168 Reference
< XIndexAccess
> Table::getKeys( ) throw (::com::sun::star::uno::RuntimeException
)
172 m_keys
= ::pq_sdbc_driver::Keys::create(
176 extractStringProperty( this, getStatics().SCHEMA_NAME
),
177 extractStringProperty( this, getStatics().NAME
) );
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
);
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
;
218 Xrename
->rename( newName
);
219 setPropertyValue_NoBroadcast_public( st
.SCHEMA_NAME
, makeAny(newSchemaName
) );
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();
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
),
282 m_conn
->createStatement(),
283 Reference
< com::sun::star::beans::XPropertySet
>( colums
->getByName( colName
), UNO_QUERY
) ,
286 if( colName
!= newName
)
288 // m_pColumns->rename( colName, newName );
289 m_pColumns
->refresh();
293 void Table::alterColumnByIndex(
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
),
307 m_conn
->createStatement(),
310 // m_pColumns->rename( oldName, newName );
311 m_pColumns
->refresh();
314 Sequence
<Type
> Table::getTypes() throw( RuntimeException
)
316 static cppu::OTypeCollection
*pCollection
;
319 MutexGuard
guard( osl::Mutex::getGlobalMutex() );
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
)
344 ret
= ReflectionBase::queryInterface( reqType
);
345 if( ! ret
.hasValue() )
346 ret
= ::cppu::queryInterface(
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 )
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
)
379 //________________________________________________________________________
380 TableDescriptor::TableDescriptor(
381 const ::rtl::Reference
< RefCountedMutex
> & refMutex
,
382 const Reference
< com::sun::star::sdbc::XConnection
> & connection
,
383 ConnectionSettings
*pSettings
)
385 getStatics().refl
.tableDescriptor
.implName
,
386 getStatics().refl
.tableDescriptor
.serviceNames
,
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
);
403 Reference
< XNameAccess
> TableDescriptor::getIndexes() throw (::com::sun::star::uno::RuntimeException
)
405 if( ! m_indexes
.is() )
407 m_indexes
= ::pq_sdbc_driver::IndexDescriptors::create(
415 Reference
< XIndexAccess
> TableDescriptor::getKeys( ) throw (::com::sun::star::uno::RuntimeException
)
419 m_keys
= ::pq_sdbc_driver::KeyDescriptors::create(
428 Sequence
<Type
> TableDescriptor::getTypes() throw( RuntimeException
)
430 static cppu::OTypeCollection
*pCollection
;
433 MutexGuard
guard( osl::Mutex::getGlobalMutex() );
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
)
456 ret
= ReflectionBase::queryInterface( reqType
);
457 if( ! ret
.hasValue() )
458 ret
= ::cppu::queryInterface(
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 ));
467 Reference
< XPropertySet
> TableDescriptor::createDataDescriptor( ) throw (RuntimeException
)
469 TableDescriptor
* pTable
= new TableDescriptor(
470 m_refMutex
, m_conn
, m_pSettings
);
473 pTable
->m_values
= m_values
;
475 return Reference
< XPropertySet
> ( pTable
);