LibreOffice Module connectivity (master) 1
pq_xindexes.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*************************************************************************
3 *
4 * Effective License of whole file:
5 *
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.
9 *
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.
14 *
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
19 *
20 * Parts "Copyright by Sun Microsystems, Inc" prior to August 2011:
21 *
22 * The Contents of this file are made available subject to the terms of
23 * the GNU Lesser General Public License Version 2.1
24 *
25 * Copyright: 2000 by Sun Microsystems, Inc.
26 *
27 * Contributor(s): Joerg Budischewski
28 *
29 * All parts contributed on or after August 2011:
30 *
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/.
34 *
35 ************************************************************************/
36
37#include <sal/log.hxx>
38#include <rtl/ref.hxx>
39#include <rtl/ustrbuf.hxx>
40#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
41#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
42#include <com/sun/star/sdbc/SQLException.hpp>
43#include <com/sun/star/sdbc/XRow.hpp>
44#include <com/sun/star/sdbc/XParameters.hpp>
46#include <o3tl/safeint.hxx>
47#include <utility>
48
49#include "pq_xindexes.hxx"
50#include "pq_xindex.hxx"
51#include "pq_statics.hxx"
52#include "pq_tools.hxx"
53
54using osl::MutexGuard;
55
56
58
59using com::sun::star::uno::Any;
60using com::sun::star::uno::UNO_QUERY;
63
64using com::sun::star::container::XEnumerationAccess;
65using com::sun::star::container::XEnumeration;
66
67
68using com::sun::star::sdbcx::XColumnsSupplier;
69
70using com::sun::star::sdbc::XRow;
71using com::sun::star::sdbc::XResultSet;
72using com::sun::star::sdbc::XParameters;
73using com::sun::star::sdbc::XPreparedStatement;
74
75namespace pq_sdbc_driver
76{
77
79 const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
80 const css::uno::Reference< css::sdbc::XConnection > & origin,
81 ConnectionSettings *pSettings,
82 OUString schemaName,
83 OUString tableName)
84 : Container( refMutex, origin, pSettings, getStatics().KEY ),
85 m_schemaName(std::move( schemaName )),
86 m_tableName(std::move( tableName ))
87{
88}
89
91{}
92
94{
95 try
96 {
97 SAL_INFO("connectivity.postgresql", "sdbcx.Indexes get refreshed for table " << m_schemaName << "." << m_tableName);
98
99 osl::MutexGuard guard( m_xMutex->GetMutex() );
100 Statics & st = getStatics();
101
102 Int2StringMap column2NameMap;
104
105 // see XDatabaseMetaData::getIndexInfo()
106 Reference< XPreparedStatement > stmt = m_origin->prepareStatement(
107 "SELECT nspname, " // 1
108 "pg_class.relname, " // 2
109 "class2.relname, " // 3
110 "indisclustered, " // 4
111 "indisunique, " // 5
112 "indisprimary, " // 6
113 "indkey " // 7
114 "FROM pg_index INNER JOIN pg_class ON indrelid = pg_class.oid "
115 "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid "
116 "INNER JOIN pg_class as class2 ON pg_index.indexrelid = class2.oid "
117 "WHERE nspname = ? AND pg_class.relname = ?" );
118
119 Reference< XParameters > params( stmt, UNO_QUERY);
120 params->setString( 1, m_schemaName );
121 params->setString( 2, m_tableName );
122 Reference< XResultSet > rs = stmt->executeQuery();
123
124 Reference< XRow > row( rs, UNO_QUERY );
126 m_values.clear();
127 sal_Int32 index = 0;
128 while( rs->next() )
129 {
130 // C_SCHEMA = 1
131 // C_TABLENAME = 2
132 static const sal_Int32 C_INDEXNAME = 3;
133 static const sal_Int32 C_IS_CLUSTERED = 4;
134 static const sal_Int32 C_IS_UNIQUE = 5;
135 static const sal_Int32 C_IS_PRIMARY = 6;
136 static const sal_Int32 C_COLUMNS = 7;
137 OUString currentIndexName = row->getString( C_INDEXNAME );
138 rtl::Reference<Index> pIndex =
141
142 bool isUnique = row->getBoolean( C_IS_UNIQUE );
143 bool isPrimary = row->getBoolean( C_IS_PRIMARY );
144 bool isClusterd = row->getBoolean( C_IS_CLUSTERED );
146 pIndex->setPropertyValue_NoBroadcast_public(
147 st.IS_UNIQUE, Any( isUnique ) );
148 pIndex->setPropertyValue_NoBroadcast_public(
149 st.IS_PRIMARY_KEY_INDEX, Any( isPrimary ) );
150 pIndex->setPropertyValue_NoBroadcast_public(
151 st.IS_CLUSTERED, Any( isClusterd ) );
152 pIndex->setPropertyValue_NoBroadcast_public(
153 st.NAME, Any( currentIndexName ) );
154
155 std::vector< sal_Int32 > seq = parseIntArray( row->getString( C_COLUMNS ) );
156 Sequence< OUString > columnNames(seq.size());
157 auto columnNamesRange = asNonConstRange(columnNames);
158 for( size_t columns = 0 ; columns < seq.size() ; columns ++ )
159 {
160 columnNamesRange[columns] = column2NameMap[ seq[columns] ];
161 }
162
163 pIndex->setPropertyValue_NoBroadcast_public(
164 st.PRIVATE_COLUMN_INDEXES, Any( columnNames ));
165
166 {
167 m_values.push_back( Any( prop ) );
168 map[ currentIndexName ] = index;
169 ++index;
170 }
171 }
172 m_name2index.swap( map );
173 }
174 catch ( css::sdbc::SQLException & e )
175 {
176 css::uno::Any anyEx = cppu::getCaughtException();
177 throw css::lang::WrappedTargetRuntimeException( e.Message,
178 e.Context, anyEx );
179 }
180
181 fire( RefreshedBroadcaster( *this ) );
182}
183
184
186 const css::uno::Reference< css::beans::XPropertySet >& descriptor )
187{
188 Statics & st = getStatics();
189 OUString name = extractStringProperty( descriptor, st.NAME );
190
191 bool isUnique = extractBoolProperty( descriptor, st.IS_UNIQUE );
192
193 OUStringBuffer buf( 128 );
194
195 buf.append( "CREATE " );
196 if( isUnique )
197 buf.append( "UNIQUE " );
198 buf.append( "INDEX " );
200 buf.append( " ON " );
202
203 buf.append( " ( " );
204
205 Reference< XColumnsSupplier > columns( descriptor, UNO_QUERY );
206 if( columns.is() )
207 {
208 Reference< XEnumerationAccess > access( columns->getColumns(), UNO_QUERY );
209 if( access.is() )
210 {
211 Reference< XEnumeration > xEnum( access->createEnumeration() );
212 bool first = true;
213 while( xEnum.is() && xEnum->hasMoreElements() )
214 {
215 Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY );
216 if( first )
217 {
218 first = false;
219 }
220 else
221 {
222 buf.append( ", " );
223 }
224 buf.append( extractStringProperty( column, st.NAME ) );
225 }
226 }
227 }
228 buf.append( " ) " );
229
230 m_origin->createStatement()->executeUpdate( buf.makeStringAndClear() );
231 refresh();
232}
233
234void Indexes::dropByIndex( sal_Int32 index )
235{
236
237
238 osl::MutexGuard guard( m_xMutex->GetMutex() );
239 if( index < 0 || o3tl::make_unsigned(index) >= m_values.size() )
240 {
241 throw css::lang::IndexOutOfBoundsException(
242 "Indexes: Index out of range (allowed 0 to "
243 + OUString::number( m_values.size() -1 )
244 + ", got " + OUString::number( index )
245 + ")",
246 *this );
247 }
248
250 m_values[index] >>= set;
251 Statics &st = getStatics();
252
253 OUStringBuffer buf( 128 );
254 buf.append( "DROP INDEX " );
256 m_origin->createStatement()->executeUpdate( buf.makeStringAndClear() );
257
259}
260
261
262css::uno::Reference< css::beans::XPropertySet > Indexes::createDataDescriptor()
263{
265}
266
268 const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
269 const css::uno::Reference< css::sdbc::XConnection > & origin,
270 ConnectionSettings *pSettings,
271 const OUString & schemaName,
272 const OUString & tableName)
273{
275 = new Indexes( refMutex, origin, pSettings, schemaName, tableName );
276 pIndexes->refresh();
277 return pIndexes;
278}
279
280
282 const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
283 const css::uno::Reference< css::sdbc::XConnection > & origin,
284 ConnectionSettings *pSettings)
285 : Container( refMutex, origin, pSettings, getStatics().INDEX )
286{}
287
289 const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
290 const css::uno::Reference< css::sdbc::XConnection > & origin,
291 ConnectionSettings *pSettings)
292{
293 return new IndexDescriptors( refMutex, origin, pSettings );
294}
295
296css::uno::Reference< css::beans::XPropertySet > IndexDescriptors::createDataDescriptor()
297{
299}
300
301};
302
303/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
struct _ADOIndex Index
Definition: Awrapadox.hxx:45
ConnectionSettings * m_pSettings
void fire(const EventBroadcastHelper &helper)
css::uno::Reference< css::sdbc::XConnection > m_origin
::rtl::Reference< comphelper::RefCountedMutex > m_xMutex
virtual void SAL_CALL dropByIndex(sal_Int32 index) override
std::vector< css::uno::Any > m_values
virtual css::uno::Reference< css::beans::XPropertySet > SAL_CALL createDataDescriptor() override
static css::uno::Reference< css::container::XNameAccess > create(const ::rtl::Reference< comphelper::RefCountedMutex > &refMutex, const css::uno::Reference< css::sdbc::XConnection > &origin, ConnectionSettings *pSettings)
IndexDescriptors(const ::rtl::Reference< comphelper::RefCountedMutex > &refMutex, const css::uno::Reference< css::sdbc::XConnection > &origin, ConnectionSettings *pSettings)
virtual ~Indexes() override
Definition: pq_xindexes.cxx:90
virtual css::uno::Reference< css::beans::XPropertySet > SAL_CALL createDataDescriptor() override
Indexes(const ::rtl::Reference< comphelper::RefCountedMutex > &refMutex, const css::uno::Reference< css::sdbc::XConnection > &origin, ConnectionSettings *pSettings, OUString schemaName, OUString tableName)
Definition: pq_xindexes.cxx:78
virtual void SAL_CALL refresh() override
Definition: pq_xindexes.cxx:93
virtual void SAL_CALL dropByIndex(sal_Int32 index) override
static css::uno::Reference< css::container::XNameAccess > create(const ::rtl::Reference< comphelper::RefCountedMutex > &refMutex, const css::uno::Reference< css::sdbc::XConnection > &origin, ConnectionSettings *pSettings, const OUString &schemaName, const OUString &tableName)
virtual void SAL_CALL appendByDescriptor(const css::uno::Reference< css::beans::XPropertySet > &descriptor) override
#define SAL_INFO(area, stream)
void set(css::uno::UnoInterfaceReference const &value)
class SAL_NO_VTABLE XPropertySet
Any SAL_CALL getCaughtException()
constexpr OUStringLiteral first
index
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
Statics & getStatics()
Definition: pq_statics.cxx:112
void bufferQuoteQualifiedIdentifier(OUStringBuffer &buf, std::u16string_view schema, std::u16string_view table, ConnectionSettings *settings)
Definition: pq_tools.cxx:181
std::unordered_map< OUString, sal_Int32 > String2IntMap
std::vector< sal_Int32 > parseIntArray(const OUString &str)
Definition: pq_tools.cxx:691
OUString extractStringProperty(const Reference< XPropertySet > &descriptor, const OUString &name)
Definition: pq_tools.cxx:204
void bufferQuoteIdentifier(OUStringBuffer &buf, std::u16string_view toQuote, ConnectionSettings *settings)
Definition: pq_tools.cxx:175
std::unordered_map< sal_Int32, OUString > Int2StringMap
bool extractBoolProperty(const Reference< XPropertySet > &descriptor, const OUString &name)
Definition: pq_tools.cxx:212
void fillAttnum2attnameMap(Int2StringMap &map, const Reference< css::sdbc::XConnection > &conn, const OUString &schema, const OUString &table)
Definition: pq_tools.cxx:707
OUString name
Definition: pq_statics.cxx:74
const char * tableName
Definition: pq_statics.cxx:57
std::map< OUString, rtl::Reference< Entity > > map