merge the formfield patch from ooo-build
[ooovba.git] / connectivity / source / drivers / postgresql / pq_xtables.cxx
blob81c699df6c3eea3633fda56c5472129c5cf4b243
1 /*************************************************************************
3 * $RCSfile: pq_xtables.cxx,v $
5 * $Revision: 1.1.2.4 $
7 * last change: $Author: jbu $ $Date: 2006/05/01 19:19:08 $
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,
34 * MA 02111-1307 USA
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 <vector>
64 #include <rtl/ustrbuf.hxx>
66 #include <com/sun/star/sdbc/XRow.hpp>
67 #include <com/sun/star/sdbc/XParameters.hpp>
68 #include <com/sun/star/sdbcx/Privilege.hpp>
69 #include <com/sun/star/sdbcx/KeyType.hpp>
70 #include <com/sun/star/sdbc/KeyRule.hpp>
71 #include <com/sun/star/sdbc/DataType.hpp>
73 #include "pq_xtables.hxx"
74 #include "pq_xviews.hxx"
75 #include "pq_xtable.hxx"
76 #include "pq_statics.hxx"
77 #include "pq_tools.hxx"
79 using osl::MutexGuard;
81 using rtl::OUString;
82 using rtl::OUStringBuffer;
83 using rtl::OUStringToOString;
85 using com::sun::star::beans::XPropertySet;
87 using com::sun::star::uno::Any;
88 using com::sun::star::uno::makeAny;
89 using com::sun::star::uno::UNO_QUERY;
90 using com::sun::star::uno::Type;
91 using com::sun::star::uno::XInterface;
92 using com::sun::star::uno::Reference;
93 using com::sun::star::uno::Sequence;
94 using com::sun::star::uno::RuntimeException;
96 using com::sun::star::container::NoSuchElementException;
97 using com::sun::star::container::XEnumerationAccess;
98 using com::sun::star::container::XEnumeration;
99 using com::sun::star::lang::WrappedTargetException;
101 using com::sun::star::sdbc::XRow;
102 // using com::sun::star::sdbc::DataType;
103 using com::sun::star::sdbc::XCloseable;
104 using com::sun::star::sdbc::XStatement;
105 using com::sun::star::sdbc::XResultSet;
106 using com::sun::star::sdbc::XParameters;
107 using com::sun::star::sdbc::XPreparedStatement;
108 using com::sun::star::sdbc::XDatabaseMetaData;
109 using com::sun::star::sdbcx::XColumnsSupplier;
110 using com::sun::star::sdbcx::XKeysSupplier;
111 using com::sun::star::sdbcx::XViewsSupplier;
112 // using com::sun::star::sdbcx::Privilege;
114 namespace pq_sdbc_driver
116 #define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
117 Tables::Tables(
118 const ::rtl::Reference< RefCountedMutex > & refMutex,
119 const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin,
120 ConnectionSettings *pSettings )
121 : Container( refMutex, origin, pSettings, getStatics().TABLE )
124 Tables::~Tables()
127 void Tables::refresh()
128 throw (::com::sun::star::uno::RuntimeException)
132 osl::MutexGuard guard( m_refMutex->mutex );
133 Statics & st = getStatics();
135 Reference< XDatabaseMetaData > meta = m_origin->getMetaData();
137 Reference< XResultSet > rs =
138 meta->getTables( Any(), st.cPERCENT,st.cPERCENT, Sequence< OUString > () );
140 Reference< XRow > xRow( rs , UNO_QUERY );
142 String2IntMap map;
144 std::vector< Any, Allocator< Any> > vec;
145 sal_Int32 tableIndex = 0;
146 while( rs->next() )
148 // if creating all these tables turns out to have too bad performance, we might
149 // instead offer a factory interface
150 Table * pTable =
151 new Table( m_refMutex, m_origin, m_pSettings );
152 Reference< com::sun::star::beans::XPropertySet > prop = pTable;
154 OUString name = xRow->getString( TABLE_INDEX_NAME+1);
155 OUString schema = xRow->getString( TABLE_INDEX_SCHEMA+1);
156 pTable->setPropertyValue_NoBroadcast_public(
157 st.CATALOG_NAME , makeAny(xRow->getString( TABLE_INDEX_CATALOG+1) ) );
158 pTable->setPropertyValue_NoBroadcast_public( st.NAME , makeAny( name ) );
159 pTable->setPropertyValue_NoBroadcast_public( st.SCHEMA_NAME , makeAny( schema ));
160 pTable->setPropertyValue_NoBroadcast_public(
161 st.TYPE , makeAny( xRow->getString( TABLE_INDEX_TYPE+1) ) );
162 pTable->setPropertyValue_NoBroadcast_public(
163 st.DESCRIPTION , makeAny( xRow->getString( TABLE_INDEX_REMARKS+1) ) );
164 pTable->setPropertyValue_NoBroadcast_public(
165 st.PRIVILEGES ,
166 makeAny( (sal_Int32)
167 ( com::sun::star::sdbcx::Privilege::SELECT |
168 com::sun::star::sdbcx::Privilege::INSERT |
169 com::sun::star::sdbcx::Privilege::UPDATE |
170 com::sun::star::sdbcx::Privilege::DELETE |
171 com::sun::star::sdbcx::Privilege::READ |
172 com::sun::star::sdbcx::Privilege::CREATE |
173 com::sun::star::sdbcx::Privilege::ALTER |
174 com::sun::star::sdbcx::Privilege::REFERENCE |
175 com::sun::star::sdbcx::Privilege::DROP ) ) );
177 vec.push_back( makeAny( prop ) );
178 OUStringBuffer buf( name.getLength() + schema.getLength() + 1);
179 buf.append( schema ).appendAscii( "." ).append( name );
180 map[ buf.makeStringAndClear() ] = tableIndex;
181 tableIndex ++;
183 m_values = Sequence< com::sun::star::uno::Any > ( & vec[0] , vec.size() );
184 m_name2index.swap( map );
186 catch ( com::sun::star::sdbc::SQLException & e )
188 throw RuntimeException( e.Message , e.Context );
191 fire( RefreshedBroadcaster( *this ) );
195 static void appendColumnList(
196 OUStringBuffer &buf, const Reference< XColumnsSupplier > & columnSupplier, sal_Int32 encoding )
198 if( columnSupplier.is() )
200 Reference< XEnumerationAccess > columns( columnSupplier->getColumns(),UNO_QUERY );
201 if( columns.is() )
203 Reference< XEnumeration > xEnum( columns->createEnumeration() );
204 bool first = true;
205 Statics & st = getStatics();
207 while( xEnum.is() && xEnum->hasMoreElements() )
209 if( first )
211 first = false;
213 else
215 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", " ) );
217 Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY );
218 OUString name = extractStringProperty( column, st.NAME );
219 OUString defaultValue = extractStringProperty( column, st.DEFAULT_VALUE );
220 sal_Bool isNullable = extractBoolProperty( column, st.IS_NULLABLE );
221 sal_Bool isAutoIncrement = extractBoolProperty( column, st.IS_AUTO_INCREMENT );
223 bufferQuoteIdentifier( buf, name );
225 OUString type = sqltype2string( column );
226 if( isAutoIncrement )
228 sal_Int32 dataType;
229 column->getPropertyValue( st.TYPE ) >>= dataType;
230 if( com::sun::star::sdbc::DataType::INTEGER == dataType )
232 buf.appendAscii( " serial ");
233 isNullable = sal_False;
235 else if( com::sun::star::sdbc::DataType::BIGINT == dataType )
237 buf.appendAscii( " serial8 " );
238 isNullable = sal_False;
240 else
241 buf.append( type );
243 else
245 buf.append( type );
247 if( defaultValue.getLength() )
249 bufferQuoteConstant( buf, defaultValue, encoding );
252 if( ! isNullable )
253 // buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " NULL " ) );
254 // else
255 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " NOT NULL " ) );
262 static void appendKeyList(
263 OUStringBuffer & buf, const Reference< XKeysSupplier > &keySupplier )
265 if( keySupplier.is() )
267 Reference< XEnumerationAccess > keys( keySupplier->getKeys(), UNO_QUERY );
268 if(keys.is() )
270 Statics &st = getStatics();
271 Reference< XEnumeration > xEnum = keys->createEnumeration();
272 while( xEnum.is() && xEnum->hasMoreElements() )
274 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", " ) );
275 Reference< XPropertySet > key( xEnum->nextElement(), UNO_QUERY );
276 bufferKey2TableConstraint( buf, key );
282 void Tables::appendByDescriptor(
283 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor )
284 throw (::com::sun::star::sdbc::SQLException,
285 ::com::sun::star::container::ElementExistException,
286 ::com::sun::star::uno::RuntimeException)
288 osl::MutexGuard guard( m_refMutex->mutex );
289 Reference< XStatement > stmt =
290 m_origin->createStatement();
292 Statics &st = getStatics();
293 OUString name,schema;
294 descriptor->getPropertyValue( st.SCHEMA_NAME ) >>= schema;
295 descriptor->getPropertyValue( st.NAME ) >>= name;
297 TransactionGuard transaction( stmt );
299 OUStringBuffer buf( 128 );
300 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("CREATE TABLE" ) );
301 bufferQuoteQualifiedIdentifier( buf, schema, name );
302 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "(" ) );
304 // columns
305 Reference< XColumnsSupplier > supplier( descriptor, UNO_QUERY );
306 appendColumnList( buf, supplier, m_pSettings->encoding );
308 appendKeyList( buf, Reference< XKeysSupplier >( descriptor, UNO_QUERY ) );
310 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ") " ) );
311 // execute the creation !
312 transaction.executeUpdate( buf.makeStringAndClear() );
314 // description ....
315 OUString description = extractStringProperty( descriptor, st.DESCRIPTION );
316 if( description.getLength() )
318 buf = OUStringBuffer( 128 );
319 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "COMMENT ON TABLE" ) );
320 bufferQuoteQualifiedIdentifier( buf, schema, name );
321 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "IS " ) );
322 bufferQuoteConstant( buf, description, m_pSettings->encoding );
324 transaction.executeUpdate( buf.makeStringAndClear() );
327 // column descriptions
328 if( supplier.is() )
330 Reference< XEnumerationAccess > columns( supplier->getColumns(),UNO_QUERY );
331 if( columns.is() )
333 Reference< XEnumeration > xEnum( columns->createEnumeration() );
334 while( xEnum.is() && xEnum->hasMoreElements() )
336 Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY );
337 // help text seems to be used by OOo rather than Description
338 // OUString description = extractStringProperty( column, st.HELP_TEXT );
339 OUString helpText = extractStringProperty( column,st.DESCRIPTION );
340 if( description.getLength() )
342 buf = OUStringBuffer( 128 );
343 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "COMMENT ON COLUMN " ) );
344 bufferQuoteQualifiedIdentifier(
345 buf, schema, name, extractStringProperty( column, st.NAME ) );
346 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "IS " ) );
347 bufferQuoteConstant(
348 buf, description,m_pSettings->encoding );
349 transaction.executeUpdate( buf.makeStringAndClear() );
355 transaction.commit();
357 disposeNoThrow( stmt );
358 // TODO: cheaper recalculate
359 // Container::append( concatQualified( schema, name ), descriptor ); // maintain the lists
360 refresh();
362 // increase the vector
363 // sal_Int32 index = m_values.getLength();
364 // m_values.realloc( index + 1 );
366 // Table * pTable =
367 // new Table( m_refMutex, m_origin, m_pSettings, false /*modifiable*/ );
368 // Reference< com::sun::star::beans::XPropertySet > prop = pTable;
369 // copyProperties( pTable, descriptor );
370 // m_values[index] = makeAny( prop );
371 // OUStringBuffer buf( name.getLength() + 1 + schema.getLength() );
372 // buf.append( schema ).appendAscii( "." ).append( name );
373 // m_name2index[ buf.makeStringAndClear() ] = index;
376 // void Tables::dropByName( const ::rtl::OUString& elementName )
377 // throw (::com::sun::star::sdbc::SQLException,
378 // ::com::sun::star::container::NoSuchElementException,
379 // ::com::sun::star::uno::RuntimeException)
380 // {
381 // String2IntMap::const_iterator ii = m_name2index.find( elementName );
382 // if( ii == m_name2index.end() )
383 // {
384 // OUStringBuffer buf( 128 );
385 // buf.appendAscii( "Table " );
386 // buf.append( elementName );
387 // buf.appendAscii( " is unknown, so it can't be dropped" );
388 // throw com::sun::star::container::NoSuchElementException(
389 // buf.makeStringAndClear(), *this );
390 // }
391 // dropByIndex( ii->second );
392 // }
394 void Tables::dropByIndex( sal_Int32 index )
395 throw (::com::sun::star::sdbc::SQLException,
396 ::com::sun::star::lang::IndexOutOfBoundsException,
397 ::com::sun::star::uno::RuntimeException)
399 osl::MutexGuard guard( m_refMutex->mutex );
400 if( index < 0 || index >= m_values.getLength() )
402 OUStringBuffer buf( 128 );
403 buf.appendAscii( "TABLES: Index out of range (allowed 0 to " );
404 buf.append( (sal_Int32) (m_values.getLength() -1) );
405 buf.appendAscii( ", got " );
406 buf.append( index );
407 buf.appendAscii( ")" );
408 throw com::sun::star::lang::IndexOutOfBoundsException(
409 buf.makeStringAndClear(), *this );
412 Reference< XPropertySet > set;
413 m_values[index] >>= set;
414 Statics &st = getStatics();
415 OUString name,schema;
416 set->getPropertyValue( st.SCHEMA_NAME ) >>= schema;
417 set->getPropertyValue( st.NAME ) >>= name;
418 if( extractStringProperty( set, st.TYPE ).equals( st.VIEW ) && m_pSettings->views.is() )
420 m_pSettings->pViewsImpl->dropByName( concatQualified( schema, name ) );
422 else
424 OUStringBuffer update( 128 );
425 update.appendAscii( RTL_CONSTASCII_STRINGPARAM( "DROP " ) );
426 if( extractStringProperty( set, st.TYPE ).equals( st.VIEW ) )
427 update.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VIEW " ) );
428 else
429 update.appendAscii( RTL_CONSTASCII_STRINGPARAM( "TABLE " ) );
430 bufferQuoteQualifiedIdentifier( update, schema, name );
431 Reference< XStatement > stmt = m_origin->createStatement( );
432 DisposeGuard dispGuard( stmt );
433 stmt->executeUpdate( update.makeStringAndClear() );
436 Container::dropByIndex( index );
440 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > Tables::createDataDescriptor()
441 throw (::com::sun::star::uno::RuntimeException)
443 return new TableDescriptor( m_refMutex, m_origin, m_pSettings );
446 Reference< com::sun::star::container::XNameAccess > Tables::create(
447 const ::rtl::Reference< RefCountedMutex > & refMutex,
448 const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin,
449 ConnectionSettings *pSettings,
450 Tables **ppTables)
452 *ppTables = new Tables( refMutex, origin, pSettings );
453 Reference< com::sun::star::container::XNameAccess > ret = *ppTables;
454 (*ppTables)->refresh();
456 return ret;
459 void Tables::disposing()
461 Container::disposing();