Use COMReference to handle COM pointers in CreateShortcut
[LibreOffice.git] / connectivity / source / drivers / postgresql / pq_xtables.cxx
blob423ec81f2166915516cc0fc9ab1dad95a23df43a
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/ref.hxx>
38 #include <rtl/ustrbuf.hxx>
39 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
40 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
41 #include <com/sun/star/sdbc/SQLException.hpp>
42 #include <com/sun/star/sdbc/XRow.hpp>
43 #include <com/sun/star/sdbcx/Privilege.hpp>
44 #include <com/sun/star/sdbc/DataType.hpp>
45 #include <cppuhelper/exc_hlp.hxx>
46 #include <o3tl/safeint.hxx>
48 #include "pq_xtables.hxx"
49 #include "pq_xviews.hxx"
50 #include "pq_xtable.hxx"
51 #include "pq_statics.hxx"
52 #include "pq_tools.hxx"
54 using osl::MutexGuard;
56 using com::sun::star::beans::XPropertySet;
58 using com::sun::star::uno::Any;
59 using com::sun::star::uno::UNO_QUERY;
60 using com::sun::star::uno::Reference;
61 using com::sun::star::uno::Sequence;
63 using com::sun::star::container::XEnumerationAccess;
64 using com::sun::star::container::XEnumeration;
66 using com::sun::star::sdbc::XRow;
67 using com::sun::star::sdbc::XStatement;
68 using com::sun::star::sdbc::XResultSet;
69 using com::sun::star::sdbc::XDatabaseMetaData;
70 using com::sun::star::sdbcx::XColumnsSupplier;
71 using com::sun::star::sdbcx::XKeysSupplier;
73 namespace pq_sdbc_driver
75 Tables::Tables(
76 const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
77 const css::uno::Reference< css::sdbc::XConnection > & origin,
78 ConnectionSettings *pSettings )
79 : Container( refMutex, origin, pSettings, getStatics().TABLE )
82 Tables::~Tables()
85 void Tables::refresh()
87 try
89 osl::MutexGuard guard( m_xMutex->GetMutex() );
90 Statics & st = getStatics();
92 Reference< XDatabaseMetaData > meta = m_origin->getMetaData();
94 Reference< XResultSet > rs =
95 meta->getTables( Any(), st.cPERCENT,st.cPERCENT, Sequence< OUString > () );
97 Reference< XRow > xRow( rs , UNO_QUERY );
99 String2IntMap map;
101 m_values.clear();
102 sal_Int32 tableIndex = 0;
103 while( rs->next() )
105 // if creating all these tables turns out to have too bad performance, we might
106 // instead offer a factory interface
107 rtl::Reference<Table> pTable =
108 new Table( m_xMutex, m_origin, m_pSettings );
109 Reference< css::beans::XPropertySet > prop = pTable;
111 OUString name = xRow->getString( TABLE_INDEX_NAME+1);
112 OUString schema = xRow->getString( TABLE_INDEX_SCHEMA+1);
113 pTable->setPropertyValue_NoBroadcast_public(
114 st.CATALOG_NAME , Any(xRow->getString( TABLE_INDEX_CATALOG+1) ) );
115 pTable->setPropertyValue_NoBroadcast_public( st.NAME , Any( name ) );
116 pTable->setPropertyValue_NoBroadcast_public( st.SCHEMA_NAME , Any( schema ));
117 pTable->setPropertyValue_NoBroadcast_public(
118 st.TYPE , Any( xRow->getString( TABLE_INDEX_TYPE+1) ) );
119 pTable->setPropertyValue_NoBroadcast_public(
120 st.DESCRIPTION , Any( xRow->getString( TABLE_INDEX_REMARKS+1) ) );
121 pTable->setPropertyValue_NoBroadcast_public(
122 st.PRIVILEGES ,
123 Any( sal_Int32( css::sdbcx::Privilege::SELECT |
124 css::sdbcx::Privilege::INSERT |
125 css::sdbcx::Privilege::UPDATE |
126 css::sdbcx::Privilege::DELETE |
127 css::sdbcx::Privilege::READ |
128 css::sdbcx::Privilege::CREATE |
129 css::sdbcx::Privilege::ALTER |
130 css::sdbcx::Privilege::REFERENCE |
131 css::sdbcx::Privilege::DROP ) ) );
134 m_values.push_back( Any( prop ) );
135 map[ schema + "." + name ] = tableIndex;
136 ++tableIndex;
139 m_name2index.swap( map );
141 catch ( const css::sdbc::SQLException & e )
143 css::uno::Any anyEx = cppu::getCaughtException();
144 throw css::lang::WrappedTargetRuntimeException( e.Message,
145 e.Context, anyEx );
148 fire( RefreshedBroadcaster( *this ) );
152 static void appendColumnList(
153 OUStringBuffer &buf, const Reference< XColumnsSupplier > & columnSupplier, ConnectionSettings *settings )
155 if( !columnSupplier.is() )
156 return;
158 Reference< XEnumerationAccess > columns( columnSupplier->getColumns(),UNO_QUERY );
159 if( !columns.is() )
160 return;
162 Reference< XEnumeration > xEnum( columns->createEnumeration() );
163 bool first = true;
164 Statics & st = getStatics();
166 while( xEnum.is() && xEnum->hasMoreElements() )
168 if( first )
170 first = false;
172 else
174 buf.append( ", " );
176 Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY );
177 OUString name = extractStringProperty( column, st.NAME );
178 OUString defaultValue = extractStringProperty( column, st.DEFAULT_VALUE );
179 bool isNullable = extractBoolProperty( column, st.IS_NULLABLE );
180 bool isAutoIncrement = extractBoolProperty( column, st.IS_AUTO_INCREMENT );
182 bufferQuoteIdentifier( buf, name, settings );
184 OUString type = sqltype2string( column );
185 if( isAutoIncrement )
187 sal_Int32 dataType = 0;
188 column->getPropertyValue( st.TYPE ) >>= dataType;
189 if( css::sdbc::DataType::INTEGER == dataType )
191 buf.append( " serial ");
192 isNullable = false;
194 else if( css::sdbc::DataType::BIGINT == dataType )
196 buf.append( " serial8 " );
197 isNullable = false;
199 else
200 buf.append( type );
202 else
204 buf.append( type );
206 if( !defaultValue.isEmpty() )
208 bufferQuoteConstant( buf, defaultValue, settings );
211 if( ! isNullable )
212 buf.append( " NOT NULL " );
217 static void appendKeyList(
218 OUStringBuffer & buf, const Reference< XKeysSupplier > &keySupplier, ConnectionSettings *settings )
220 if( !keySupplier.is() )
221 return;
223 Reference< XEnumerationAccess > keys( keySupplier->getKeys(), UNO_QUERY );
224 if(keys.is() )
226 Reference< XEnumeration > xEnum = keys->createEnumeration();
227 while( xEnum.is() && xEnum->hasMoreElements() )
229 buf.append( ", " );
230 Reference< XPropertySet > key( xEnum->nextElement(), UNO_QUERY );
231 bufferKey2TableConstraint( buf, key, settings );
236 void Tables::appendByDescriptor(
237 const css::uno::Reference< css::beans::XPropertySet >& descriptor )
239 osl::MutexGuard guard( m_xMutex->GetMutex() );
240 Reference< XStatement > stmt =
241 m_origin->createStatement();
243 Statics &st = getStatics();
244 OUString name,schema;
245 descriptor->getPropertyValue( st.SCHEMA_NAME ) >>= schema;
246 descriptor->getPropertyValue( st.NAME ) >>= name;
248 TransactionGuard transaction( stmt );
250 OUStringBuffer buf( 128 );
251 buf.append( "CREATE TABLE" );
252 bufferQuoteQualifiedIdentifier( buf, schema, name , m_pSettings);
253 buf.append( "(" );
255 // columns
256 Reference< XColumnsSupplier > supplier( descriptor, UNO_QUERY );
257 appendColumnList( buf, supplier, m_pSettings );
259 appendKeyList( buf, Reference< XKeysSupplier >( descriptor, UNO_QUERY ), m_pSettings );
261 buf.append( ") " );
262 // execute the creation !
263 transaction.executeUpdate( buf.makeStringAndClear() );
265 // description...
266 OUString description = extractStringProperty( descriptor, st.DESCRIPTION );
267 if( !description.isEmpty() )
269 buf.truncate();
270 buf.append( "COMMENT ON TABLE" );
271 bufferQuoteQualifiedIdentifier( buf, schema, name, m_pSettings );
272 buf.append( "IS " );
273 bufferQuoteConstant( buf, description, m_pSettings);
275 transaction.executeUpdate( buf.makeStringAndClear() );
278 // column descriptions
279 if( supplier.is() )
281 Reference< XEnumerationAccess > columns( supplier->getColumns(),UNO_QUERY );
282 if( columns.is() )
284 Reference< XEnumeration > xEnum( columns->createEnumeration() );
285 while( xEnum.is() && xEnum->hasMoreElements() )
287 Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY );
288 description = extractStringProperty( column,st.DESCRIPTION );
289 if( !description.isEmpty() )
291 buf.truncate();
292 buf.append( "COMMENT ON COLUMN " );
293 bufferQuoteQualifiedIdentifier(
294 buf, schema, name, extractStringProperty( column, st.NAME ), m_pSettings );
295 buf.append( "IS " );
296 bufferQuoteConstant( buf, description, m_pSettings );
297 transaction.executeUpdate( buf.makeStringAndClear() );
303 transaction.commit();
305 disposeNoThrow( stmt );
306 // TODO: cheaper recalculate
307 // Container::append( concatQualified( schema, name ), descriptor ); // maintain the lists
308 refresh();
311 void Tables::dropByIndex( sal_Int32 index )
313 osl::MutexGuard guard( m_xMutex->GetMutex() );
314 if( index < 0 || o3tl::make_unsigned(index) >= m_values.size() )
316 throw css::lang::IndexOutOfBoundsException(
317 "TABLES: Index out of range (allowed 0 to " + OUString::number(m_values.size() -1)
318 + ", got " + OUString::number( index ) + ")",
319 *this );
322 Reference< XPropertySet > set;
323 m_values[index] >>= set;
324 Statics &st = getStatics();
325 OUString name,schema;
326 set->getPropertyValue( st.SCHEMA_NAME ) >>= schema;
327 set->getPropertyValue( st.NAME ) >>= name;
328 if( extractStringProperty( set, st.TYPE ) == st.VIEW && m_pSettings->views.is() )
330 m_pSettings->pViewsImpl->dropByName( concatQualified( schema, name ) );
332 else
334 OUStringBuffer update( 128 );
335 update.append( "DROP " );
336 if( extractStringProperty( set, st.TYPE ) == st.VIEW )
337 update.append( "VIEW " );
338 else
339 update.append( "TABLE " );
340 bufferQuoteQualifiedIdentifier( update, schema, name, m_pSettings );
341 Reference< XStatement > stmt = m_origin->createStatement( );
342 DisposeGuard dispGuard( stmt );
343 stmt->executeUpdate( update.makeStringAndClear() );
346 Container::dropByIndex( index );
350 css::uno::Reference< css::beans::XPropertySet > Tables::createDataDescriptor()
352 return new TableDescriptor( m_xMutex, m_origin, m_pSettings );
355 Reference< css::container::XNameAccess > Tables::create(
356 const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
357 const css::uno::Reference< css::sdbc::XConnection > & origin,
358 ConnectionSettings *pSettings,
359 rtl::Reference<Tables> *ppTables)
361 *ppTables = new Tables( refMutex, origin, pSettings );
362 (*ppTables)->refresh();
364 return *ppTables;
369 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */