Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * Effective License of whole file:
5 : *
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.
9 : *
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.
14 : *
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
19 : *
20 : * Parts "Copyright by Sun Microsystems, Inc" prior to August 2011:
21 : *
22 : * The Contents of this file are made available subject to the terms of
23 : * the GNU Lesser General Public License Version 2.1
24 : *
25 : * Copyright: 2000 by Sun Microsystems, Inc.
26 : *
27 : * Contributor(s): Joerg Budischewski
28 : *
29 : * All parts contributed on or after August 2011:
30 : *
31 : * This Source Code Form is subject to the terms of the Mozilla Public
32 : * License, v. 2.0. If a copy of the MPL was not distributed with this
33 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
34 : *
35 : ************************************************************************/
36 :
37 : #include <rtl/ustrbuf.hxx>
38 :
39 : #include <cppuhelper/typeprovider.hxx>
40 : #include <cppuhelper/queryinterface.hxx>
41 :
42 : #include <com/sun/star/beans/PropertyAttribute.hpp>
43 :
44 : #include <com/sun/star/sdbc/XRow.hpp>
45 : #include <com/sun/star/sdbc/XParameters.hpp>
46 :
47 : #include "pq_xtable.hxx"
48 : #include "pq_xtables.hxx"
49 : #include "pq_xviews.hxx"
50 : #include "pq_xindexes.hxx"
51 : #include "pq_xkeys.hxx"
52 : #include "pq_xcolumns.hxx"
53 : #include "pq_tools.hxx"
54 : #include "pq_statics.hxx"
55 :
56 : using osl::MutexGuard;
57 : using osl::Mutex;
58 :
59 : using com::sun::star::container::XNameAccess;
60 : using com::sun::star::container::XIndexAccess;
61 : using com::sun::star::container::ElementExistException;
62 : using com::sun::star::container::NoSuchElementException;
63 :
64 : using com::sun::star::uno::Reference;
65 : using com::sun::star::uno::Exception;
66 : using com::sun::star::uno::UNO_QUERY;
67 : using com::sun::star::uno::XInterface;
68 : using com::sun::star::uno::Sequence;
69 : using com::sun::star::uno::Any;
70 : using com::sun::star::uno::makeAny;
71 : using com::sun::star::uno::Type;
72 : using com::sun::star::uno::RuntimeException;
73 :
74 : using com::sun::star::lang::IllegalArgumentException;
75 : using com::sun::star::lang::IndexOutOfBoundsException;
76 :
77 : using com::sun::star::beans::XPropertySetInfo;
78 : using com::sun::star::beans::XFastPropertySet;
79 : using com::sun::star::beans::XMultiPropertySet;
80 : using com::sun::star::beans::XPropertySet;
81 : using com::sun::star::beans::Property;
82 :
83 : using com::sun::star::sdbc::XResultSet;
84 : using com::sun::star::sdbc::XPreparedStatement;
85 : using com::sun::star::sdbc::XStatement;
86 : using com::sun::star::sdbc::XParameters;
87 : using com::sun::star::sdbc::XRow;
88 : using com::sun::star::sdbc::SQLException;
89 :
90 : namespace pq_sdbc_driver
91 : {
92 0 : Table::Table( const ::rtl::Reference< RefCountedMutex > & refMutex,
93 : const Reference< com::sun::star::sdbc::XConnection > & connection,
94 : ConnectionSettings *pSettings)
95 : : ReflectionBase(
96 0 : getStatics().refl.table.implName,
97 0 : getStatics().refl.table.serviceNames,
98 : refMutex,
99 : connection,
100 : pSettings,
101 0 : * getStatics().refl.table.pProps ),
102 0 : m_pColumns( 0 )
103 0 : {}
104 :
105 0 : Reference< XPropertySet > Table::createDataDescriptor( ) throw (RuntimeException, std::exception)
106 : {
107 : TableDescriptor * pTable = new TableDescriptor(
108 0 : m_refMutex, m_conn, m_pSettings );
109 0 : pTable->copyValuesFrom( this );
110 :
111 0 : return Reference< XPropertySet > ( pTable );
112 : }
113 :
114 0 : Reference< XNameAccess > Table::getColumns( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
115 : {
116 0 : if( ! m_columns.is() )
117 : {
118 0 : m_columns = Columns::create(
119 : m_refMutex,
120 : m_conn,
121 : m_pSettings,
122 0 : extractStringProperty( this, getStatics().SCHEMA_NAME ),
123 0 : extractStringProperty( this, getStatics().NAME ),
124 0 : &m_pColumns);
125 : }
126 0 : return m_columns;
127 : }
128 :
129 0 : Reference< XNameAccess > Table::getIndexes() throw (::com::sun::star::uno::RuntimeException, std::exception)
130 : {
131 0 : if( ! m_indexes.is() )
132 : {
133 0 : m_indexes = ::pq_sdbc_driver::Indexes::create(
134 : m_refMutex,
135 : m_conn,
136 : m_pSettings,
137 0 : extractStringProperty( this, getStatics().SCHEMA_NAME ),
138 0 : extractStringProperty( this, getStatics().NAME ) );
139 : }
140 0 : return m_indexes;
141 : }
142 :
143 0 : Reference< XIndexAccess > Table::getKeys( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
144 : {
145 0 : if( ! m_keys.is() )
146 : {
147 0 : m_keys = ::pq_sdbc_driver::Keys::create(
148 : m_refMutex,
149 : m_conn,
150 : m_pSettings,
151 0 : extractStringProperty( this, getStatics().SCHEMA_NAME ),
152 0 : extractStringProperty( this, getStatics().NAME ) );
153 : }
154 0 : return m_keys;
155 : }
156 :
157 0 : void Table::rename( const OUString& newName )
158 : throw (::com::sun::star::sdbc::SQLException,
159 : ::com::sun::star::container::ElementExistException,
160 : ::com::sun::star::uno::RuntimeException, std::exception)
161 : {
162 0 : MutexGuard guard( m_refMutex->mutex );
163 0 : Statics & st = getStatics();
164 :
165 0 : OUString oldName = extractStringProperty(this,st.NAME );
166 0 : OUString schema = extractStringProperty(this,st.SCHEMA_NAME );
167 0 : OUString fullOldName = concatQualified( schema, oldName );
168 :
169 0 : OUString newTableName;
170 0 : OUString newSchemaName;
171 : // OOo2.0 passes schema + dot + new-table-name while
172 : // OO1.1.x passes new Name without schema
173 : // in case name contains a dot, it is interpreted as schema.tablename
174 0 : if( newName.indexOf( '.' ) >= 0 )
175 : {
176 0 : splitConcatenatedIdentifier( newName, &newSchemaName, &newTableName );
177 : }
178 : else
179 : {
180 0 : newTableName = newName;
181 0 : newSchemaName = schema;
182 : }
183 0 : OUString fullNewName = concatQualified( newSchemaName, newTableName );
184 :
185 0 : if( extractStringProperty( this, st.TYPE ).equals( st.VIEW ) && m_pSettings->views.is() )
186 : {
187 : // maintain view list (really strange API !)
188 0 : Any a = m_pSettings->pViewsImpl->getByName( fullOldName );
189 0 : Reference< com::sun::star::sdbcx::XRename > Xrename;
190 0 : a >>= Xrename;
191 0 : if( Xrename.is() )
192 : {
193 0 : Xrename->rename( newName );
194 0 : setPropertyValue_NoBroadcast_public( st.SCHEMA_NAME, makeAny(newSchemaName) );
195 0 : }
196 : }
197 : else
198 : {
199 0 : if( ! newSchemaName.equals(schema) )
200 : {
201 : // try new schema name first
202 : try
203 : {
204 0 : OUStringBuffer buf(128);
205 0 : buf.append( "ALTER TABLE" );
206 0 : bufferQuoteQualifiedIdentifier(buf, schema, oldName, m_pSettings );
207 0 : buf.append( "SET SCHEMA" );
208 0 : bufferQuoteIdentifier( buf, newSchemaName, m_pSettings );
209 0 : Reference< XStatement > statement = m_conn->createStatement();
210 0 : statement->executeUpdate( buf.makeStringAndClear() );
211 0 : setPropertyValue_NoBroadcast_public( st.SCHEMA_NAME, makeAny(newSchemaName) );
212 0 : disposeNoThrow( statement );
213 0 : schema = newSchemaName;
214 : }
215 0 : catch( com::sun::star::sdbc::SQLException &e )
216 : {
217 0 : OUString buf( e.Message + "(NOTE: Only postgresql server >= V8.1 support changing a table's schema)" );
218 0 : e.Message = buf;
219 0 : throw;
220 : }
221 :
222 : }
223 0 : if( ! newTableName.equals( oldName ) ) // might also be just the change of a schema name
224 : {
225 0 : OUStringBuffer buf(128);
226 0 : buf.append( "ALTER TABLE" );
227 0 : bufferQuoteQualifiedIdentifier(buf, schema, oldName, m_pSettings );
228 0 : buf.append( "RENAME TO" );
229 0 : bufferQuoteIdentifier( buf, newTableName, m_pSettings );
230 0 : Reference< XStatement > statement = m_conn->createStatement();
231 0 : statement->executeUpdate( buf.makeStringAndClear() );
232 0 : disposeNoThrow( statement );
233 : }
234 : }
235 0 : setPropertyValue_NoBroadcast_public( st.NAME, makeAny(newTableName) );
236 : // inform the container of the name change !
237 0 : if( m_pSettings->tables.is() )
238 : {
239 0 : m_pSettings->pTablesImpl->rename( fullOldName, fullNewName );
240 0 : }
241 0 : }
242 :
243 0 : void Table::alterColumnByName(
244 : const OUString& colName,
245 : const Reference< XPropertySet >& descriptor )
246 : throw (SQLException,NoSuchElementException,RuntimeException, std::exception)
247 : {
248 : Reference< com::sun::star::container::XNameAccess > columns =
249 0 : Reference< com::sun::star::container::XNameAccess > ( getColumns(), UNO_QUERY );
250 :
251 0 : OUString newName = extractStringProperty(descriptor, getStatics().NAME );
252 : ::pq_sdbc_driver::alterColumnByDescriptor(
253 0 : extractStringProperty( this, getStatics().SCHEMA_NAME ),
254 0 : extractStringProperty( this, getStatics().NAME ),
255 : m_pSettings,
256 0 : m_conn->createStatement(),
257 0 : Reference< com::sun::star::beans::XPropertySet>( columns->getByName( colName ), UNO_QUERY) ,
258 0 : descriptor );
259 :
260 0 : if( colName != newName )
261 : {
262 : // m_pColumns->rename( colName, newName );
263 0 : m_pColumns->refresh();
264 0 : }
265 0 : }
266 :
267 0 : void Table::alterColumnByIndex(
268 : sal_Int32 index,
269 : const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor )
270 : throw (SQLException,IndexOutOfBoundsException,RuntimeException, std::exception)
271 : {
272 : Reference< com::sun::star::container::XIndexAccess > columns =
273 0 : Reference< com::sun::star::container::XIndexAccess>( getColumns(), UNO_QUERY );
274 0 : Reference< com::sun::star::beans::XPropertySet> column(columns->getByIndex( index ), UNO_QUERY );
275 : ::pq_sdbc_driver::alterColumnByDescriptor(
276 0 : extractStringProperty( this, getStatics().SCHEMA_NAME ),
277 0 : extractStringProperty( this, getStatics().NAME ),
278 : m_pSettings,
279 0 : m_conn->createStatement(),
280 : column,
281 0 : descriptor );
282 0 : m_pColumns->refresh();
283 0 : }
284 :
285 0 : Sequence<Type > Table::getTypes() throw( RuntimeException, std::exception )
286 : {
287 : static cppu::OTypeCollection *pCollection;
288 0 : if( ! pCollection )
289 : {
290 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
291 0 : if( !pCollection )
292 : {
293 : static cppu::OTypeCollection collection(
294 0 : cppu::UnoType<com::sun::star::sdbcx::XIndexesSupplier>::get(),
295 0 : cppu::UnoType<com::sun::star::sdbcx::XKeysSupplier>::get(),
296 0 : cppu::UnoType<com::sun::star::sdbcx::XColumnsSupplier>::get(),
297 0 : cppu::UnoType<com::sun::star::sdbcx::XRename>::get(),
298 0 : cppu::UnoType<com::sun::star::sdbcx::XAlterTable>::get(),
299 0 : ReflectionBase::getTypes());
300 0 : pCollection = &collection;
301 0 : }
302 : }
303 0 : return pCollection->getTypes();
304 : }
305 :
306 0 : Sequence< sal_Int8> Table::getImplementationId() throw( RuntimeException, std::exception )
307 : {
308 0 : return css::uno::Sequence<sal_Int8>();
309 : }
310 :
311 0 : Any Table::queryInterface( const Type & reqType ) throw (RuntimeException, std::exception)
312 : {
313 0 : Any ret;
314 :
315 0 : ret = ReflectionBase::queryInterface( reqType );
316 0 : if( ! ret.hasValue() )
317 0 : ret = ::cppu::queryInterface(
318 : reqType,
319 : static_cast< com::sun::star::sdbcx::XIndexesSupplier * > ( this ),
320 : static_cast< com::sun::star::sdbcx::XKeysSupplier * > ( this ),
321 : static_cast< com::sun::star::sdbcx::XColumnsSupplier * > ( this ),
322 : static_cast< com::sun::star::sdbcx::XRename * > ( this ),
323 : static_cast< com::sun::star::sdbcx::XAlterTable * > ( this )
324 0 : );
325 0 : return ret;
326 : }
327 :
328 0 : ::com::sun::star::uno::Any Table::getPropertyValue(const OUString& aPropertyName)
329 : throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
330 : {
331 0 : return ReflectionBase::getPropertyValue( aPropertyName );
332 : }
333 :
334 :
335 0 : OUString Table::getName( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
336 : {
337 0 : Statics & st = getStatics();
338 : return concatQualified(
339 : extractStringProperty( this, st.SCHEMA_NAME ),
340 0 : extractStringProperty( this, st.NAME ) );
341 : }
342 :
343 0 : void Table::setName( const OUString& aName ) throw (::com::sun::star::uno::RuntimeException, std::exception)
344 : {
345 0 : rename( aName );
346 0 : }
347 :
348 :
349 :
350 :
351 0 : TableDescriptor::TableDescriptor(
352 : const ::rtl::Reference< RefCountedMutex > & refMutex,
353 : const Reference< com::sun::star::sdbc::XConnection > & connection,
354 : ConnectionSettings *pSettings)
355 : : ReflectionBase(
356 0 : getStatics().refl.tableDescriptor.implName,
357 0 : getStatics().refl.tableDescriptor.serviceNames,
358 : refMutex,
359 : connection,
360 : pSettings,
361 0 : * getStatics().refl.tableDescriptor.pProps )
362 : {
363 0 : }
364 :
365 0 : Reference< XNameAccess > TableDescriptor::getColumns( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
366 : {
367 0 : if( ! m_columns.is() )
368 : {
369 0 : m_columns = new ColumnDescriptors(m_refMutex, m_conn, m_pSettings );
370 : }
371 0 : return m_columns;
372 : }
373 :
374 0 : Reference< XNameAccess > TableDescriptor::getIndexes() throw (::com::sun::star::uno::RuntimeException, std::exception)
375 : {
376 0 : if( ! m_indexes.is() )
377 : {
378 0 : m_indexes = ::pq_sdbc_driver::IndexDescriptors::create(
379 : m_refMutex,
380 : m_conn,
381 0 : m_pSettings);
382 : }
383 0 : return m_indexes;
384 : }
385 :
386 0 : Reference< XIndexAccess > TableDescriptor::getKeys( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
387 : {
388 0 : if( ! m_keys.is() )
389 : {
390 0 : m_keys = ::pq_sdbc_driver::KeyDescriptors::create(
391 : m_refMutex,
392 : m_conn,
393 0 : m_pSettings );
394 : }
395 0 : return m_keys;
396 : }
397 :
398 :
399 0 : Sequence<Type > TableDescriptor::getTypes() throw( RuntimeException, std::exception )
400 : {
401 : static cppu::OTypeCollection *pCollection;
402 0 : if( ! pCollection )
403 : {
404 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
405 0 : if( !pCollection )
406 : {
407 : static cppu::OTypeCollection collection(
408 0 : cppu::UnoType<com::sun::star::sdbcx::XIndexesSupplier>::get(),
409 0 : cppu::UnoType<com::sun::star::sdbcx::XKeysSupplier>::get(),
410 0 : cppu::UnoType<com::sun::star::sdbcx::XColumnsSupplier>::get(),
411 0 : ReflectionBase::getTypes());
412 0 : pCollection = &collection;
413 0 : }
414 : }
415 0 : return pCollection->getTypes();
416 : }
417 :
418 0 : Sequence< sal_Int8> TableDescriptor::getImplementationId() throw( RuntimeException, std::exception )
419 : {
420 0 : return css::uno::Sequence<sal_Int8>();
421 : }
422 :
423 0 : Any TableDescriptor::queryInterface( const Type & reqType ) throw (RuntimeException, std::exception)
424 : {
425 0 : Any ret;
426 :
427 0 : ret = ReflectionBase::queryInterface( reqType );
428 0 : if( ! ret.hasValue() )
429 0 : ret = ::cppu::queryInterface(
430 : reqType,
431 : static_cast< com::sun::star::sdbcx::XIndexesSupplier * > ( this ),
432 : static_cast< com::sun::star::sdbcx::XKeysSupplier * > ( this ),
433 0 : static_cast< com::sun::star::sdbcx::XColumnsSupplier * > ( this ));
434 0 : return ret;
435 : }
436 :
437 :
438 0 : Reference< XPropertySet > TableDescriptor::createDataDescriptor( ) throw (RuntimeException, std::exception)
439 : {
440 : TableDescriptor * pTable = new TableDescriptor(
441 0 : m_refMutex, m_conn, m_pSettings );
442 :
443 : // TODO: deep copies
444 0 : pTable->m_values = m_values;
445 :
446 0 : return Reference< XPropertySet > ( pTable );
447 : }
448 :
449 : }
450 :
451 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|