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,
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 <rtl/strbuf.hxx>
40 #include <com/sun/star/sdbc/XRow.hpp>
41 #include <com/sun/star/sdbc/XParameters.hpp>
42 #include <com/sun/star/sdbc/KeyRule.hpp>
43 #include <com/sun/star/sdbcx/KeyType.hpp>
45 #include "pq_xindexes.hxx"
46 #include "pq_xindex.hxx"
47 #include "pq_statics.hxx"
48 #include "pq_tools.hxx"
50 using osl::MutexGuard
;
53 using com::sun::star::beans::XPropertySet
;
55 using com::sun::star::uno::Any
;
56 using com::sun::star::uno::makeAny
;
57 using com::sun::star::uno::UNO_QUERY
;
58 using com::sun::star::uno::Type
;
59 using com::sun::star::uno::XInterface
;
60 using com::sun::star::uno::Reference
;
61 using com::sun::star::uno::Sequence
;
62 using com::sun::star::uno::RuntimeException
;
64 using com::sun::star::container::NoSuchElementException
;
65 using com::sun::star::container::XEnumerationAccess
;
66 using com::sun::star::container::XEnumeration
;
68 using com::sun::star::lang::WrappedTargetException
;
70 using com::sun::star::sdbcx::XColumnsSupplier
;
72 using com::sun::star::sdbc::XRow
;
73 using com::sun::star::sdbc::XCloseable
;
74 using com::sun::star::sdbc::XStatement
;
75 using com::sun::star::sdbc::XResultSet
;
76 using com::sun::star::sdbc::XParameters
;
77 using com::sun::star::sdbc::XPreparedStatement
;
78 using com::sun::star::sdbc::XDatabaseMetaData
;
80 namespace pq_sdbc_driver
84 const ::rtl::Reference
< RefCountedMutex
> & refMutex
,
85 const ::com::sun::star::uno::Reference
< com::sun::star::sdbc::XConnection
> & origin
,
86 ConnectionSettings
*pSettings
,
87 const OUString
&schemaName
,
88 const OUString
&tableName
)
89 : Container( refMutex
, origin
, pSettings
, getStatics().KEY
),
90 m_schemaName( schemaName
),
91 m_tableName( tableName
)
98 void Indexes::refresh()
99 throw (::com::sun::star::uno::RuntimeException
, std::exception
)
103 if( isLog( m_pSettings
, LogLevel::INFO
) )
106 buf
.append( "sdbcx.Indexes get refreshed for table " );
107 buf
.append( OUStringToOString( m_schemaName
, m_pSettings
->encoding
) );
109 buf
.append( OUStringToOString( m_tableName
,m_pSettings
->encoding
) );
110 log( m_pSettings
, LogLevel::INFO
, buf
.makeStringAndClear().getStr() );
113 osl::MutexGuard
guard( m_refMutex
->mutex
);
114 Statics
& st
= getStatics();
116 Int2StringMap column2NameMap
;
117 fillAttnum2attnameMap( column2NameMap
, m_origin
, m_schemaName
, m_tableName
);
119 // see XDatabaseMetaData::getIndexInfo()
120 Reference
< XPreparedStatement
> stmt
= m_origin
->prepareStatement(
121 "SELECT nspname, " // 1
122 "pg_class.relname, " // 2
123 "class2.relname, " // 3
124 "indisclustered, " // 4
126 "indisprimary, " // 6
128 "FROM pg_index INNER JOIN pg_class ON indrelid = pg_class.oid "
129 "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid "
130 "INNER JOIN pg_class as class2 ON pg_index.indexrelid = class2.oid "
131 "WHERE nspname = ? AND pg_class.relname = ?" );
133 Reference
< XParameters
> params( stmt
, UNO_QUERY
);
134 params
->setString( 1, m_schemaName
);
135 params
->setString( 2, m_tableName
);
136 Reference
< XResultSet
> rs
= stmt
->executeQuery();
138 Reference
< XRow
> row( rs
, UNO_QUERY
);
140 m_values
= Sequence
< com::sun::star::uno::Any
> ();
144 static const sal_Int32 C_SCHEMA
= 1;
145 static const sal_Int32 C_TABLENAME
= 2;
146 static const sal_Int32 C_INDEXNAME
= 3;
147 static const sal_Int32 C_IS_CLUSTERED
= 4;
148 static const sal_Int32 C_IS_UNIQUE
= 5;
149 static const sal_Int32 C_IS_PRIMARY
= 6;
150 static const sal_Int32 C_COLUMNS
= 7;
151 OUString currentIndexName
= row
->getString( C_INDEXNAME
);
153 new Index( m_refMutex
, m_origin
, m_pSettings
,
154 m_schemaName
, m_tableName
);
156 (void) C_SCHEMA
; (void) C_TABLENAME
;
157 sal_Bool isUnique
= row
->getBoolean( C_IS_UNIQUE
);
158 sal_Bool isPrimary
= row
->getBoolean( C_IS_PRIMARY
);
159 sal_Bool isClusterd
= row
->getBoolean( C_IS_CLUSTERED
);
160 Reference
< com::sun::star::beans::XPropertySet
> prop
= pIndex
;
161 pIndex
->setPropertyValue_NoBroadcast_public(
162 st
.IS_UNIQUE
, Any( &isUnique
, getBooleanCppuType() ) );
163 pIndex
->setPropertyValue_NoBroadcast_public(
164 st
.IS_PRIMARY_KEY_INDEX
, Any( &isPrimary
, getBooleanCppuType() ) );
165 pIndex
->setPropertyValue_NoBroadcast_public(
166 st
.IS_CLUSTERED
, Any( &isClusterd
, getBooleanCppuType() ) );
167 pIndex
->setPropertyValue_NoBroadcast_public(
168 st
.NAME
, makeAny( currentIndexName
) );
170 Sequence
< sal_Int32
> seq
= parseIntArray( row
->getString( C_COLUMNS
) );
171 Sequence
< OUString
> columnNames(seq
.getLength());
172 for( int columns
= 0 ; columns
< seq
.getLength() ; columns
++ )
174 columnNames
[columns
] = column2NameMap
[ seq
[columns
] ];
177 pIndex
->setPropertyValue_NoBroadcast_public(
178 st
.PRIVATE_COLUMN_INDEXES
, makeAny( columnNames
));
181 const int currentIndex
= index
++;
182 assert(currentIndex
== m_values
.getLength());
183 m_values
.realloc( index
);
184 m_values
[currentIndex
] = makeAny( prop
);
185 map
[ currentIndexName
] = currentIndex
;
188 m_name2index
.swap( map
);
190 catch ( com::sun::star::sdbc::SQLException
& e
)
192 throw RuntimeException( e
.Message
, e
.Context
);
195 fire( RefreshedBroadcaster( *this ) );
199 void Indexes::appendByDescriptor(
200 const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
>& descriptor
)
201 throw (::com::sun::star::sdbc::SQLException
,
202 ::com::sun::star::container::ElementExistException
,
203 ::com::sun::star::uno::RuntimeException
, std::exception
)
205 Statics
& st
= getStatics();
206 OUString name
= extractStringProperty( descriptor
, st
.NAME
);
208 bool isUnique
= extractBoolProperty( descriptor
, st
.IS_UNIQUE
);
210 OUStringBuffer
buf( 128 );
212 buf
.append( "CREATE " );
214 buf
.append( "UNIQUE " );
215 buf
.append( "INDEX " );
216 bufferQuoteIdentifier( buf
, name
, m_pSettings
);
217 buf
.append( " ON " );
218 bufferQuoteQualifiedIdentifier( buf
, m_schemaName
, m_tableName
, m_pSettings
);
222 Reference
< XColumnsSupplier
> columns( descriptor
, UNO_QUERY
);
225 Reference
< XEnumerationAccess
> access( columns
->getColumns(), UNO_QUERY
);
228 Reference
< XEnumeration
> xEnum( access
->createEnumeration() );
230 while( xEnum
.is() && xEnum
->hasMoreElements() )
232 Reference
< XPropertySet
> column( xEnum
->nextElement(), UNO_QUERY
);
241 buf
.append( extractStringProperty( column
, st
.NAME
) );
247 m_origin
->createStatement()->executeUpdate( buf
.makeStringAndClear() );
251 void Indexes::dropByIndex( sal_Int32 index
)
252 throw (::com::sun::star::sdbc::SQLException
,
253 ::com::sun::star::lang::IndexOutOfBoundsException
,
254 ::com::sun::star::uno::RuntimeException
, std::exception
)
258 osl::MutexGuard
guard( m_refMutex
->mutex
);
259 if( index
< 0 || index
>= m_values
.getLength() )
261 OUStringBuffer
buf( 128 );
262 buf
.appendAscii( "Indexes: Index out of range (allowed 0 to " );
263 buf
.append( (sal_Int32
) (m_values
.getLength() -1) );
264 buf
.appendAscii( ", got " );
266 buf
.appendAscii( ")" );
267 throw com::sun::star::lang::IndexOutOfBoundsException(
268 buf
.makeStringAndClear(), *this );
271 Reference
< XPropertySet
> set
;
272 m_values
[index
] >>= set
;
273 Statics
&st
= getStatics();
275 OUStringBuffer
buf( 128 );
276 buf
.append( "DROP INDEX " );
277 bufferQuoteIdentifier( buf
, extractStringProperty( set
, st
.NAME
), m_pSettings
);
278 m_origin
->createStatement()->executeUpdate( buf
.makeStringAndClear() );
280 Container::dropByIndex( index
);
284 ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> Indexes::createDataDescriptor()
285 throw (::com::sun::star::uno::RuntimeException
, std::exception
)
287 return new IndexDescriptor( m_refMutex
, m_origin
, m_pSettings
);
290 Reference
< com::sun::star::container::XNameAccess
> Indexes::create(
291 const ::rtl::Reference
< RefCountedMutex
> & refMutex
,
292 const ::com::sun::star::uno::Reference
< com::sun::star::sdbc::XConnection
> & origin
,
293 ConnectionSettings
*pSettings
,
294 const OUString
& schemaName
,
295 const OUString
& tableName
)
297 Indexes
*pIndexes
= new Indexes( refMutex
, origin
, pSettings
, schemaName
, tableName
);
298 Reference
< com::sun::star::container::XNameAccess
> ret
= pIndexes
;
305 IndexDescriptors::IndexDescriptors(
306 const ::rtl::Reference
< RefCountedMutex
> & refMutex
,
307 const ::com::sun::star::uno::Reference
< com::sun::star::sdbc::XConnection
> & origin
,
308 ConnectionSettings
*pSettings
)
309 : Container( refMutex
, origin
, pSettings
, getStatics().INDEX
)
312 Reference
< com::sun::star::container::XNameAccess
> IndexDescriptors::create(
313 const ::rtl::Reference
< RefCountedMutex
> & refMutex
,
314 const ::com::sun::star::uno::Reference
< com::sun::star::sdbc::XConnection
> & origin
,
315 ConnectionSettings
*pSettings
)
317 return new IndexDescriptors( refMutex
, origin
, pSettings
);
320 ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> IndexDescriptors::createDataDescriptor()
321 throw (::com::sun::star::uno::RuntimeException
, std::exception
)
323 return new IndexDescriptor( m_refMutex
, m_origin
, m_pSettings
);
328 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */