nss: upgrade to release 3.73
[LibreOffice.git] / connectivity / source / drivers / postgresql / pq_xtables.cxx
blob83758208b203de7c9c24c20aba7114fd4d8dc671
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>
38 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
39 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
40 #include <com/sun/star/sdbc/SQLException.hpp>
41 #include <com/sun/star/sdbc/XRow.hpp>
42 #include <com/sun/star/sdbcx/Privilege.hpp>
43 #include <com/sun/star/sdbc/DataType.hpp>
44 #include <cppuhelper/exc_hlp.hxx>
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::Reference;
60 using com::sun::star::uno::Sequence;
62 using com::sun::star::container::XEnumerationAccess;
63 using com::sun::star::container::XEnumeration;
65 using com::sun::star::sdbc::XRow;
66 using com::sun::star::sdbc::XStatement;
67 using com::sun::star::sdbc::XResultSet;
68 using com::sun::star::sdbc::XDatabaseMetaData;
69 using com::sun::star::sdbcx::XColumnsSupplier;
70 using com::sun::star::sdbcx::XKeysSupplier;
72 namespace pq_sdbc_driver
74 Tables::Tables(
75 const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
76 const css::uno::Reference< css::sdbc::XConnection > & origin,
77 ConnectionSettings *pSettings )
78 : Container( refMutex, origin, pSettings, getStatics().TABLE )
81 Tables::~Tables()
84 void Tables::refresh()
86 try
88 osl::MutexGuard guard( m_xMutex->GetMutex() );
89 Statics & st = getStatics();
91 Reference< XDatabaseMetaData > meta = m_origin->getMetaData();
93 Reference< XResultSet > rs =
94 meta->getTables( Any(), st.cPERCENT,st.cPERCENT, Sequence< OUString > () );
96 Reference< XRow > xRow( rs , UNO_QUERY );
98 String2IntMap map;
100 m_values.clear();
101 sal_Int32 tableIndex = 0;
102 while( rs->next() )
104 // if creating all these tables turns out to have too bad performance, we might
105 // instead offer a factory interface
106 Table * pTable =
107 new Table( m_xMutex, m_origin, m_pSettings );
108 Reference< css::beans::XPropertySet > prop = pTable;
110 OUString name = xRow->getString( TABLE_INDEX_NAME+1);
111 OUString schema = xRow->getString( TABLE_INDEX_SCHEMA+1);
112 pTable->setPropertyValue_NoBroadcast_public(
113 st.CATALOG_NAME , makeAny(xRow->getString( TABLE_INDEX_CATALOG+1) ) );
114 pTable->setPropertyValue_NoBroadcast_public( st.NAME , makeAny( name ) );
115 pTable->setPropertyValue_NoBroadcast_public( st.SCHEMA_NAME , makeAny( schema ));
116 pTable->setPropertyValue_NoBroadcast_public(
117 st.TYPE , makeAny( xRow->getString( TABLE_INDEX_TYPE+1) ) );
118 pTable->setPropertyValue_NoBroadcast_public(
119 st.DESCRIPTION , makeAny( xRow->getString( TABLE_INDEX_REMARKS+1) ) );
120 pTable->setPropertyValue_NoBroadcast_public(
121 st.PRIVILEGES ,
122 makeAny( sal_Int32( css::sdbcx::Privilege::SELECT |
123 css::sdbcx::Privilege::INSERT |
124 css::sdbcx::Privilege::UPDATE |
125 css::sdbcx::Privilege::DELETE |
126 css::sdbcx::Privilege::READ |
127 css::sdbcx::Privilege::CREATE |
128 css::sdbcx::Privilege::ALTER |
129 css::sdbcx::Privilege::REFERENCE |
130 css::sdbcx::Privilege::DROP ) ) );
133 m_values.push_back( makeAny( prop ) );
134 map[ schema + "." + name ] = tableIndex;
135 ++tableIndex;
138 m_name2index.swap( map );
140 catch ( const css::sdbc::SQLException & e )
142 css::uno::Any anyEx = cppu::getCaughtException();
143 throw css::lang::WrappedTargetRuntimeException( e.Message,
144 e.Context, anyEx );
147 fire( RefreshedBroadcaster( *this ) );
151 static void appendColumnList(
152 OUStringBuffer &buf, const Reference< XColumnsSupplier > & columnSupplier, ConnectionSettings *settings )
154 if( !columnSupplier.is() )
155 return;
157 Reference< XEnumerationAccess > columns( columnSupplier->getColumns(),UNO_QUERY );
158 if( !columns.is() )
159 return;
161 Reference< XEnumeration > xEnum( columns->createEnumeration() );
162 bool first = true;
163 Statics & st = getStatics();
165 while( xEnum.is() && xEnum->hasMoreElements() )
167 if( first )
169 first = false;
171 else
173 buf.append( ", " );
175 Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY );
176 OUString name = extractStringProperty( column, st.NAME );
177 OUString defaultValue = extractStringProperty( column, st.DEFAULT_VALUE );
178 bool isNullable = extractBoolProperty( column, st.IS_NULLABLE );
179 bool isAutoIncrement = extractBoolProperty( column, st.IS_AUTO_INCREMENT );
181 bufferQuoteIdentifier( buf, name, settings );
183 OUString type = sqltype2string( column );
184 if( isAutoIncrement )
186 sal_Int32 dataType = 0;
187 column->getPropertyValue( st.TYPE ) >>= dataType;
188 if( css::sdbc::DataType::INTEGER == dataType )
190 buf.append( " serial ");
191 isNullable = false;
193 else if( css::sdbc::DataType::BIGINT == dataType )
195 buf.append( " serial8 " );
196 isNullable = false;
198 else
199 buf.append( type );
201 else
203 buf.append( type );
205 if( !defaultValue.isEmpty() )
207 bufferQuoteConstant( buf, defaultValue, settings );
210 if( ! isNullable )
211 buf.append( " NOT NULL " );
216 static void appendKeyList(
217 OUStringBuffer & buf, const Reference< XKeysSupplier > &keySupplier, ConnectionSettings *settings )
219 if( !keySupplier.is() )
220 return;
222 Reference< XEnumerationAccess > keys( keySupplier->getKeys(), UNO_QUERY );
223 if(keys.is() )
225 Reference< XEnumeration > xEnum = keys->createEnumeration();
226 while( xEnum.is() && xEnum->hasMoreElements() )
228 buf.append( ", " );
229 Reference< XPropertySet > key( xEnum->nextElement(), UNO_QUERY );
230 bufferKey2TableConstraint( buf, key, settings );
235 void Tables::appendByDescriptor(
236 const css::uno::Reference< css::beans::XPropertySet >& descriptor )
238 osl::MutexGuard guard( m_xMutex->GetMutex() );
239 Reference< XStatement > stmt =
240 m_origin->createStatement();
242 Statics &st = getStatics();
243 OUString name,schema;
244 descriptor->getPropertyValue( st.SCHEMA_NAME ) >>= schema;
245 descriptor->getPropertyValue( st.NAME ) >>= name;
247 TransactionGuard transaction( stmt );
249 OUStringBuffer buf( 128 );
250 buf.append( "CREATE TABLE" );
251 bufferQuoteQualifiedIdentifier( buf, schema, name , m_pSettings);
252 buf.append( "(" );
254 // columns
255 Reference< XColumnsSupplier > supplier( descriptor, UNO_QUERY );
256 appendColumnList( buf, supplier, m_pSettings );
258 appendKeyList( buf, Reference< XKeysSupplier >( descriptor, UNO_QUERY ), m_pSettings );
260 buf.append( ") " );
261 // execute the creation !
262 transaction.executeUpdate( buf.makeStringAndClear() );
264 // description...
265 OUString description = extractStringProperty( descriptor, st.DESCRIPTION );
266 if( !description.isEmpty() )
268 buf.truncate();
269 buf.append( "COMMENT ON TABLE" );
270 bufferQuoteQualifiedIdentifier( buf, schema, name, m_pSettings );
271 buf.append( "IS " );
272 bufferQuoteConstant( buf, description, m_pSettings);
274 transaction.executeUpdate( buf.makeStringAndClear() );
277 // column descriptions
278 if( supplier.is() )
280 Reference< XEnumerationAccess > columns( supplier->getColumns(),UNO_QUERY );
281 if( columns.is() )
283 Reference< XEnumeration > xEnum( columns->createEnumeration() );
284 while( xEnum.is() && xEnum->hasMoreElements() )
286 Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY );
287 description = extractStringProperty( column,st.DESCRIPTION );
288 if( !description.isEmpty() )
290 buf.truncate();
291 buf.append( "COMMENT ON COLUMN " );
292 bufferQuoteQualifiedIdentifier(
293 buf, schema, name, extractStringProperty( column, st.NAME ), m_pSettings );
294 buf.append( "IS " );
295 bufferQuoteConstant( buf, description, m_pSettings );
296 transaction.executeUpdate( buf.makeStringAndClear() );
302 transaction.commit();
304 disposeNoThrow( stmt );
305 // TODO: cheaper recalculate
306 // Container::append( concatQualified( schema, name ), descriptor ); // maintain the lists
307 refresh();
310 void Tables::dropByIndex( sal_Int32 index )
312 osl::MutexGuard guard( m_xMutex->GetMutex() );
313 if( index < 0 || index >= static_cast<sal_Int32>(m_values.size()) )
315 throw css::lang::IndexOutOfBoundsException(
316 "TABLES: Index out of range (allowed 0 to " + OUString::number(m_values.size() -1)
317 + ", got " + OUString::number( index ) + ")",
318 *this );
321 Reference< XPropertySet > set;
322 m_values[index] >>= set;
323 Statics &st = getStatics();
324 OUString name,schema;
325 set->getPropertyValue( st.SCHEMA_NAME ) >>= schema;
326 set->getPropertyValue( st.NAME ) >>= name;
327 if( extractStringProperty( set, st.TYPE ) == st.VIEW && m_pSettings->views.is() )
329 m_pSettings->pViewsImpl->dropByName( concatQualified( schema, name ) );
331 else
333 OUStringBuffer update( 128 );
334 update.append( "DROP " );
335 if( extractStringProperty( set, st.TYPE ) == st.VIEW )
336 update.append( "VIEW " );
337 else
338 update.append( "TABLE " );
339 bufferQuoteQualifiedIdentifier( update, schema, name, m_pSettings );
340 Reference< XStatement > stmt = m_origin->createStatement( );
341 DisposeGuard dispGuard( stmt );
342 stmt->executeUpdate( update.makeStringAndClear() );
345 Container::dropByIndex( index );
349 css::uno::Reference< css::beans::XPropertySet > Tables::createDataDescriptor()
351 return new TableDescriptor( m_xMutex, m_origin, m_pSettings );
354 Reference< css::container::XNameAccess > Tables::create(
355 const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
356 const css::uno::Reference< css::sdbc::XConnection > & origin,
357 ConnectionSettings *pSettings,
358 Tables **ppTables)
360 *ppTables = new Tables( refMutex, origin, pSettings );
361 Reference< css::container::XNameAccess > ret = *ppTables;
362 (*ppTables)->refresh();
364 return ret;
369 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */