merge the formfield patch from ooo-build
[ooovba.git] / connectivity / source / drivers / postgresql / pq_xindexes.cxx
blobea9fd438b119931fe4f2337a6811dd91436815c2
1 /*************************************************************************
3 * $RCSfile: pq_xindexes.cxx,v $
5 * $Revision: 1.1.2.2 $
7 * last change: $Author: jbu $ $Date: 2004/08/29 08:33:31 $
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>
63 #include <hash_map>
65 #include <rtl/ustrbuf.hxx>
66 #include <rtl/strbuf.hxx>
68 #include <com/sun/star/sdbc/XRow.hpp>
69 #include <com/sun/star/sdbc/XParameters.hpp>
70 #include <com/sun/star/sdbc/KeyRule.hpp>
71 #include <com/sun/star/sdbcx/KeyType.hpp>
73 #include "pq_xindexes.hxx"
74 #include "pq_xindex.hxx"
75 #include "pq_statics.hxx"
76 #include "pq_tools.hxx"
78 using osl::MutexGuard;
80 using rtl::OUString;
81 using rtl::OUStringBuffer;
82 using rtl::OUStringToOString;
84 using com::sun::star::beans::XPropertySet;
86 using com::sun::star::uno::Any;
87 using com::sun::star::uno::makeAny;
88 using com::sun::star::uno::UNO_QUERY;
89 using com::sun::star::uno::Type;
90 using com::sun::star::uno::XInterface;
91 using com::sun::star::uno::Reference;
92 using com::sun::star::uno::Sequence;
93 using com::sun::star::uno::RuntimeException;
95 using com::sun::star::container::NoSuchElementException;
96 using com::sun::star::container::XEnumerationAccess;
97 using com::sun::star::container::XEnumeration;
99 using com::sun::star::lang::WrappedTargetException;
101 using com::sun::star::sdbcx::XColumnsSupplier;
103 using com::sun::star::sdbc::XRow;
104 using com::sun::star::sdbc::XCloseable;
105 using com::sun::star::sdbc::XStatement;
106 using com::sun::star::sdbc::XResultSet;
107 using com::sun::star::sdbc::XParameters;
108 using com::sun::star::sdbc::XPreparedStatement;
109 using com::sun::star::sdbc::XDatabaseMetaData;
111 namespace pq_sdbc_driver
113 #define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
115 Indexes::Indexes(
116 const ::rtl::Reference< RefCountedMutex > & refMutex,
117 const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin,
118 ConnectionSettings *pSettings,
119 const rtl::OUString &schemaName,
120 const rtl::OUString &tableName)
121 : Container( refMutex, origin, pSettings, getStatics().KEY ),
122 m_schemaName( schemaName ),
123 m_tableName( tableName )
127 Indexes::~Indexes()
130 void Indexes::refresh()
131 throw (::com::sun::star::uno::RuntimeException)
135 if( isLog( m_pSettings, LogLevel::INFO ) )
137 rtl::OStringBuffer buf;
138 buf.append( "sdbcx.Indexes get refreshed for table " );
139 buf.append( OUStringToOString( m_schemaName, m_pSettings->encoding ) );
140 buf.append( "." );
141 buf.append( OUStringToOString( m_tableName,m_pSettings->encoding ) );
142 log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear().getStr() );
145 osl::MutexGuard guard( m_refMutex->mutex );
146 Statics & st = getStatics();
148 Int2StringMap column2NameMap;
149 fillAttnum2attnameMap( column2NameMap, m_origin, m_schemaName, m_tableName );
151 // see XDatabaseMetaData::getIndexInfo()
152 Reference< XPreparedStatement > stmt = m_origin->prepareStatement(
153 ASCII_STR(
154 "SELECT nspname, " // 1
155 "pg_class.relname, " // 2
156 "class2.relname, " // 3
157 "indisclustered, " // 4
158 "indisunique, " // 5
159 "indisprimary, " // 6
160 "indkey " // 7
161 "FROM pg_index INNER JOIN pg_class ON indrelid = pg_class.oid "
162 "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid "
163 "INNER JOIN pg_class as class2 ON pg_index.indexrelid = class2.oid "
164 "WHERE nspname = ? AND pg_class.relname = ?" ) );
166 Reference< XParameters > params( stmt, UNO_QUERY);
167 params->setString( 1, m_schemaName );
168 params->setString( 2, m_tableName );
169 Reference< XResultSet > rs = stmt->executeQuery();
171 Reference< XRow > row( rs, UNO_QUERY );
172 String2IntMap map;
173 std::vector< Any, Allocator< Any> > vec;
174 sal_Int32 index = 0;
175 while( rs->next() )
177 static const sal_Int32 C_SCHEMA = 1;
178 static const sal_Int32 C_TABLENAME = 2;
179 static const sal_Int32 C_INDEXNAME = 3;
180 static const sal_Int32 C_IS_CLUSTERED = 4;
181 static const sal_Int32 C_IS_UNIQUE = 5;
182 static const sal_Int32 C_IS_PRIMARY = 6;
183 static const sal_Int32 C_COLUMNS = 7;
184 OUString currentIndexName = row->getString( C_INDEXNAME );
185 Index *pIndex =
186 new Index( m_refMutex, m_origin, m_pSettings,
187 m_schemaName, m_tableName );
189 sal_Bool isUnique = row->getBoolean( C_IS_UNIQUE );
190 sal_Bool isPrimary = row->getBoolean( C_IS_PRIMARY );
191 sal_Bool isClusterd = row->getBoolean( C_IS_CLUSTERED );
192 Reference< com::sun::star::beans::XPropertySet > prop = pIndex;
193 pIndex->setPropertyValue_NoBroadcast_public(
194 st.IS_UNIQUE, Any( &isUnique, getBooleanCppuType() ) );
195 pIndex->setPropertyValue_NoBroadcast_public(
196 st.IS_PRIMARY_KEY_INDEX, Any( &isPrimary, getBooleanCppuType() ) );
197 pIndex->setPropertyValue_NoBroadcast_public(
198 st.IS_CLUSTERED, Any( &isClusterd, getBooleanCppuType() ) );
199 pIndex->setPropertyValue_NoBroadcast_public(
200 st.NAME, makeAny( currentIndexName ) );
202 Sequence< sal_Int32 > seq = parseIntArray( row->getString( C_COLUMNS ) );
203 Sequence< OUString > columnNames(seq.getLength());
204 for( int columns = 0 ; columns < seq.getLength() ; columns ++ )
206 columnNames[columns] = column2NameMap[ seq[columns] ];
209 pIndex->setPropertyValue_NoBroadcast_public(
210 st.PRIVATE_COLUMN_INDEXES, makeAny( columnNames ));
212 vec.push_back( makeAny( prop ) );
213 map[ currentIndexName ] = index;
214 index ++;
216 m_values = Sequence< com::sun::star::uno::Any > ( & vec[0] , vec.size() );
217 m_name2index.swap( map );
219 catch ( com::sun::star::sdbc::SQLException & e )
221 throw RuntimeException( e.Message , e.Context );
224 fire( RefreshedBroadcaster( *this ) );
228 void Indexes::appendByDescriptor(
229 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor )
230 throw (::com::sun::star::sdbc::SQLException,
231 ::com::sun::star::container::ElementExistException,
232 ::com::sun::star::uno::RuntimeException)
234 Statics & st = getStatics();
235 OUString name = extractStringProperty( descriptor, st.NAME );
237 sal_Bool isUnique = extractBoolProperty( descriptor, st.IS_UNIQUE );
239 OUStringBuffer buf( 128 );
241 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "CREATE " ) );
242 if( isUnique )
243 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "UNIQUE " ) );
244 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "INDEX " ) );
245 bufferQuoteIdentifier( buf, name );
246 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " ON " ) );
247 bufferQuoteQualifiedIdentifier( buf, m_schemaName, m_tableName );
249 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " ( " ) );
251 Reference< XColumnsSupplier > columns( descriptor, UNO_QUERY );
252 if( columns.is() )
254 Reference< XEnumerationAccess > access( columns->getColumns(), UNO_QUERY );
255 if( access.is() )
257 Reference< XEnumeration > xEnum( access->createEnumeration() );
258 bool first = true;
259 while( xEnum.is() && xEnum->hasMoreElements() )
261 Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY );
262 if( first )
264 first = false;
266 else
268 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", " ) );
270 buf.append( extractStringProperty( column, st.NAME ) );
274 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " ) " ) );
276 m_origin->createStatement()->executeUpdate( buf.makeStringAndClear() );
277 refresh();
280 void Indexes::dropByIndex( sal_Int32 index )
281 throw (::com::sun::star::sdbc::SQLException,
282 ::com::sun::star::lang::IndexOutOfBoundsException,
283 ::com::sun::star::uno::RuntimeException)
287 osl::MutexGuard guard( m_refMutex->mutex );
288 if( index < 0 || index >= m_values.getLength() )
290 OUStringBuffer buf( 128 );
291 buf.appendAscii( "Indexes: Index out of range (allowed 0 to " );
292 buf.append( (sal_Int32) (m_values.getLength() -1) );
293 buf.appendAscii( ", got " );
294 buf.append( index );
295 buf.appendAscii( ")" );
296 throw com::sun::star::lang::IndexOutOfBoundsException(
297 buf.makeStringAndClear(), *this );
300 Reference< XPropertySet > set;
301 m_values[index] >>= set;
302 Statics &st = getStatics();
304 OUStringBuffer buf( 128 );
305 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "DROP INDEX " ) );
306 bufferQuoteIdentifier( buf, extractStringProperty( set, st.NAME ) );
307 m_origin->createStatement()->executeUpdate( buf.makeStringAndClear() );
309 Container::dropByIndex( index );
313 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > Indexes::createDataDescriptor()
314 throw (::com::sun::star::uno::RuntimeException)
316 return new IndexDescriptor( m_refMutex, m_origin, m_pSettings );
319 Reference< com::sun::star::container::XNameAccess > Indexes::create(
320 const ::rtl::Reference< RefCountedMutex > & refMutex,
321 const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin,
322 ConnectionSettings *pSettings,
323 const rtl::OUString & schemaName,
324 const rtl::OUString & tableName)
326 Indexes *pIndexes = new Indexes( refMutex, origin, pSettings, schemaName, tableName );
327 Reference< com::sun::star::container::XNameAccess > ret = pIndexes;
328 pIndexes->refresh();
329 return ret;
333 //_________________________________________________________________________________________
334 IndexDescriptors::IndexDescriptors(
335 const ::rtl::Reference< RefCountedMutex > & refMutex,
336 const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin,
337 ConnectionSettings *pSettings)
338 : Container( refMutex, origin, pSettings, getStatics().INDEX )
341 Reference< com::sun::star::container::XNameAccess > IndexDescriptors::create(
342 const ::rtl::Reference< RefCountedMutex > & refMutex,
343 const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin,
344 ConnectionSettings *pSettings)
346 return new IndexDescriptors( refMutex, origin, pSettings );
349 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > IndexDescriptors::createDataDescriptor()
350 throw (::com::sun::star::uno::RuntimeException)
352 return new IndexDescriptor( m_refMutex, m_origin, m_pSettings );