LibreOffice Module connectivity (master) 1
pq_xtables.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 <rtl/ref.hxx>
38#include <rtl/ustrbuf.hxx>
39#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
40#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
41#include <com/sun/star/sdbc/SQLException.hpp>
42#include <com/sun/star/sdbc/XRow.hpp>
43#include <com/sun/star/sdbcx/Privilege.hpp>
44#include <com/sun/star/sdbc/DataType.hpp>
46#include <o3tl/safeint.hxx>
47
48#include "pq_xtables.hxx"
49#include "pq_xviews.hxx"
50#include "pq_xtable.hxx"
51#include "pq_statics.hxx"
52#include "pq_tools.hxx"
53
54using osl::MutexGuard;
55
57
58using com::sun::star::uno::Any;
59using com::sun::star::uno::UNO_QUERY;
62
63using com::sun::star::container::XEnumerationAccess;
64using com::sun::star::container::XEnumeration;
65
66using com::sun::star::sdbc::XRow;
67using com::sun::star::sdbc::XStatement;
68using com::sun::star::sdbc::XResultSet;
69using com::sun::star::sdbc::XDatabaseMetaData;
70using com::sun::star::sdbcx::XColumnsSupplier;
71using com::sun::star::sdbcx::XKeysSupplier;
72
73namespace pq_sdbc_driver
74{
76 const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
77 const css::uno::Reference< css::sdbc::XConnection > & origin,
78 ConnectionSettings *pSettings )
79 : Container( refMutex, origin, pSettings, getStatics().TABLE )
80{}
81
83{}
84
86{
87 try
88 {
89 osl::MutexGuard guard( m_xMutex->GetMutex() );
90 Statics & st = getStatics();
91
92 Reference< XDatabaseMetaData > meta = m_origin->getMetaData();
93
95 meta->getTables( Any(), st.cPERCENT,st.cPERCENT, Sequence< OUString > () );
96
97 Reference< XRow > xRow( rs , UNO_QUERY );
98
100
101 m_values.clear();
102 sal_Int32 tableIndex = 0;
103 while( rs->next() )
104 {
105 // if creating all these tables turns out to have too bad performance, we might
106 // instead offer a factory interface
107 rtl::Reference<Table> pTable =
110
111 OUString name = xRow->getString( TABLE_INDEX_NAME+1);
112 OUString schema = xRow->getString( TABLE_INDEX_SCHEMA+1);
113 pTable->setPropertyValue_NoBroadcast_public(
114 st.CATALOG_NAME , Any(xRow->getString( TABLE_INDEX_CATALOG+1) ) );
115 pTable->setPropertyValue_NoBroadcast_public( st.NAME , Any( name ) );
116 pTable->setPropertyValue_NoBroadcast_public( st.SCHEMA_NAME , Any( schema ));
117 pTable->setPropertyValue_NoBroadcast_public(
118 st.TYPE , Any( xRow->getString( TABLE_INDEX_TYPE+1) ) );
119 pTable->setPropertyValue_NoBroadcast_public(
120 st.DESCRIPTION , Any( xRow->getString( TABLE_INDEX_REMARKS+1) ) );
121 pTable->setPropertyValue_NoBroadcast_public(
122 st.PRIVILEGES ,
123 Any( sal_Int32( css::sdbcx::Privilege::SELECT |
124 css::sdbcx::Privilege::INSERT |
125 css::sdbcx::Privilege::UPDATE |
126 css::sdbcx::Privilege::DELETE |
127 css::sdbcx::Privilege::READ |
128 css::sdbcx::Privilege::CREATE |
129 css::sdbcx::Privilege::ALTER |
130 css::sdbcx::Privilege::REFERENCE |
131 css::sdbcx::Privilege::DROP ) ) );
132
133 {
134 m_values.push_back( Any( prop ) );
135 map[ schema + "." + name ] = tableIndex;
136 ++tableIndex;
137 }
138 }
139 m_name2index.swap( map );
140 }
141 catch ( const css::sdbc::SQLException & e )
142 {
143 css::uno::Any anyEx = cppu::getCaughtException();
144 throw css::lang::WrappedTargetRuntimeException( e.Message,
145 e.Context, anyEx );
146 }
147
148 fire( RefreshedBroadcaster( *this ) );
149}
150
151
153 OUStringBuffer &buf, const Reference< XColumnsSupplier > & columnSupplier, ConnectionSettings *settings )
154{
155 if( !columnSupplier.is() )
156 return;
157
158 Reference< XEnumerationAccess > columns( columnSupplier->getColumns(),UNO_QUERY );
159 if( !columns.is() )
160 return;
161
162 Reference< XEnumeration > xEnum( columns->createEnumeration() );
163 bool first = true;
164 Statics & st = getStatics();
165
166 while( xEnum.is() && xEnum->hasMoreElements() )
167 {
168 if( first )
169 {
170 first = false;
171 }
172 else
173 {
174 buf.append( ", " );
175 }
176 Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY );
177 OUString name = extractStringProperty( column, st.NAME );
178 OUString defaultValue = extractStringProperty( column, st.DEFAULT_VALUE );
179 bool isNullable = extractBoolProperty( column, st.IS_NULLABLE );
181
182 bufferQuoteIdentifier( buf, name, settings );
183
184 OUString type = sqltype2string( column );
185 if( isAutoIncrement )
186 {
187 sal_Int32 dataType = 0;
188 column->getPropertyValue( st.TYPE ) >>= dataType;
189 if( css::sdbc::DataType::INTEGER == dataType )
190 {
191 buf.append( " serial ");
192 isNullable = false;
193 }
194 else if( css::sdbc::DataType::BIGINT == dataType )
195 {
196 buf.append( " serial8 " );
197 isNullable = false;
198 }
199 else
200 buf.append( type );
201 }
202 else
203 {
204 buf.append( type );
205 }
206 if( !defaultValue.isEmpty() )
207 {
208 bufferQuoteConstant( buf, defaultValue, settings );
209 }
210
211 if( ! isNullable )
212 buf.append( " NOT NULL " );
213
214 }
215}
216
217static void appendKeyList(
218 OUStringBuffer & buf, const Reference< XKeysSupplier > &keySupplier, ConnectionSettings *settings )
219{
220 if( !keySupplier.is() )
221 return;
222
223 Reference< XEnumerationAccess > keys( keySupplier->getKeys(), UNO_QUERY );
224 if(keys.is() )
225 {
226 Reference< XEnumeration > xEnum = keys->createEnumeration();
227 while( xEnum.is() && xEnum->hasMoreElements() )
228 {
229 buf.append( ", " );
230 Reference< XPropertySet > key( xEnum->nextElement(), UNO_QUERY );
231 bufferKey2TableConstraint( buf, key, settings );
232 }
233 }
234}
235
237 const css::uno::Reference< css::beans::XPropertySet >& descriptor )
238{
239 osl::MutexGuard guard( m_xMutex->GetMutex() );
241 m_origin->createStatement();
242
243 Statics &st = getStatics();
244 OUString name,schema;
245 descriptor->getPropertyValue( st.SCHEMA_NAME ) >>= schema;
246 descriptor->getPropertyValue( st.NAME ) >>= name;
247
248 TransactionGuard transaction( stmt );
249
250 OUStringBuffer buf( 128 );
251 buf.append( "CREATE TABLE" );
253 buf.append( "(" );
254
255 // columns
256 Reference< XColumnsSupplier > supplier( descriptor, UNO_QUERY );
257 appendColumnList( buf, supplier, m_pSettings );
258
259 appendKeyList( buf, Reference< XKeysSupplier >( descriptor, UNO_QUERY ), m_pSettings );
260
261 buf.append( ") " );
262 // execute the creation !
263 transaction.executeUpdate( buf.makeStringAndClear() );
264
265 // description...
266 OUString description = extractStringProperty( descriptor, st.DESCRIPTION );
267 if( !description.isEmpty() )
268 {
269 buf.truncate();
270 buf.append( "COMMENT ON TABLE" );
272 buf.append( "IS " );
273 bufferQuoteConstant( buf, description, m_pSettings);
274
275 transaction.executeUpdate( buf.makeStringAndClear() );
276 }
277
278 // column descriptions
279 if( supplier.is() )
280 {
281 Reference< XEnumerationAccess > columns( supplier->getColumns(),UNO_QUERY );
282 if( columns.is() )
283 {
284 Reference< XEnumeration > xEnum( columns->createEnumeration() );
285 while( xEnum.is() && xEnum->hasMoreElements() )
286 {
287 Reference< XPropertySet > column( xEnum->nextElement(), UNO_QUERY );
288 description = extractStringProperty( column,st.DESCRIPTION );
289 if( !description.isEmpty() )
290 {
291 buf.truncate();
292 buf.append( "COMMENT ON COLUMN " );
294 buf, schema, name, extractStringProperty( column, st.NAME ), m_pSettings );
295 buf.append( "IS " );
296 bufferQuoteConstant( buf, description, m_pSettings );
297 transaction.executeUpdate( buf.makeStringAndClear() );
298 }
299 }
300 }
301 }
302
303 transaction.commit();
304
305 disposeNoThrow( stmt );
306 // TODO: cheaper recalculate
307// Container::append( concatQualified( schema, name ), descriptor ); // maintain the lists
308 refresh();
309}
310
311void Tables::dropByIndex( sal_Int32 index )
312{
313 osl::MutexGuard guard( m_xMutex->GetMutex() );
314 if( index < 0 || o3tl::make_unsigned(index) >= m_values.size() )
315 {
316 throw css::lang::IndexOutOfBoundsException(
317 "TABLES: Index out of range (allowed 0 to " + OUString::number(m_values.size() -1)
318 + ", got " + OUString::number( index ) + ")",
319 *this );
320 }
321
323 m_values[index] >>= set;
324 Statics &st = getStatics();
325 OUString name,schema;
326 set->getPropertyValue( st.SCHEMA_NAME ) >>= schema;
327 set->getPropertyValue( st.NAME ) >>= name;
328 if( extractStringProperty( set, st.TYPE ) == st.VIEW && m_pSettings->views.is() )
329 {
330 m_pSettings->pViewsImpl->dropByName( concatQualified( schema, name ) );
331 }
332 else
333 {
334 OUStringBuffer update( 128 );
335 update.append( "DROP " );
336 if( extractStringProperty( set, st.TYPE ) == st.VIEW )
337 update.append( "VIEW " );
338 else
339 update.append( "TABLE " );
341 Reference< XStatement > stmt = m_origin->createStatement( );
342 DisposeGuard dispGuard( stmt );
343 stmt->executeUpdate( update.makeStringAndClear() );
344 }
345
347}
348
349
350css::uno::Reference< css::beans::XPropertySet > Tables::createDataDescriptor()
351{
353}
354
356 const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
357 const css::uno::Reference< css::sdbc::XConnection > & origin,
358 ConnectionSettings *pSettings,
359 rtl::Reference<Tables> *ppTables)
360{
361 *ppTables = new Tables( refMutex, origin, pSettings );
362 (*ppTables)->refresh();
363
364 return *ppTables;
365}
366
367};
368
369/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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 void SAL_CALL refresh() override
Definition: pq_xtables.cxx:85
virtual void SAL_CALL dropByIndex(sal_Int32 index) override
Definition: pq_xtables.cxx:311
static css::uno::Reference< css::container::XNameAccess > create(const ::rtl::Reference< comphelper::RefCountedMutex > &refMutex, const css::uno::Reference< css::sdbc::XConnection > &origin, ConnectionSettings *pSettings, rtl::Reference< Tables > *ppTables)
Definition: pq_xtables.cxx:355
Tables(const ::rtl::Reference< comphelper::RefCountedMutex > &refMutex, const css::uno::Reference< css::sdbc::XConnection > &origin, ConnectionSettings *pSettings)
Definition: pq_xtables.cxx:75
virtual ~Tables() override
Definition: pq_xtables.cxx:82
virtual void SAL_CALL appendByDescriptor(const css::uno::Reference< css::beans::XPropertySet > &descriptor) override
Definition: pq_xtables.cxx:236
virtual css::uno::Reference< css::beans::XPropertySet > SAL_CALL createDataDescriptor() override
Definition: pq_xtables.cxx:350
void executeUpdate(const OUString &sql)
Definition: pq_tools.cxx:292
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)
void bufferQuoteConstant(OUStringBuffer &buf, std::u16string_view value, ConnectionSettings *settings)
Definition: pq_tools.cxx:138
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
OUString concatQualified(std::u16string_view a, std::u16string_view b)
Definition: pq_tools.cxx:90
const sal_Int32 TABLE_INDEX_SCHEMA
Definition: pq_statics.hxx:129
static Any isAutoIncrement(std::u16string_view defaultValue)
Definition: pq_xcolumns.cxx:90
const sal_Int32 TABLE_INDEX_TYPE
Definition: pq_statics.hxx:131
std::unordered_map< OUString, sal_Int32 > String2IntMap
OUString sqltype2string(const Reference< XPropertySet > &desc)
Definition: pq_tools.cxx:932
static void appendKeyList(OUStringBuffer &buf, const Reference< XKeysSupplier > &keySupplier, ConnectionSettings *settings)
Definition: pq_xtables.cxx:217
OUString extractStringProperty(const Reference< XPropertySet > &descriptor, const OUString &name)
Definition: pq_tools.cxx:204
void disposeNoThrow(const css::uno::Reference< css::uno::XInterface > &r)
Definition: pq_tools.cxx:235
static void appendColumnList(OUStringBuffer &buf, const Reference< XColumnsSupplier > &columnSupplier, ConnectionSettings *settings)
Definition: pq_xtables.cxx:152
const sal_Int32 TABLE_INDEX_REMARKS
Definition: pq_statics.hxx:132
void bufferQuoteIdentifier(OUStringBuffer &buf, std::u16string_view toQuote, ConnectionSettings *settings)
Definition: pq_tools.cxx:175
const sal_Int32 TABLE_INDEX_NAME
Definition: pq_statics.hxx:130
const sal_Int32 TABLE_INDEX_CATALOG
Definition: pq_statics.hxx:128
void bufferKey2TableConstraint(OUStringBuffer &buf, const Reference< XPropertySet > &key, ConnectionSettings *settings)
Definition: pq_tools.cxx:991
bool extractBoolProperty(const Reference< XPropertySet > &descriptor, const OUString &name)
Definition: pq_tools.cxx:212
bool isNullable
Definition: pq_statics.cxx:64
OUString name
Definition: pq_statics.cxx:74
sal_Int32 type
Definition: pq_statics.cxx:60
std::map< OUString, rtl::Reference< Entity > > map
rtl::Reference< Views > pViewsImpl
css::uno::Reference< css::container::XNameAccess > views
bool update()
TABLE