Update ooo320-m1
[ooovba.git] / connectivity / source / drivers / postgresql / pq_xkeys.cxx
blob2b9e25ec6437c4541f97fecb0cb1a6eb0b8e2f52
1 /*************************************************************************
3 * $RCSfile: pq_xkeys.cxx,v $
5 * $Revision: 1.1.2.3 $
7 * last change: $Author: jbu $ $Date: 2004/08/29 08:33:32 $
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_xkeys.hxx"
74 #include "pq_xkey.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::lang::WrappedTargetException;
98 using com::sun::star::sdbc::XRow;
99 using com::sun::star::sdbc::XCloseable;
100 using com::sun::star::sdbc::XStatement;
101 using com::sun::star::sdbc::XResultSet;
102 using com::sun::star::sdbc::XParameters;
103 using com::sun::star::sdbc::XPreparedStatement;
104 using com::sun::star::sdbc::XDatabaseMetaData;
106 namespace pq_sdbc_driver
108 #define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
110 Keys::Keys(
111 const ::rtl::Reference< RefCountedMutex > & refMutex,
112 const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin,
113 ConnectionSettings *pSettings,
114 const rtl::OUString &schemaName,
115 const rtl::OUString &tableName)
116 : Container( refMutex, origin, pSettings, getStatics().KEY ),
117 m_schemaName( schemaName ),
118 m_tableName( tableName )
121 Keys::~Keys()
124 static sal_Int32 string2keytype( const rtl::OUString &type )
126 sal_Int32 ret = com::sun::star::sdbcx::KeyType::UNIQUE;
127 if( type.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "p" ) ) == 0 )
128 ret = com::sun::star::sdbcx::KeyType::PRIMARY;
129 else if( type.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "f" ) ) == 0 )
130 ret = com::sun::star::sdbcx::KeyType::FOREIGN;
131 return ret;
134 static sal_Int32 string2keyrule( const rtl::OUString & rule )
136 sal_Int32 ret = com::sun::star::sdbc::KeyRule::NO_ACTION;
137 if( rule.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "r" ) ) == 0 )
138 ret = com::sun::star::sdbc::KeyRule::RESTRICT;
139 else if( rule.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "c" ) ) == 0 )
140 ret = com::sun::star::sdbc::KeyRule::CASCADE;
141 else if( rule.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "n" ) ) == 0 )
142 ret = com::sun::star::sdbc::KeyRule::SET_NULL;
143 else if( rule.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "d" ) ) == 0 )
144 ret = com::sun::star::sdbc::KeyRule::SET_DEFAULT;
145 return ret;
150 // static void fillAttnum2attnameMap(
151 // Int2StringMap &map,
152 // const Reference< com::sun::star::sdbc::XConnection > &conn,
153 // const rtl::OUString &schema,
154 // const rtl::OUString &table )
155 // {
156 // Reference< XPreparedStatement > prep = conn->prepareStatement(
157 // ASCII_STR( "SELECT attname,attnum "
158 // "FROM pg_attribute "
159 // "INNER JOIN pg_class ON attrelid = pg_class.oid "
160 // "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid "
161 // "WHERE relname=? AND nspname=?" ) );
163 // Reference< XParameters > paras( prep, UNO_QUERY );
164 // paras->setString( 1 , table );
165 // paras->setString( 2 , schema );
166 // Reference< XResultSet > rs = prep->executeQuery();
168 // Reference< XRow > xRow( rs , UNO_QUERY );
169 // while( rs->next() )
170 // {
171 // map[ xRow->getInt(2) ] = xRow->getString(1);
172 // }
173 // }
175 // static Sequence< rtl::OUString > resolveColumnNames(
176 // const Int2StringMap &map, const rtl::OUString &array )
177 // {
178 // Sequence< sal_Int32 > intArray = string2intarray( array );
179 // Sequence< ::rtl::OUString > ret( intArray.getLength() );
180 // for( int i = 0; i < intArray.getLength() ; i ++ )
181 // {
182 // Int2StringMap::const_iterator ii = map.find( intArray[i] );
183 // if( ii != map.end() )
184 // ret[i] = ii->second;
185 // }
186 // return ret;
187 // }
189 void Keys::refresh()
190 throw (::com::sun::star::uno::RuntimeException)
194 if( isLog( m_pSettings, LogLevel::INFO ) )
196 rtl::OStringBuffer buf;
197 buf.append( "sdbcx.Keys get refreshed for table " );
198 buf.append( OUStringToOString( m_schemaName, m_pSettings->encoding ) );
199 buf.append( "." );
200 buf.append( OUStringToOString( m_tableName,m_pSettings->encoding ) );
201 log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear().getStr() );
204 osl::MutexGuard guard( m_refMutex->mutex );
205 Statics & st = getStatics();
207 Int2StringMap mainMap;
208 fillAttnum2attnameMap( mainMap, m_origin, m_schemaName, m_tableName );
210 Reference< XPreparedStatement > stmt = m_origin->prepareStatement(
211 ASCII_STR(
212 "SELECT conname, " // 1
213 "contype, " // 2
214 "confupdtype, " // 3
215 "confdeltype, " // 4
216 "class2.relname, " // 5
217 "nmsp2.nspname, " // 6
218 "conkey," // 7
219 "confkey " // 8
220 "FROM pg_constraint INNER JOIN pg_class ON conrelid = pg_class.oid "
221 "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid "
222 "LEFT JOIN pg_class AS class2 ON confrelid = class2.oid "
223 "LEFT JOIN pg_namespace AS nmsp2 ON class2.relnamespace=nmsp2.oid "
224 "WHERE pg_class.relname = ? AND pg_namespace.nspname = ?" ) );
226 Reference< XParameters > paras( stmt, UNO_QUERY );
227 paras->setString( 1 , m_tableName );
228 paras->setString( 2 , m_schemaName );
229 Reference< XResultSet > rs = stmt->executeQuery();
231 Reference< XRow > xRow( rs , UNO_QUERY );
233 String2IntMap map;
234 std::vector< Any, Allocator< Any> > vec;
235 sal_Int32 keyIndex = 0;
236 while( rs->next() )
238 Key * pKey =
239 new Key( m_refMutex, m_origin, m_pSettings , m_schemaName, m_tableName );
240 Reference< com::sun::star::beans::XPropertySet > prop = pKey;
242 pKey->setPropertyValue_NoBroadcast_public(
243 st.NAME, makeAny( xRow->getString( 1 ) ) );
244 sal_Int32 keyType = string2keytype( xRow->getString(2) );
245 pKey->setPropertyValue_NoBroadcast_public( st.TYPE, makeAny( keyType ) );
246 pKey->setPropertyValue_NoBroadcast_public(
247 st.UPDATE_RULE, makeAny( string2keyrule( xRow->getString(3) ) ) );
248 pKey->setPropertyValue_NoBroadcast_public(
249 st.DELETE_RULE, makeAny( string2keyrule( xRow->getString(4) ) ) );
250 pKey->setPropertyValue_NoBroadcast_public(
251 st.PRIVATE_COLUMNS,
252 makeAny(
253 convertMappedIntArray2StringArray(
254 mainMap,
255 string2intarray( xRow->getString( 7 ) ) ) ) );
257 if( com::sun::star::sdbcx::KeyType::FOREIGN == keyType )
259 OUStringBuffer buf( 128 );
260 buf.append( xRow->getString( 6 ) );
261 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "." ) );
262 buf.append( xRow->getString( 5 ) );
263 pKey->setPropertyValue_NoBroadcast_public(
264 st.REFERENCED_TABLE, makeAny( buf.makeStringAndClear() ) );
266 Int2StringMap foreignMap;
267 fillAttnum2attnameMap( foreignMap, m_origin, xRow->getString(6), xRow->getString(5));
268 pKey->setPropertyValue_NoBroadcast_public(
269 st.PRIVATE_FOREIGN_COLUMNS,
270 makeAny(
271 convertMappedIntArray2StringArray(
272 foreignMap,
273 string2intarray( xRow->getString(8) ) ) ) );
276 vec.push_back( makeAny( prop ) );
277 map[ xRow->getString( 1 ) ] = keyIndex;
278 keyIndex ++;
280 m_values = Sequence< com::sun::star::uno::Any > ( & vec[0] , vec.size() );
281 m_name2index.swap( map );
283 catch ( com::sun::star::sdbc::SQLException & e )
285 throw RuntimeException( e.Message , e.Context );
288 fire( RefreshedBroadcaster( *this ) );
292 void Keys::appendByDescriptor(
293 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor )
294 throw (::com::sun::star::sdbc::SQLException,
295 ::com::sun::star::container::ElementExistException,
296 ::com::sun::star::uno::RuntimeException)
298 osl::MutexGuard guard( m_refMutex->mutex );
300 OUStringBuffer buf( 128 );
301 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE " ) );
302 bufferQuoteQualifiedIdentifier( buf, m_schemaName, m_tableName );
303 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " ADD " ) );
304 bufferKey2TableConstraint( buf, descriptor );
306 Reference< XStatement > stmt =
307 m_origin->createStatement();
308 stmt->executeUpdate( buf.makeStringAndClear() );
312 void Keys::dropByIndex( sal_Int32 index )
313 throw (::com::sun::star::sdbc::SQLException,
314 ::com::sun::star::lang::IndexOutOfBoundsException,
315 ::com::sun::star::uno::RuntimeException)
317 osl::MutexGuard guard( m_refMutex->mutex );
318 if( index < 0 || index >= m_values.getLength() )
320 OUStringBuffer buf( 128 );
321 buf.appendAscii( "TABLES: Index out of range (allowed 0 to " );
322 buf.append( (sal_Int32)(m_values.getLength() -1) );
323 buf.appendAscii( ", got " );
324 buf.append( index );
325 buf.appendAscii( ")" );
326 throw com::sun::star::lang::IndexOutOfBoundsException(
327 buf.makeStringAndClear(), *this );
331 Reference< XPropertySet > set;
332 m_values[index] >>= set;
334 OUStringBuffer buf( 128 );
335 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ALTER TABLE " ) );
336 bufferQuoteQualifiedIdentifier( buf, m_schemaName, m_tableName );
337 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " DROP CONSTRAINT " ) );
338 bufferQuoteIdentifier( buf, extractStringProperty( set , getStatics().NAME ) );
339 m_origin->createStatement()->executeUpdate( buf.makeStringAndClear() );
342 Container::dropByIndex( index );
346 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > Keys::createDataDescriptor()
347 throw (::com::sun::star::uno::RuntimeException)
349 return new KeyDescriptor( m_refMutex, m_origin, m_pSettings );
352 Reference< com::sun::star::container::XIndexAccess > Keys::create(
353 const ::rtl::Reference< RefCountedMutex > & refMutex,
354 const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin,
355 ConnectionSettings *pSettings,
356 const rtl::OUString & schemaName,
357 const rtl::OUString & tableName)
359 Keys *pKeys = new Keys( refMutex, origin, pSettings, schemaName, tableName );
360 Reference< com::sun::star::container::XIndexAccess > ret = pKeys;
361 pKeys->refresh();
363 return ret;
365 //_________________________________________________________________________________________
366 KeyDescriptors::KeyDescriptors(
367 const ::rtl::Reference< RefCountedMutex > & refMutex,
368 const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin,
369 ConnectionSettings *pSettings)
370 : Container( refMutex, origin, pSettings, getStatics().KEY )
373 Reference< com::sun::star::container::XIndexAccess > KeyDescriptors::create(
374 const ::rtl::Reference< RefCountedMutex > & refMutex,
375 const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin,
376 ConnectionSettings *pSettings)
378 return new KeyDescriptors( refMutex, origin, pSettings );
381 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > KeyDescriptors::createDataDescriptor()
382 throw (::com::sun::star::uno::RuntimeException)
384 return new KeyDescriptor( m_refMutex, m_origin, m_pSettings );