1 /*************************************************************************
3 * $RCSfile: pq_xtable.cxx,v $
7 * last change: $Author: jbu $ $Date: 2007/01/07 13:50:38 $
9 * The Contents of this file are made available subject to the terms of
10 * either of the following licenses
12 * - GNU Lesser General Public License Version 2.1
13 * - Sun Industry Standards Source License Version 1.1
15 * Sun Microsystems Inc., October, 2000
17 * GNU Lesser General Public License Version 2.1
18 * =============================================
19 * Copyright 2000 by Sun Microsystems, Inc.
20 * 901 San Antonio Road, Palo Alto, CA 94303, USA
22 * This library is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU Lesser General Public
24 * License version 2.1, as published by the Free Software Foundation.
26 * This library is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 * Lesser General Public License for more details.
31 * You should have received a copy of the GNU Lesser General Public
32 * License along with this library; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
37 * Sun Industry Standards Source License Version 1.1
38 * =================================================
39 * The contents of this file are subject to the Sun Industry Standards
40 * Source License Version 1.1 (the "License"); You may not use this file
41 * except in compliance with the License. You may obtain a copy of the
42 * License at http://www.openoffice.org/license.html.
44 * Software provided under this License is provided on an "AS IS" basis,
45 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
46 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
47 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
48 * See the License for the specific provisions governing your rights and
49 * obligations concerning the Software.
51 * The Initial Developer of the Original Code is: Joerg Budischewski
53 * Copyright: 2000 by Sun Microsystems, Inc.
55 * All Rights Reserved.
57 * Contributor(s): Joerg Budischewski
60 ************************************************************************/
62 #include <rtl/ustrbuf.hxx>
64 #include <cppuhelper/typeprovider.hxx>
65 #include <cppuhelper/queryinterface.hxx>
67 #include <com/sun/star/beans/PropertyAttribute.hpp>
69 #include <com/sun/star/sdbc/XRow.hpp>
70 #include <com/sun/star/sdbc/XParameters.hpp>
72 #include "pq_xtable.hxx"
73 #include "pq_xtables.hxx"
74 #include "pq_xviews.hxx"
75 #include "pq_xindexes.hxx"
76 #include "pq_xkeys.hxx"
77 #include "pq_xcolumns.hxx"
78 #include "pq_tools.hxx"
79 #include "pq_statics.hxx"
81 using osl::MutexGuard
;
85 using rtl::OUStringBuffer
;
86 using rtl::OUStringToOString
;
88 using com::sun::star::container::XNameAccess
;
89 using com::sun::star::container::XIndexAccess
;
90 using com::sun::star::container::ElementExistException
;
91 using com::sun::star::container::NoSuchElementException
;
93 using com::sun::star::uno::Reference
;
94 using com::sun::star::uno::Exception
;
95 using com::sun::star::uno::UNO_QUERY
;
96 using com::sun::star::uno::XInterface
;
97 using com::sun::star::uno::Sequence
;
98 using com::sun::star::uno::Any
;
99 using com::sun::star::uno::makeAny
;
100 using com::sun::star::uno::Type
;
101 using com::sun::star::uno::RuntimeException
;
103 using com::sun::star::lang::IllegalArgumentException
;
104 using com::sun::star::lang::IndexOutOfBoundsException
;
106 using com::sun::star::beans::XPropertySetInfo
;
107 using com::sun::star::beans::XFastPropertySet
;
108 using com::sun::star::beans::XMultiPropertySet
;
109 using com::sun::star::beans::XPropertySet
;
110 using com::sun::star::beans::Property
;
112 using com::sun::star::sdbc::XResultSet
;
113 using com::sun::star::sdbc::XPreparedStatement
;
114 using com::sun::star::sdbc::XStatement
;
115 using com::sun::star::sdbc::XParameters
;
116 using com::sun::star::sdbc::XRow
;
117 using com::sun::star::sdbc::SQLException
;
119 namespace pq_sdbc_driver
121 #define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
123 Table::Table( const ::rtl::Reference
< RefCountedMutex
> & refMutex
,
124 const Reference
< com::sun::star::sdbc::XConnection
> & connection
,
125 ConnectionSettings
*pSettings
)
127 getStatics().refl
.table
.implName
,
128 getStatics().refl
.table
.serviceNames
,
132 * getStatics().refl
.table
.pProps
),
136 Reference
< XPropertySet
> Table::createDataDescriptor( ) throw (RuntimeException
)
138 TableDescriptor
* pTable
= new TableDescriptor(
139 m_refMutex
, m_conn
, m_pSettings
);
140 pTable
->copyValuesFrom( this );
142 return Reference
< XPropertySet
> ( pTable
);
145 Reference
< XNameAccess
> Table::getColumns( ) throw (::com::sun::star::uno::RuntimeException
)
147 if( ! m_columns
.is() )
149 m_columns
= Columns::create(
153 extractStringProperty( this, getStatics().SCHEMA_NAME
),
154 extractStringProperty( this, getStatics().NAME
),
160 Reference
< XNameAccess
> Table::getIndexes() throw (::com::sun::star::uno::RuntimeException
)
162 if( ! m_indexes
.is() )
164 m_indexes
= ::pq_sdbc_driver::Indexes::create(
168 extractStringProperty( this, getStatics().SCHEMA_NAME
),
169 extractStringProperty( this, getStatics().NAME
) );
174 Reference
< XIndexAccess
> Table::getKeys( ) throw (::com::sun::star::uno::RuntimeException
)
178 m_keys
= ::pq_sdbc_driver::Keys::create(
182 extractStringProperty( this, getStatics().SCHEMA_NAME
),
183 extractStringProperty( this, getStatics().NAME
) );
188 void Table::rename( const ::rtl::OUString
& newName
)
189 throw (::com::sun::star::sdbc::SQLException
,
190 ::com::sun::star::container::ElementExistException
,
191 ::com::sun::star::uno::RuntimeException
)
193 MutexGuard
guard( m_refMutex
->mutex
);
194 Statics
& st
= getStatics();
196 ::rtl::OUString oldName
= extractStringProperty(this,st
.NAME
);
197 ::rtl::OUString schema
= extractStringProperty(this,st
.SCHEMA_NAME
);
198 ::rtl::OUString fullOldName
= concatQualified( schema
, oldName
);
200 OUString newTableName
;
201 OUString newSchemaName
;
202 // OOo2.0 passes schema + dot + new-table-name while
203 // OO1.1.x passes new Name without schema
204 // in case name contains a dot, it is interpreted as schema.tablename
205 if( newName
.indexOf( '.' ) >= 0 )
207 splitConcatenatedIdentifier( newName
, &newSchemaName
, &newTableName
);
211 newTableName
= newName
;
212 newSchemaName
= schema
;
214 ::rtl::OUString fullNewName
= concatQualified( newSchemaName
, newTableName
);
216 if( extractStringProperty( this, st
.TYPE
).equals( st
.VIEW
) && m_pSettings
->views
.is() )
218 // maintain view list (really strange API !)
219 Any a
= m_pSettings
->pViewsImpl
->getByName( fullOldName
);
220 Reference
< com::sun::star::sdbcx::XRename
> rename
;
224 rename
->rename( newName
);
225 setPropertyValue_NoBroadcast_public( st
.SCHEMA_NAME
, makeAny(newSchemaName
) );
230 if( ! newSchemaName
.equals(schema
) )
232 // try new schema name first
235 OUStringBuffer
buf(128);
236 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) );
237 bufferQuoteQualifiedIdentifier(buf
, schema
, oldName
);
238 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("SET SCHEMA" ) );
239 bufferQuoteIdentifier( buf
, newSchemaName
);
240 Reference
< XStatement
> statement
= m_conn
->createStatement();
241 statement
->executeUpdate( buf
.makeStringAndClear() );
242 setPropertyValue_NoBroadcast_public( st
.SCHEMA_NAME
, makeAny(newSchemaName
) );
243 disposeNoThrow( statement
);
244 schema
= newSchemaName
;
246 catch( com::sun::star::sdbc::SQLException
&e
)
248 OUStringBuffer
buf( e
.Message
);
249 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "(NOTE: Only postgresql server >= V8.1 support changing a table's schema)" ) );
250 e
.Message
= buf
.makeStringAndClear();
255 if( ! newTableName
.equals( oldName
) ) // might also be just the change of a schema name
257 OUStringBuffer
buf(128);
258 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE" ) );
259 bufferQuoteQualifiedIdentifier(buf
, schema
, oldName
);
260 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("RENAME TO" ) );
261 bufferQuoteIdentifier( buf
, newTableName
);
262 Reference
< XStatement
> statement
= m_conn
->createStatement();
263 statement
->executeUpdate( buf
.makeStringAndClear() );
264 disposeNoThrow( statement
);
267 setPropertyValue_NoBroadcast_public( st
.NAME
, makeAny(newTableName
) );
268 // inform the container of the name change !
269 if( m_pSettings
->tables
.is() )
271 m_pSettings
->pTablesImpl
->rename( fullOldName
, fullNewName
);
275 void Table::alterColumnByName(
276 const ::rtl::OUString
& colName
,
277 const Reference
< XPropertySet
>& descriptor
)
278 throw (SQLException
,NoSuchElementException
,RuntimeException
)
280 Reference
< com::sun::star::container::XNameAccess
> colums
=
281 Reference
< com::sun::star::container::XNameAccess
> ( getColumns(), UNO_QUERY
);
283 OUString newName
= extractStringProperty(descriptor
, getStatics().NAME
);
284 ::pq_sdbc_driver::alterColumnByDescriptor(
285 extractStringProperty( this, getStatics().SCHEMA_NAME
),
286 extractStringProperty( this, getStatics().NAME
),
287 m_pSettings
->encoding
,
288 m_conn
->createStatement(),
289 Reference
< com::sun::star::beans::XPropertySet
>( colums
->getByName( colName
), UNO_QUERY
) ,
292 if( colName
!= newName
)
294 // m_pColumns->rename( colName, newName );
295 m_pColumns
->refresh();
299 void Table::alterColumnByIndex(
301 const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
>& descriptor
)
302 throw (SQLException
,IndexOutOfBoundsException
,RuntimeException
)
304 Reference
< com::sun::star::container::XIndexAccess
> colums
=
305 Reference
< com::sun::star::container::XIndexAccess
>( getColumns(), UNO_QUERY
);
306 Reference
< com::sun::star::beans::XPropertySet
> column(colums
->getByIndex( index
), UNO_QUERY
);
307 OUString oldName
= extractStringProperty( column
, getStatics().NAME
);
308 OUString newName
= extractStringProperty( descriptor
, getStatics().NAME
);
309 ::pq_sdbc_driver::alterColumnByDescriptor(
310 extractStringProperty( this, getStatics().SCHEMA_NAME
),
311 extractStringProperty( this, getStatics().NAME
),
312 m_pSettings
->encoding
,
313 m_conn
->createStatement(),
316 // m_pColumns->rename( oldName, newName );
317 m_pColumns
->refresh();
320 Sequence
<Type
> Table::getTypes() throw( RuntimeException
)
322 static cppu::OTypeCollection
*pCollection
;
325 MutexGuard
guard( osl::Mutex::getGlobalMutex() );
328 static cppu::OTypeCollection
collection(
329 getCppuType( (Reference
< com::sun::star::sdbcx::XIndexesSupplier
> *) 0 ),
330 getCppuType( (Reference
< com::sun::star::sdbcx::XKeysSupplier
> *) 0 ),
331 getCppuType( (Reference
< com::sun::star::sdbcx::XColumnsSupplier
> *) 0 ),
332 getCppuType( (Reference
< com::sun::star::sdbcx::XRename
> *) 0 ),
333 getCppuType( (Reference
< com::sun::star::sdbcx::XAlterTable
> *) 0 ),
334 ReflectionBase::getTypes());
335 pCollection
= &collection
;
338 return pCollection
->getTypes();
341 Sequence
< sal_Int8
> Table::getImplementationId() throw( RuntimeException
)
343 return getStatics().refl
.table
.implementationId
;
346 Any
Table::queryInterface( const Type
& reqType
) throw (RuntimeException
)
350 ret
= ReflectionBase::queryInterface( reqType
);
351 if( ! ret
.hasValue() )
352 ret
= ::cppu::queryInterface(
354 static_cast< com::sun::star::sdbcx::XIndexesSupplier
* > ( this ),
355 static_cast< com::sun::star::sdbcx::XKeysSupplier
* > ( this ),
356 static_cast< com::sun::star::sdbcx::XColumnsSupplier
* > ( this ),
357 static_cast< com::sun::star::sdbcx::XRename
* > ( this ),
358 static_cast< com::sun::star::sdbcx::XAlterTable
* > ( this )
363 ::com::sun::star::uno::Any
Table::getPropertyValue(const ::rtl::OUString
& aPropertyName
)
364 throw(::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::lang::WrappedTargetException
, ::com::sun::star::uno::RuntimeException
)
366 return ReflectionBase::getPropertyValue( aPropertyName
);
370 ::rtl::OUString
Table::getName( ) throw (::com::sun::star::uno::RuntimeException
)
372 Statics
& st
= getStatics();
373 return concatQualified(
374 extractStringProperty( this, st
.SCHEMA_NAME
),
375 extractStringProperty( this, st
.NAME
) );
378 void Table::setName( const ::rtl::OUString
& aName
) throw (::com::sun::star::uno::RuntimeException
)
385 //________________________________________________________________________
386 TableDescriptor::TableDescriptor(
387 const ::rtl::Reference
< RefCountedMutex
> & refMutex
,
388 const Reference
< com::sun::star::sdbc::XConnection
> & connection
,
389 ConnectionSettings
*pSettings
)
391 getStatics().refl
.tableDescriptor
.implName
,
392 getStatics().refl
.tableDescriptor
.serviceNames
,
396 * getStatics().refl
.tableDescriptor
.pProps
)
400 Reference
< XNameAccess
> TableDescriptor::getColumns( ) throw (::com::sun::star::uno::RuntimeException
)
402 if( ! m_columns
.is() )
404 m_columns
= new ColumnDescriptors(m_refMutex
, m_conn
, m_pSettings
);
409 Reference
< XNameAccess
> TableDescriptor::getIndexes() throw (::com::sun::star::uno::RuntimeException
)
411 if( ! m_indexes
.is() )
413 m_indexes
= ::pq_sdbc_driver::IndexDescriptors::create(
421 Reference
< XIndexAccess
> TableDescriptor::getKeys( ) throw (::com::sun::star::uno::RuntimeException
)
425 m_keys
= ::pq_sdbc_driver::KeyDescriptors::create(
434 Sequence
<Type
> TableDescriptor::getTypes() throw( RuntimeException
)
436 static cppu::OTypeCollection
*pCollection
;
439 MutexGuard
guard( osl::Mutex::getGlobalMutex() );
442 static cppu::OTypeCollection
collection(
443 getCppuType( (Reference
< com::sun::star::sdbcx::XIndexesSupplier
> *) 0 ),
444 getCppuType( (Reference
< com::sun::star::sdbcx::XKeysSupplier
> *) 0 ),
445 getCppuType( (Reference
< com::sun::star::sdbcx::XColumnsSupplier
> *) 0 ),
446 ReflectionBase::getTypes());
447 pCollection
= &collection
;
450 return pCollection
->getTypes();
453 Sequence
< sal_Int8
> TableDescriptor::getImplementationId() throw( RuntimeException
)
455 return getStatics().refl
.tableDescriptor
.implementationId
;
458 Any
TableDescriptor::queryInterface( const Type
& reqType
) throw (RuntimeException
)
462 ret
= ReflectionBase::queryInterface( reqType
);
463 if( ! ret
.hasValue() )
464 ret
= ::cppu::queryInterface(
466 static_cast< com::sun::star::sdbcx::XIndexesSupplier
* > ( this ),
467 static_cast< com::sun::star::sdbcx::XKeysSupplier
* > ( this ),
468 static_cast< com::sun::star::sdbcx::XColumnsSupplier
* > ( this ));
473 Reference
< XPropertySet
> TableDescriptor::createDataDescriptor( ) throw (RuntimeException
)
475 TableDescriptor
* pTable
= new TableDescriptor(
476 m_refMutex
, m_conn
, m_pSettings
);
479 pTable
->m_values
= m_values
;
481 return Reference
< XPropertySet
> ( pTable
);