Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / connectivity / source / drivers / postgresql / pq_xtables.cxx
blobfc75b13c707a74e5f15f867236c2d3acacdcccc5
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 * 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/.
35 ************************************************************************/
37 #include <rtl/ustrbuf.hxx>
39 #include <com/sun/star/sdbc/XRow.hpp>
40 #include <com/sun/star/sdbc/XParameters.hpp>
41 #include <com/sun/star/sdbcx/Privilege.hpp>
42 #include <com/sun/star/sdbcx/KeyType.hpp>
43 #include <com/sun/star/sdbc/KeyRule.hpp>
44 #include <com/sun/star/sdbc/DataType.hpp>
46 #include "pq_xtables.hxx"
47 #include "pq_xviews.hxx"
48 #include "pq_xtable.hxx"
49 #include "pq_statics.hxx"
50 #include "pq_tools.hxx"
52 using osl::MutexGuard;
54 using com::sun::star::beans::XPropertySet;
56 using com::sun::star::uno::Any;
57 using com::sun::star::uno::makeAny;
58 using com::sun::star::uno::UNO_QUERY;
59 using com::sun::star::uno::Type;
60 using com::sun::star::uno::XInterface;
61 using com::sun::star::uno::Reference;
62 using com::sun::star::uno::Sequence;
63 using com::sun::star::uno::RuntimeException;
65 using com::sun::star::container::NoSuchElementException;
66 using com::sun::star::container::XEnumerationAccess;
67 using com::sun::star::container::XEnumeration;
68 using com::sun::star::lang::WrappedTargetException;
70 using com::sun::star::sdbc::XRow;
71 using com::sun::star::sdbc::XCloseable;
72 using com::sun::star::sdbc::XStatement;
73 using com::sun::star::sdbc::XResultSet;
74 using com::sun::star::sdbc::XParameters;
75 using com::sun::star::sdbc::XPreparedStatement;
76 using com::sun::star::sdbc::XDatabaseMetaData;
77 using com::sun::star::sdbcx::XColumnsSupplier;
78 using com::sun::star::sdbcx::XKeysSupplier;
79 using com::sun::star::sdbcx::XViewsSupplier;
81 namespace pq_sdbc_driver
83 Tables::Tables(
84 const ::rtl::Reference< RefCountedMutex > & refMutex,
85 const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin,
86 ConnectionSettings *pSettings )
87 : Container( refMutex, origin, pSettings, getStatics().TABLE )
90 Tables::~Tables()
93 void Tables::refresh()
94 throw (::com::sun::star::uno::RuntimeException, std::exception)
96 try
98 osl::MutexGuard guard( m_refMutex->mutex );
99 Statics & st = getStatics();
101 Reference< XDatabaseMetaData > meta = m_origin->getMetaData();
103 Reference< XResultSet > rs =
104 meta->getTables( Any(), st.cPERCENT,st.cPERCENT, Sequence< OUString > () );
106 Reference< XRow > xRow( rs , UNO_QUERY );
108 String2IntMap map;
110 m_values = Sequence< com::sun::star::uno::Any > ();
111 sal_Int32 tableIndex = 0;
112 while( rs->next() )
114 // if creating all these tables turns out to have too bad performance, we might
115 // instead offer a factory interface
116 Table * pTable =
117 new Table( m_refMutex, m_origin, m_pSettings );
118 Reference< com::sun::star::beans::XPropertySet > prop = pTable;
120 OUString name = xRow->getString( TABLE_INDEX_NAME+1);
121 OUString schema = xRow->getString( TABLE_INDEX_SCHEMA+1);
122 pTable->setPropertyValue_NoBroadcast_public(
123 st.CATALOG_NAME , makeAny(xRow->getString( TABLE_INDEX_CATALOG+1) ) );
124 pTable->setPropertyValue_NoBroadcast_public( st.NAME , makeAny( name ) );
125 pTable->setPropertyValue_NoBroadcast_public( st.SCHEMA_NAME , makeAny( schema ));
126 pTable->setPropertyValue_NoBroadcast_public(
127 st.TYPE , makeAny( xRow->getString( TABLE_INDEX_TYPE+1) ) );
128 pTable->setPropertyValue_NoBroadcast_public(
129 st.DESCRIPTION , makeAny( xRow->getString( TABLE_INDEX_REMARKS+1) ) );
130 pTable->setPropertyValue_NoBroadcast_public(
131 st.PRIVILEGES ,
132 makeAny( (sal_Int32)
133 ( com::sun::star::sdbcx::Privilege::SELECT |
134 com::sun::star::sdbcx::Privilege::INSERT |
135 com::sun::star::sdbcx::Privilege::UPDATE |
136 com::sun::star::sdbcx::Privilege::DELETE |
137 com::sun::star::sdbcx::Privilege::READ |
138 com::sun::star::sdbcx::Privilege::CREATE |
139 com::sun::star::sdbcx::Privilege::ALTER |
140 com::sun::star::sdbcx::Privilege::REFERENCE |
141 com::sun::star::sdbcx::Privilege::DROP ) ) );
144 const int currentTableIndex = tableIndex++;
145 assert(currentTableIndex == m_values.getLength());
146 m_values.realloc( tableIndex );
147 m_values[currentTableIndex] = makeAny( prop );
148 OUStringBuffer buf( name.getLength() + schema.getLength() + 1);
149 buf.append( schema + "." + name );
150 map[ buf.makeStringAndClear() ] = currentTableIndex;
153 m_name2index.swap( map );
155 catch ( const com::sun::star::sdbc::SQLException & e )
157 throw RuntimeException( e.Message , e.Context );
160 fire( RefreshedBroadcaster( *this ) );
164 static void appendColumnList(
165 OUStringBuffer &buf, const Reference< XColumnsSupplier > & columnSupplier, ConnectionSettings *settings )
167 if( columnSupplier.is() )
169 Reference< XEnumerationAccess > columns( columnSupplier->getColumns(),UNO_QUERY );
170 if( columns.is() )
172 Reference< XEnumeration > xEnum( columns->createEnumeration() );
173 bool first = true;
174 Statics & st = getStatics();
176 while( xEnum.is() && xEnum->hasMoreElements() )
178 if( first )
180 first = false;
182 else
184 buf.append( ", " );
186 Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY );
187 OUString name = extractStringProperty( column, st.NAME );
188 OUString defaultValue = extractStringProperty( column, st.DEFAULT_VALUE );
189 bool isNullable = extractBoolProperty( column, st.IS_NULLABLE );
190 bool isAutoIncrement = extractBoolProperty( column, st.IS_AUTO_INCREMENT );
192 bufferQuoteIdentifier( buf, name, settings );
194 OUString type = sqltype2string( column );
195 if( isAutoIncrement )
197 sal_Int32 dataType = 0;
198 column->getPropertyValue( st.TYPE ) >>= dataType;
199 if( com::sun::star::sdbc::DataType::INTEGER == dataType )
201 buf.append( " serial ");
202 isNullable = false;
204 else if( com::sun::star::sdbc::DataType::BIGINT == dataType )
206 buf.append( " serial8 " );
207 isNullable = false;
209 else
210 buf.append( type );
212 else
214 buf.append( type );
216 if( !defaultValue.isEmpty() )
218 bufferQuoteConstant( buf, defaultValue, settings );
221 if( ! isNullable )
222 buf.append( " NOT NULL " );
229 static void appendKeyList(
230 OUStringBuffer & buf, const Reference< XKeysSupplier > &keySupplier, ConnectionSettings *settings )
232 if( keySupplier.is() )
234 Reference< XEnumerationAccess > keys( keySupplier->getKeys(), UNO_QUERY );
235 if(keys.is() )
237 Reference< XEnumeration > xEnum = keys->createEnumeration();
238 while( xEnum.is() && xEnum->hasMoreElements() )
240 buf.append( ", " );
241 Reference< XPropertySet > key( xEnum->nextElement(), UNO_QUERY );
242 bufferKey2TableConstraint( buf, key, settings );
248 void Tables::appendByDescriptor(
249 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor )
250 throw (::com::sun::star::sdbc::SQLException,
251 ::com::sun::star::container::ElementExistException,
252 ::com::sun::star::uno::RuntimeException, std::exception)
254 osl::MutexGuard guard( m_refMutex->mutex );
255 Reference< XStatement > stmt =
256 m_origin->createStatement();
258 Statics &st = getStatics();
259 OUString name,schema;
260 descriptor->getPropertyValue( st.SCHEMA_NAME ) >>= schema;
261 descriptor->getPropertyValue( st.NAME ) >>= name;
263 TransactionGuard transaction( stmt );
265 OUStringBuffer buf( 128 );
266 buf.append( "CREATE TABLE" );
267 bufferQuoteQualifiedIdentifier( buf, schema, name , m_pSettings);
268 buf.append( "(" );
270 // columns
271 Reference< XColumnsSupplier > supplier( descriptor, UNO_QUERY );
272 appendColumnList( buf, supplier, m_pSettings );
274 appendKeyList( buf, Reference< XKeysSupplier >( descriptor, UNO_QUERY ), m_pSettings );
276 buf.append( ") " );
277 // execute the creation !
278 transaction.executeUpdate( buf.makeStringAndClear() );
280 // description ....
281 OUString description = extractStringProperty( descriptor, st.DESCRIPTION );
282 if( !description.isEmpty() )
284 buf = OUStringBuffer( 128 );
285 buf.append( "COMMENT ON TABLE" );
286 bufferQuoteQualifiedIdentifier( buf, schema, name, m_pSettings );
287 buf.append( "IS " );
288 bufferQuoteConstant( buf, description, m_pSettings);
290 transaction.executeUpdate( buf.makeStringAndClear() );
293 // column descriptions
294 if( supplier.is() )
296 Reference< XEnumerationAccess > columns( supplier->getColumns(),UNO_QUERY );
297 if( columns.is() )
299 Reference< XEnumeration > xEnum( columns->createEnumeration() );
300 while( xEnum.is() && xEnum->hasMoreElements() )
302 Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY );
303 description = extractStringProperty( column,st.DESCRIPTION );
304 if( !description.isEmpty() )
306 buf = OUStringBuffer( 128 );
307 buf.append( "COMMENT ON COLUMN " );
308 bufferQuoteQualifiedIdentifier(
309 buf, schema, name, extractStringProperty( column, st.NAME ), m_pSettings );
310 buf.append( "IS " );
311 bufferQuoteConstant( buf, description, m_pSettings );
312 transaction.executeUpdate( buf.makeStringAndClear() );
318 transaction.commit();
320 disposeNoThrow( stmt );
321 // TODO: cheaper recalculate
322 // Container::append( concatQualified( schema, name ), descriptor ); // maintain the lists
323 refresh();
326 void Tables::dropByIndex( sal_Int32 index )
327 throw (::com::sun::star::sdbc::SQLException,
328 ::com::sun::star::lang::IndexOutOfBoundsException,
329 ::com::sun::star::uno::RuntimeException, std::exception)
331 osl::MutexGuard guard( m_refMutex->mutex );
332 if( index < 0 || index >= m_values.getLength() )
334 OUStringBuffer buf( 128 );
335 buf.append( "TABLES: Index out of range (allowed 0 to " + OUString::number(m_values.getLength() -1) +
336 ", got " + OUString::number( index ) + ")" );
337 throw com::sun::star::lang::IndexOutOfBoundsException( buf.makeStringAndClear(), *this );
340 Reference< XPropertySet > set;
341 m_values[index] >>= set;
342 Statics &st = getStatics();
343 OUString name,schema;
344 set->getPropertyValue( st.SCHEMA_NAME ) >>= schema;
345 set->getPropertyValue( st.NAME ) >>= name;
346 if( extractStringProperty( set, st.TYPE ).equals( st.VIEW ) && m_pSettings->views.is() )
348 m_pSettings->pViewsImpl->dropByName( concatQualified( schema, name ) );
350 else
352 OUStringBuffer update( 128 );
353 update.append( "DROP " );
354 if( extractStringProperty( set, st.TYPE ).equals( st.VIEW ) )
355 update.append( "VIEW " );
356 else
357 update.append( "TABLE " );
358 bufferQuoteQualifiedIdentifier( update, schema, name, m_pSettings );
359 Reference< XStatement > stmt = m_origin->createStatement( );
360 DisposeGuard dispGuard( stmt );
361 stmt->executeUpdate( update.makeStringAndClear() );
364 Container::dropByIndex( index );
368 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > Tables::createDataDescriptor()
369 throw (::com::sun::star::uno::RuntimeException, std::exception)
371 return new TableDescriptor( m_refMutex, m_origin, m_pSettings );
374 Reference< com::sun::star::container::XNameAccess > Tables::create(
375 const ::rtl::Reference< RefCountedMutex > & refMutex,
376 const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin,
377 ConnectionSettings *pSettings,
378 Tables **ppTables)
380 *ppTables = new Tables( refMutex, origin, pSettings );
381 Reference< com::sun::star::container::XNameAccess > ret = *ppTables;
382 (*ppTables)->refresh();
384 return ret;
387 void Tables::disposing()
389 Container::disposing();
394 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */