1 /*************************************************************************
3 * $RCSfile: pq_xindexes.cxx,v $
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,
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 ************************************************************************/
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
;
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 ) )
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
)
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
) );
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(
154 "SELECT nspname, " // 1
155 "pg_class.relname, " // 2
156 "class2.relname, " // 3
157 "indisclustered, " // 4
159 "indisprimary, " // 6
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
);
173 std::vector
< Any
, Allocator
< Any
> > vec
;
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
);
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
;
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 " ) );
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
);
254 Reference
< XEnumerationAccess
> access( columns
->getColumns(), UNO_QUERY
);
257 Reference
< XEnumeration
> xEnum( access
->createEnumeration() );
259 while( xEnum
.is() && xEnum
->hasMoreElements() )
261 Reference
< XPropertySet
> column( xEnum
->nextElement(), UNO_QUERY
);
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() );
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 " );
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
;
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
);