1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dbtools2.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
33 #include "connectivity/dbtools.hxx"
34 #include "connectivity/dbconversion.hxx"
35 #include "connectivity/dbcharset.hxx"
36 #include <unotools/confignode.hxx>
37 #include "resource/sharedresources.hxx"
38 #ifndef CONNECTIVITY_RESOURCE_COMMON_HRC
39 #include "resource/common_res.hrc"
41 #include <com/sun/star/sdbc/XConnection.hpp>
42 #include <com/sun/star/sdbc/ColumnValue.hpp>
43 #include <com/sun/star/sdbc/DataType.hpp>
44 #include <com/sun/star/sdbc/XRow.hpp>
45 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
46 #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
47 #include <com/sun/star/sdbc/XDriverAccess.hpp>
48 #include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
49 #include <com/sun/star/sdbcx/Privilege.hpp>
50 #include <com/sun/star/container/XIndexAccess.hpp>
51 #include <com/sun/star/container/XEnumerationAccess.hpp>
52 #include <com/sun/star/sdbc/KeyRule.hpp>
53 #include <com/sun/star/sdbcx/KeyType.hpp>
54 #include "TConnection.hxx"
55 #include "connectivity/sdbcx/VColumn.hxx"
56 #include <com/sun/star/frame/XModel.hpp>
57 #include <com/sun/star/container/XChild.hpp>
59 #include <tools/diagnose_ex.h>
60 #include <unotools/sharedunocomponent.hxx>
61 #include <comphelper/configurationhelper.hxx>
63 //.........................................................................
66 //.........................................................................
67 using namespace ::com::sun::star::uno
;
68 using namespace ::com::sun::star::beans
;
69 using namespace ::com::sun::star::sdbc
;
70 using namespace ::com::sun::star::sdbcx
;
71 using namespace ::com::sun::star::lang
;
72 using namespace ::com::sun::star::container
;
73 using namespace ::com::sun::star::frame
;
74 using namespace connectivity
;
75 using namespace comphelper
;
77 ::rtl::OUString
createStandardColumnPart(const Reference
< XPropertySet
>& xColProp
,const Reference
< XConnection
>& _xConnection
,const ::rtl::OUString
& _sCreatePattern
)
80 Reference
<XDatabaseMetaData
> xMetaData
= _xConnection
->getMetaData();
82 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
84 ::rtl::OUString sTypeName
;
85 sal_Int32 nDataType
= 0;
86 sal_Int32 nPrecision
= 0;
89 const ::rtl::OUString sQuoteString
= xMetaData
->getIdentifierQuoteString();
90 ::rtl::OUStringBuffer aSql
= ::dbtools::quoteName(sQuoteString
,::comphelper::getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
))));
92 aSql
.appendAscii(" ");
94 nDataType
= nPrecision
= nScale
= 0;
95 sal_Bool bIsAutoIncrement
= sal_False
;
96 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_TYPENAME
)) >>= sTypeName
;
97 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_TYPE
)) >>= nDataType
;
98 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_PRECISION
)) >>= nPrecision
;
99 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_SCALE
)) >>= nScale
;
100 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT
)) >>= bIsAutoIncrement
;
102 // check if the user enter a specific string to create autoincrement values
103 ::rtl::OUString sAutoIncrementValue
;
104 Reference
<XPropertySetInfo
> xPropInfo
= xColProp
->getPropertySetInfo();
105 if ( xPropInfo
.is() && xPropInfo
->hasPropertyByName(rPropMap
.getNameByIndex(PROPERTY_ID_AUTOINCREMENTCREATION
)) )
106 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_AUTOINCREMENTCREATION
)) >>= sAutoIncrementValue
;
107 // look if we have to use precisions
108 sal_Bool bUseLiteral
= sal_False
;
109 ::rtl::OUString sPreFix
,sPostFix
,sCreateParams
;
111 Reference
<XResultSet
> xRes
= xMetaData
->getTypeInfo();
114 Reference
<XRow
> xRow(xRes
,UNO_QUERY
);
117 ::rtl::OUString sTypeName2Cmp
= xRow
->getString(1);
118 sal_Int32 nType
= xRow
->getShort(2);
119 sPreFix
= xRow
->getString (4);
120 sPostFix
= xRow
->getString (5);
121 sCreateParams
= xRow
->getString(6);
122 // first identical type will be used if typename is empty
123 if ( !sTypeName
.getLength() && nType
== nDataType
)
124 sTypeName
= sTypeName2Cmp
;
126 if( sTypeName
.equalsIgnoreAsciiCase(sTypeName2Cmp
) && nType
== nDataType
&& sCreateParams
.getLength() && !xRow
->wasNull())
128 bUseLiteral
= sal_True
;
135 sal_Int32 nIndex
= 0;
136 if ( sAutoIncrementValue
.getLength() && (nIndex
= sTypeName
.indexOf(sAutoIncrementValue
)) != -1 )
138 sTypeName
= sTypeName
.replaceAt(nIndex
,sTypeName
.getLength() - nIndex
,::rtl::OUString());
141 if ( (nPrecision
> 0 || nScale
> 0) && bUseLiteral
)
143 sal_Int32 nParenPos
= sTypeName
.indexOf('(');
144 if ( nParenPos
== -1 )
146 aSql
.append(sTypeName
);
147 aSql
.appendAscii("(");
151 aSql
.append(sTypeName
.copy(0,++nParenPos
));
154 if ( nPrecision
> 0 && nDataType
!= DataType::TIMESTAMP
)
156 aSql
.append(nPrecision
);
157 if ( (nScale
> 0) || (_sCreatePattern
.getLength() && sCreateParams
.indexOf(_sCreatePattern
) != -1) )
158 aSql
.appendAscii(",");
160 if ( (nScale
> 0) || (_sCreatePattern
.getLength() && sCreateParams
.indexOf(_sCreatePattern
) != -1 ) || nDataType
== DataType::TIMESTAMP
)
163 if ( nParenPos
== -1 )
164 aSql
.appendAscii(")");
167 nParenPos
= sTypeName
.indexOf(')',nParenPos
);
168 aSql
.append(sTypeName
.copy(nParenPos
));
172 aSql
.append(sTypeName
); // simply add the type name
174 ::rtl::OUString aDefault
= ::comphelper::getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_DEFAULTVALUE
)));
175 if ( aDefault
.getLength() )
177 aSql
.append(::rtl::OUString::createFromAscii(" DEFAULT "));
178 aSql
.append(sPreFix
);
179 aSql
.append(aDefault
);
180 aSql
.append(sPostFix
);
181 } // if ( aDefault.getLength() )
183 if(::comphelper::getINT32(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_ISNULLABLE
))) == ColumnValue::NO_NULLS
)
184 aSql
.append(::rtl::OUString::createFromAscii(" NOT NULL"));
186 if ( bIsAutoIncrement
&& sAutoIncrementValue
.getLength())
188 aSql
.appendAscii(" ");
189 aSql
.append(sAutoIncrementValue
);
192 return aSql
.makeStringAndClear();
194 // -----------------------------------------------------------------------------
196 ::rtl::OUString
createStandardCreateStatement(const Reference
< XPropertySet
>& descriptor
,const Reference
< XConnection
>& _xConnection
,const ::rtl::OUString
& _sCreatePattern
)
198 ::rtl::OUStringBuffer aSql
= ::rtl::OUString::createFromAscii("CREATE TABLE ");
199 ::rtl::OUString sCatalog
,sSchema
,sTable
,sComposedName
;
201 Reference
<XDatabaseMetaData
> xMetaData
= _xConnection
->getMetaData();
202 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
204 descriptor
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_CATALOGNAME
)) >>= sCatalog
;
205 descriptor
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_SCHEMANAME
)) >>= sSchema
;
206 descriptor
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)) >>= sTable
;
208 sComposedName
= ::dbtools::composeTableName( xMetaData
, sCatalog
, sSchema
, sTable
, sal_True
, ::dbtools::eInTableDefinitions
);
209 if ( !sComposedName
.getLength() )
210 ::dbtools::throwFunctionSequenceException(_xConnection
);
212 aSql
.append(sComposedName
);
213 aSql
.append(::rtl::OUString::createFromAscii(" ("));
216 Reference
<XColumnsSupplier
> xColumnSup(descriptor
,UNO_QUERY
);
217 Reference
<XIndexAccess
> xColumns(xColumnSup
->getColumns(),UNO_QUERY
);
218 // check if there are columns
219 if(!xColumns
.is() || !xColumns
->getCount())
220 ::dbtools::throwFunctionSequenceException(_xConnection
);
222 Reference
< XPropertySet
> xColProp
;
224 sal_Int32 nCount
= xColumns
->getCount();
225 for(sal_Int32 i
=0;i
<nCount
;++i
)
227 if ( (xColumns
->getByIndex(i
) >>= xColProp
) && xColProp
.is() )
229 aSql
.append(createStandardColumnPart(xColProp
,_xConnection
,_sCreatePattern
));
230 aSql
.appendAscii(",");
233 return aSql
.makeStringAndClear();
237 ::rtl::OUString
generateColumnNames(const Reference
<XIndexAccess
>& _xColumns
,const Reference
<XDatabaseMetaData
>& _xMetaData
)
239 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
240 static const ::rtl::OUString
sComma(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(",")));
242 const ::rtl::OUString
sQuote(_xMetaData
->getIdentifierQuoteString());
243 ::rtl::OUString sSql
= ::rtl::OUString::createFromAscii(" (");
244 Reference
< XPropertySet
> xColProp
;
246 sal_Int32 nColCount
= _xColumns
->getCount();
247 for(sal_Int32 i
=0;i
<nColCount
;++i
)
249 if ( (_xColumns
->getByIndex(i
) >>= xColProp
) && xColProp
.is() )
250 sSql
+= ::dbtools::quoteName(sQuote
,::comphelper::getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
))))
255 sSql
= sSql
.replaceAt(sSql
.getLength()-1,1,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")")));
259 // -----------------------------------------------------------------------------
260 ::rtl::OUString
createStandardKeyStatement(const Reference
< XPropertySet
>& descriptor
,const Reference
< XConnection
>& _xConnection
)
262 Reference
<XDatabaseMetaData
> xMetaData
= _xConnection
->getMetaData();
263 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
265 ::rtl::OUStringBuffer aSql
;
267 Reference
<XKeysSupplier
> xKeySup(descriptor
,UNO_QUERY
);
268 Reference
<XIndexAccess
> xKeys
= xKeySup
->getKeys();
271 Reference
< XPropertySet
> xColProp
;
272 Reference
<XIndexAccess
> xColumns
;
273 Reference
<XColumnsSupplier
> xColumnSup
;
274 ::rtl::OUString sCatalog
,sSchema
,sTable
,sComposedName
;
275 sal_Bool bPKey
= sal_False
;
276 for(sal_Int32 i
=0;i
<xKeys
->getCount();++i
)
278 if ( (xKeys
->getByIndex(i
) >>= xColProp
) && xColProp
.is() )
281 sal_Int32 nKeyType
= ::comphelper::getINT32(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_TYPE
)));
283 if ( nKeyType
== KeyType::PRIMARY
)
286 ::dbtools::throwFunctionSequenceException(_xConnection
);
289 xColumnSup
= Reference
<XColumnsSupplier
>(xColProp
,UNO_QUERY
);
290 xColumns
= Reference
<XIndexAccess
>(xColumnSup
->getColumns(),UNO_QUERY
);
291 if(!xColumns
.is() || !xColumns
->getCount())
292 ::dbtools::throwFunctionSequenceException(_xConnection
);
294 const ::rtl::OUString sQuote
= xMetaData
->getIdentifierQuoteString();
295 aSql
.append(::rtl::OUString::createFromAscii(" PRIMARY KEY "));
296 aSql
.append(generateColumnNames(xColumns
,xMetaData
));
298 else if(nKeyType
== KeyType::UNIQUE
)
300 xColumnSup
= Reference
<XColumnsSupplier
>(xColProp
,UNO_QUERY
);
301 xColumns
= Reference
<XIndexAccess
>(xColumnSup
->getColumns(),UNO_QUERY
);
302 if(!xColumns
.is() || !xColumns
->getCount())
303 ::dbtools::throwFunctionSequenceException(_xConnection
);
305 const ::rtl::OUString sQuote
= xMetaData
->getIdentifierQuoteString();
306 aSql
.append(::rtl::OUString::createFromAscii(" UNIQUE "));
307 aSql
.append(generateColumnNames(xColumns
,xMetaData
));
309 else if(nKeyType
== KeyType::FOREIGN
)
311 sal_Int32 nDeleteRule
= getINT32(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_DELETERULE
)));
313 xColumnSup
= Reference
<XColumnsSupplier
>(xColProp
,UNO_QUERY
);
314 xColumns
= Reference
<XIndexAccess
>(xColumnSup
->getColumns(),UNO_QUERY
);
315 if(!xColumns
.is() || !xColumns
->getCount())
316 ::dbtools::throwFunctionSequenceException(_xConnection
);
318 aSql
.append(::rtl::OUString::createFromAscii(" FOREIGN KEY "));
319 ::rtl::OUString sRefTable
= getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_REFERENCEDTABLE
)));
320 ::dbtools::qualifiedNameComponents(xMetaData
,
325 ::dbtools::eInDataManipulation
);
326 sComposedName
= ::dbtools::composeTableName( xMetaData
, sCatalog
, sSchema
, sTable
, sal_True
, ::dbtools::eInTableDefinitions
);
329 if ( !sComposedName
.getLength() )
330 ::dbtools::throwFunctionSequenceException(_xConnection
);
332 aSql
.append(generateColumnNames(xColumns
,xMetaData
));
336 case KeyRule::CASCADE
:
337 aSql
.append(::rtl::OUString::createFromAscii(" ON DELETE CASCADE "));
339 case KeyRule::RESTRICT
:
340 aSql
.append(::rtl::OUString::createFromAscii(" ON DELETE RESTRICT "));
342 case KeyRule::SET_NULL
:
343 aSql
.append(::rtl::OUString::createFromAscii(" ON DELETE SET NULL "));
345 case KeyRule::SET_DEFAULT
:
346 aSql
.append(::rtl::OUString::createFromAscii(" ON DELETE SET DEFAULT "));
356 if ( aSql
.getLength() )
358 if ( aSql
.charAt(aSql
.getLength()-1) == ',' )
359 aSql
.setCharAt(aSql
.getLength()-1,')');
361 aSql
.appendAscii(")");
364 return aSql
.makeStringAndClear();
367 // -----------------------------------------------------------------------------
368 ::rtl::OUString
createSqlCreateTableStatement( const Reference
< XPropertySet
>& descriptor
,
369 const Reference
< XConnection
>& _xConnection
,
370 const ::rtl::OUString
& _sCreatePattern
)
372 ::rtl::OUString aSql
= ::dbtools::createStandardCreateStatement(descriptor
,_xConnection
,_sCreatePattern
);
373 const ::rtl::OUString sKeyStmt
= ::dbtools::createStandardKeyStatement(descriptor
,_xConnection
);
374 if ( sKeyStmt
.getLength() )
378 if ( aSql
.lastIndexOf(',') == (aSql
.getLength()-1) )
379 aSql
= aSql
.replaceAt(aSql
.getLength()-1,1,::rtl::OUString::createFromAscii(")"));
381 aSql
+= ::rtl::OUString::createFromAscii(")");
387 Reference
<XPropertySet
> lcl_createSDBCXColumn(const Reference
<XNameAccess
>& _xPrimaryKeyColumns
,
388 const Reference
<XConnection
>& _xConnection
,
389 const Any
& _aCatalog
,
390 const ::rtl::OUString
& _aSchema
,
391 const ::rtl::OUString
& _aTable
,
392 const ::rtl::OUString
& _rQueryName
,
393 const ::rtl::OUString
& _rName
,
395 sal_Bool _bQueryForInfo
,
396 sal_Bool _bIsAutoIncrement
,
397 sal_Bool _bIsCurrency
,
398 sal_Int32 _nDataType
)
400 Reference
<XPropertySet
> xProp
;
401 Reference
<XDatabaseMetaData
> xMetaData
= _xConnection
->getMetaData();
402 Reference
< XResultSet
> xResult
= xMetaData
->getColumns(_aCatalog
, _aSchema
, _aTable
, _rQueryName
);
406 UStringMixEqual
aMixCompare(_bCase
);
407 Reference
< XRow
> xRow(xResult
,UNO_QUERY
);
408 while( xResult
->next() )
410 if ( aMixCompare(xRow
->getString(4),_rName
) )
412 sal_Int32 nField5
= xRow
->getInt(5);
413 ::rtl::OUString aField6
= xRow
->getString(6);
414 sal_Int32 nField7
= xRow
->getInt(7)
415 , nField9
= xRow
->getInt(9)
416 , nField11
= xRow
->getInt(11);
417 ::rtl::OUString sField13
= xRow
->getString(13);
418 ::comphelper::disposeComponent(xRow
);
420 sal_Bool bAutoIncrement
= _bIsAutoIncrement
421 ,bIsCurrency
= _bIsCurrency
;
422 if ( _bQueryForInfo
)
424 const ::rtl::OUString sQuote
= xMetaData
->getIdentifierQuoteString();
425 ::rtl::OUString sQuotedName
= ::dbtools::quoteName(sQuote
,_rName
);
426 ::rtl::OUString sComposedName
;
427 sComposedName
= composeTableNameForSelect(_xConnection
, getString( _aCatalog
), _aSchema
, _aTable
);
429 ColumnInformationMap
aInfo(_bCase
);
430 collectColumnInformation(_xConnection
,sComposedName
,sQuotedName
,aInfo
);
431 ColumnInformationMap::iterator aIter
= aInfo
.begin();
432 if ( aIter
!= aInfo
.end() )
434 bAutoIncrement
= aIter
->second
.first
.first
;
435 bIsCurrency
= aIter
->second
.first
.second
;
436 if ( DataType::OTHER
== nField5
)
437 nField5
= aIter
->second
.second
;
440 else if ( DataType::OTHER
== nField5
)
441 nField5
= _nDataType
;
443 if ( nField11
!= ColumnValue::NO_NULLS
)
447 if ( _xPrimaryKeyColumns
.is() )
449 if ( _xPrimaryKeyColumns
->hasByName(_rName
) )
450 nField11
= ColumnValue::NO_NULLS
;
455 Reference
< XResultSet
> xPKeys
= xMetaData
->getPrimaryKeys( _aCatalog
, _aSchema
, _aTable
);
456 Reference
< XRow
> xPKeyRow( xPKeys
, UNO_QUERY_THROW
);
457 while( xPKeys
->next() ) // there can be only one primary key
459 ::rtl::OUString sKeyColumn
= xPKeyRow
->getString(4);
460 if ( aMixCompare(_rName
,sKeyColumn
) )
462 nField11
= ColumnValue::NO_NULLS
;
470 OSL_ENSURE( false, "lcl_createSDBCXColumn: caught an exception!" );
474 connectivity::sdbcx::OColumn
* pRet
= new connectivity::sdbcx::OColumn(_rName
,
494 //------------------------------------------------------------------
495 Reference
< XModel
> lcl_getXModel(const Reference
< XInterface
>& _xIface
)
497 Reference
< XInterface
> xParent
= _xIface
;
498 Reference
< XModel
> xModel(xParent
,UNO_QUERY
);;
499 while( xParent
.is() && !xModel
.is() )
501 Reference
<XChild
> xChild(xParent
,UNO_QUERY
);
502 xParent
.set(xChild
.is() ? xChild
->getParent() : Reference
< XInterface
>(),UNO_QUERY
);
503 xModel
.set(xParent
,UNO_QUERY
);
508 // -----------------------------------------------------------------------------
509 Reference
<XPropertySet
> createSDBCXColumn(const Reference
<XPropertySet
>& _xTable
,
510 const Reference
<XConnection
>& _xConnection
,
511 const ::rtl::OUString
& _rName
,
513 sal_Bool _bQueryForInfo
,
514 sal_Bool _bIsAutoIncrement
,
515 sal_Bool _bIsCurrency
,
516 sal_Int32 _nDataType
)
518 Reference
<XPropertySet
> xProp
;
519 OSL_ENSURE(_xTable
.is(),"Table is NULL!");
523 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
524 Reference
<XDatabaseMetaData
> xMetaData
= _xConnection
->getMetaData();
526 aCatalog
= _xTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_CATALOGNAME
));
528 ::rtl::OUString aSchema
, aTable
;
529 _xTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_SCHEMANAME
)) >>= aSchema
;
530 _xTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)) >>= aTable
;
532 Reference
<XKeysSupplier
> xKeysSup(_xTable
,UNO_QUERY
);
533 Reference
<XNameAccess
> xPrimaryKeyColumns
;
536 const Reference
<XIndexAccess
> xKeys
= xKeysSup
->getKeys();
539 const sal_Int32 nKeyCount
= xKeys
->getCount();
540 for(sal_Int32 nKeyIter
= 0; nKeyIter
< nKeyCount
;++nKeyIter
)
542 const Reference
<XPropertySet
> xKey(xKeys
->getByIndex(nKeyIter
),UNO_QUERY_THROW
);
544 xKey
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_TYPE
)) >>= nType
;
545 if ( nType
== KeyType::PRIMARY
)
547 const Reference
<XColumnsSupplier
> xColS(xKey
,UNO_QUERY_THROW
);
548 xPrimaryKeyColumns
= xColS
->getColumns();
551 } // for(sal_Int32 nKeyIter = 0; nKeyIter < nKeyCount;++)
555 xProp
= lcl_createSDBCXColumn(xPrimaryKeyColumns
,_xConnection
,aCatalog
, aSchema
, aTable
, _rName
,_rName
,_bCase
,_bQueryForInfo
,_bIsAutoIncrement
,_bIsCurrency
,_nDataType
);
558 xProp
= lcl_createSDBCXColumn(xPrimaryKeyColumns
,_xConnection
,aCatalog
, aSchema
, aTable
, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("%")),_rName
,_bCase
,_bQueryForInfo
,_bIsAutoIncrement
,_bIsCurrency
,_nDataType
);
560 xProp
= new connectivity::sdbcx::OColumn(_rName
,
561 ::rtl::OUString(),::rtl::OUString(),
562 ColumnValue::NULLABLE_UNKNOWN
,
576 // -----------------------------------------------------------------------------
577 bool getBooleanDataSourceSetting( const Reference
< XConnection
>& _rxConnection
, const sal_Char
* _pAsciiSettingName
)
579 bool bValue( false );
582 Reference
< XPropertySet
> xDataSourceProperties( findDataSource( _rxConnection
), UNO_QUERY
);
583 OSL_ENSURE( xDataSourceProperties
.is(), "::dbtools::getBooleanDataSourceSetting: somebody is using this with a non-SDB-level connection!" );
584 if ( xDataSourceProperties
.is() )
586 Reference
< XPropertySet
> xSettings(
587 xDataSourceProperties
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Settings") ) ),
590 OSL_VERIFY( xSettings
->getPropertyValue( ::rtl::OUString::createFromAscii( _pAsciiSettingName
) ) >>= bValue
);
593 catch( const Exception
& )
595 DBG_UNHANDLED_EXCEPTION();
600 // -----------------------------------------------------------------------------
601 sal_Bool
isDataSourcePropertyEnabled(const Reference
<XInterface
>& _xProp
,const ::rtl::OUString
& _sProperty
,sal_Bool _bDefault
)
603 sal_Bool bEnabled
= _bDefault
;
606 Reference
< XPropertySet
> xProp(findDataSource(_xProp
),UNO_QUERY
);
609 Sequence
< PropertyValue
> aInfo
;
610 xProp
->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Info"))) >>= aInfo
;
611 const PropertyValue
* pValue
=::std::find_if(aInfo
.getConstArray(),
612 aInfo
.getConstArray() + aInfo
.getLength(),
613 ::std::bind2nd(TPropertyValueEqualFunctor(),_sProperty
));
614 if ( pValue
&& pValue
!= (aInfo
.getConstArray() + aInfo
.getLength()) )
615 pValue
->Value
>>= bEnabled
;
620 DBG_UNHANDLED_EXCEPTION();
624 // -----------------------------------------------------------------------------
625 Reference
< XTablesSupplier
> getDataDefinitionByURLAndConnection(
626 const ::rtl::OUString
& _rsUrl
,
627 const Reference
< XConnection
>& _xConnection
,
628 const Reference
< XMultiServiceFactory
>& _rxFactory
)
630 Reference
< XTablesSupplier
> xTablesSup
;
633 Reference
< XDriverAccess
> xManager(
634 _rxFactory
->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.sdbc.DriverManager") ),
636 Reference
< XDataDefinitionSupplier
> xSupp( xManager
->getDriverByURL( _rsUrl
), UNO_QUERY
);
639 xTablesSup
= xSupp
->getDataDefinitionByConnection( _xConnection
);
641 // if we don't get the catalog from the original driver we have to try them all.
642 if ( !xTablesSup
.is() )
644 Reference
< XEnumerationAccess
> xEnumAccess( xManager
, UNO_QUERY_THROW
);
645 Reference
< XEnumeration
> xEnum( xEnumAccess
->createEnumeration(), UNO_QUERY_THROW
);
646 while ( xEnum
.is() && xEnum
->hasMoreElements() && !xTablesSup
.is() )
648 xEnum
->nextElement() >>= xSupp
;
650 xTablesSup
= xSupp
->getDataDefinitionByConnection( _xConnection
);
654 catch( const Exception
& )
656 DBG_UNHANDLED_EXCEPTION();
661 // -----------------------------------------------------------------------------
662 sal_Int32
getTablePrivileges(const Reference
< XDatabaseMetaData
>& _xMetaData
,
663 const ::rtl::OUString
& _sCatalog
,
664 const ::rtl::OUString
& _sSchema
,
665 const ::rtl::OUString
& _sTable
)
667 OSL_ENSURE(_xMetaData
.is(),"Invalid metadata!");
668 sal_Int32 nPrivileges
= 0;
672 if(_sCatalog
.getLength())
674 Reference
< XResultSet
> xPrivileges
= _xMetaData
->getTablePrivileges(aVal
, _sSchema
, _sTable
);
675 Reference
< XRow
> xCurrentRow(xPrivileges
, UNO_QUERY
);
677 if ( xCurrentRow
.is() )
679 ::rtl::OUString sUserWorkingFor
= _xMetaData
->getUserName();
680 static const ::rtl::OUString sSELECT
= ::rtl::OUString::createFromAscii("SELECT");
681 static const ::rtl::OUString sINSERT
= ::rtl::OUString::createFromAscii("INSERT");
682 static const ::rtl::OUString sUPDATE
= ::rtl::OUString::createFromAscii("UPDATE");
683 static const ::rtl::OUString sDELETE
= ::rtl::OUString::createFromAscii("DELETE");
684 static const ::rtl::OUString sREAD
= ::rtl::OUString::createFromAscii("READ");
685 static const ::rtl::OUString sCREATE
= ::rtl::OUString::createFromAscii("CREATE");
686 static const ::rtl::OUString sALTER
= ::rtl::OUString::createFromAscii("ALTER");
687 static const ::rtl::OUString sREFERENCE
= ::rtl::OUString::createFromAscii("REFERENCE");
688 static const ::rtl::OUString sDROP
= ::rtl::OUString::createFromAscii("DROP");
689 // after creation the set is positioned before the first record, per definitionem
691 Reference
< XResultSetMetaDataSupplier
> xSup(xPrivileges
,UNO_QUERY
);
694 Reference
< XResultSetMetaData
> xRsMetaData
= xSup
->getMetaData();
695 if ( xRsMetaData
.is() )
697 sal_Int32 nCount
= xRsMetaData
->getColumnCount();
698 for (sal_Int32 i
=1; i
<=nCount
; ++i
)
700 ::rtl::OUString sColumnName
= xRsMetaData
->getColumnName(i
);
706 ::rtl::OUString sPrivilege
, sGrantee
;
707 while ( xPrivileges
->next() )
710 ::rtl::OUString sCat
, sSchema
, sName
, sGrantor
, sGrantable
;
711 sCat
= xCurrentRow
->getString(1);
712 sSchema
= xCurrentRow
->getString(2);
713 sName
= xCurrentRow
->getString(3);
714 sGrantor
= xCurrentRow
->getString(4);
716 sGrantee
= xCurrentRow
->getString(5);
717 sPrivilege
= xCurrentRow
->getString(6);
719 sGrantable
= xCurrentRow
->getString(7);
722 if (!sUserWorkingFor
.equalsIgnoreAsciiCase(sGrantee
))
725 if (sPrivilege
.equalsIgnoreAsciiCase(sSELECT
))
726 nPrivileges
|= Privilege::SELECT
;
727 else if (sPrivilege
.equalsIgnoreAsciiCase(sINSERT
))
728 nPrivileges
|= Privilege::INSERT
;
729 else if (sPrivilege
.equalsIgnoreAsciiCase(sUPDATE
))
730 nPrivileges
|= Privilege::UPDATE
;
731 else if (sPrivilege
.equalsIgnoreAsciiCase(sDELETE
))
732 nPrivileges
|= Privilege::DELETE
;
733 else if (sPrivilege
.equalsIgnoreAsciiCase(sREAD
))
734 nPrivileges
|= Privilege::READ
;
735 else if (sPrivilege
.equalsIgnoreAsciiCase(sCREATE
))
736 nPrivileges
|= Privilege::CREATE
;
737 else if (sPrivilege
.equalsIgnoreAsciiCase(sALTER
))
738 nPrivileges
|= Privilege::ALTER
;
739 else if (sPrivilege
.equalsIgnoreAsciiCase(sREFERENCE
))
740 nPrivileges
|= Privilege::REFERENCE
;
741 else if (sPrivilege
.equalsIgnoreAsciiCase(sDROP
))
742 nPrivileges
|= Privilege::DROP
;
745 disposeComponent(xPrivileges
);
747 catch(const SQLException
& e
)
749 static ::rtl::OUString sNotSupportedState
= ::rtl::OUString::createFromAscii("IM001");
750 // some drivers don't support any privileges so we assume that we are allowed to do all we want :-)
751 if(e
.SQLState
== sNotSupportedState
)
752 nPrivileges
|= Privilege::DROP
|
753 Privilege::REFERENCE
|
762 OSL_ENSURE(0,"Could not collect the privileges !");
766 // -----------------------------------------------------------------------------
767 // we need some more information about the column
768 void collectColumnInformation(const Reference
< XConnection
>& _xConnection
,
769 const ::rtl::OUString
& _sComposedName
,
770 const ::rtl::OUString
& _rName
,
771 ColumnInformationMap
& _rInfo
)
773 static ::rtl::OUString STR_WHERE
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" WHERE "));
775 ::rtl::OUString sSelect
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT "));
777 sSelect
+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM "));
778 sSelect
+= _sComposedName
;
779 sSelect
+= STR_WHERE
;
780 sSelect
+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0 = 1"));
784 ::utl::SharedUNOComponent
< XStatement
> xStmt( _xConnection
->createStatement() );
785 Reference
< XPropertySet
> xStatementProps( xStmt
, UNO_QUERY_THROW
);
786 xStatementProps
->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_ESCAPEPROCESSING
), makeAny( (sal_Bool
)sal_False
) );
787 Reference
< XResultSet
> xResult( xStmt
->executeQuery( sSelect
), UNO_QUERY_THROW
);
788 Reference
< XResultSetMetaDataSupplier
> xSuppMeta( xResult
, UNO_QUERY_THROW
);
789 Reference
< XResultSetMetaData
> xMeta( xSuppMeta
->getMetaData(), UNO_QUERY_THROW
);
791 sal_Int32 nCount
= xMeta
->getColumnCount();
792 OSL_ENSURE( nCount
!= 0, "::dbtools::collectColumnInformation: result set has empty (column-less) meta data!" );
793 for (sal_Int32 i
=1; i
<= nCount
; ++i
)
795 _rInfo
.insert(ColumnInformationMap::value_type(xMeta
->getColumnName(i
),
796 ColumnInformation(TBoolPair(xMeta
->isAutoIncrement(i
),xMeta
->isCurrency(i
)),xMeta
->getColumnType(i
))));
799 catch( const Exception
& )
801 DBG_UNHANDLED_EXCEPTION();
805 // -----------------------------------------------------------------------------
806 bool isEmbeddedInDatabase( const Reference
< XInterface
>& _rxComponent
, Reference
< XConnection
>& _rxActualConnection
)
808 bool bIsEmbedded
= false;
811 Reference
< XModel
> xModel
= lcl_getXModel( _rxComponent
);
815 Sequence
< PropertyValue
> aArgs
= xModel
->getArgs();
816 const PropertyValue
* pIter
= aArgs
.getConstArray();
817 const PropertyValue
* pEnd
= pIter
+ aArgs
.getLength();
818 for(;pIter
!= pEnd
;++pIter
)
820 if ( pIter
->Name
.equalsAscii("ComponentData") )
822 Sequence
<PropertyValue
> aDocumentContext
;
823 pIter
->Value
>>= aDocumentContext
;
824 const PropertyValue
* pContextIter
= aDocumentContext
.getConstArray();
825 const PropertyValue
* pContextEnd
= pContextIter
+ aDocumentContext
.getLength();
826 for(;pContextIter
!= pContextEnd
;++pContextIter
)
828 if ( pContextIter
->Name
.equalsAscii( "ActiveConnection" )
829 && ( pContextIter
->Value
>>= _rxActualConnection
)
843 // not intereseted in
847 // -----------------------------------------------------------------------------
850 ::rtl::OUString
lcl_getEncodingName( rtl_TextEncoding _eEncoding
)
852 ::rtl::OUString sEncodingName
;
854 OCharsetMap aCharsets
;
855 OCharsetMap::CharsetIterator aEncodingPos
= aCharsets
.find( _eEncoding
);
856 OSL_ENSURE( aEncodingPos
!= aCharsets
.end(), "lcl_getEncodingName: *which* encoding?" );
857 if ( aEncodingPos
!= aCharsets
.end() )
858 sEncodingName
= (*aEncodingPos
).getIanaName();
860 return sEncodingName
;
864 // -----------------------------------------------------------------------------
865 sal_Int32
DBTypeConversion::convertUnicodeString( const ::rtl::OUString
& _rSource
, ::rtl::OString
& _rDest
, rtl_TextEncoding _eEncoding
) SAL_THROW((com::sun::star::sdbc::SQLException
))
867 if ( !rtl_convertUStringToString( &_rDest
.pData
, _rSource
.getStr(), _rSource
.getLength(),
869 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
|
870 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE
|
871 RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0
|
872 RTL_UNICODETOTEXT_FLAGS_NOCOMPOSITE
)
875 SharedResources aResources
;
876 ::rtl::OUString sMessage
= aResources
.getResourceStringWithSubstitution( STR_CANNOT_CONVERT_STRING
,
877 "$string$", _rSource
,
878 "$charset$", lcl_getEncodingName( _eEncoding
)
884 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "22018" ) ),
890 return _rDest
.getLength();
893 // -----------------------------------------------------------------------------
894 sal_Int32
DBTypeConversion::convertUnicodeStringToLength( const ::rtl::OUString
& _rSource
, ::rtl::OString
& _rDest
,
895 sal_Int32 _nMaxLen
, rtl_TextEncoding _eEncoding
) SAL_THROW((SQLException
))
897 sal_Int32 nLen
= convertUnicodeString( _rSource
, _rDest
, _eEncoding
);
898 if ( nLen
> _nMaxLen
)
900 SharedResources aResources
;
901 ::rtl::OUString sMessage
= aResources
.getResourceStringWithSubstitution( STR_STRING_LENGTH_EXCEEDED
,
902 "$string$", _rSource
,
903 "$maxlen$", ::rtl::OUString::valueOf( _nMaxLen
),
904 "$charset$", lcl_getEncodingName( _eEncoding
)
910 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "22001" ) ),
918 ::rtl::OUString
lcl_getReportEngines()
920 static ::rtl::OUString
s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.DataAccess/ReportEngines"));
923 // -----------------------------------------------------------------------------
924 ::rtl::OUString
lcl_getDefaultReportEngine()
926 static ::rtl::OUString
s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("DefaultReportEngine"));
929 // -----------------------------------------------------------------------------
930 ::rtl::OUString
lcl_getReportEngineNames()
932 static ::rtl::OUString
s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("ReportEngineNames"));
935 // -----------------------------------------------------------------------------
936 ::rtl::OUString
getDefaultReportEngineServiceName(const Reference
< XMultiServiceFactory
>& _rxORB
)
938 ::utl::OConfigurationTreeRoot aReportEngines
= ::utl::OConfigurationTreeRoot::createWithServiceFactory(
939 _rxORB
, lcl_getReportEngines(), -1, ::utl::OConfigurationTreeRoot::CM_READONLY
);
941 if ( aReportEngines
.isValid() )
943 ::rtl::OUString sDefaultReportEngineName
;
944 aReportEngines
.getNodeValue(lcl_getDefaultReportEngine()) >>= sDefaultReportEngineName
;
945 if ( sDefaultReportEngineName
.getLength() )
947 ::utl::OConfigurationNode aReportEngineNames
= aReportEngines
.openNode(lcl_getReportEngineNames());
948 if ( aReportEngineNames
.isValid() )
950 ::utl::OConfigurationNode aReportEngine
= aReportEngineNames
.openNode(sDefaultReportEngineName
);
951 if ( aReportEngine
.isValid() )
953 ::rtl::OUString sRet
;
954 const static ::rtl::OUString
s_sService(RTL_CONSTASCII_USTRINGPARAM("ServiceName"));
955 aReportEngine
.getNodeValue(s_sService
) >>= sRet
;
961 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.report.pentaho.SOReportJobFactory"));
964 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.report.pentaho.SOReportJobFactory"));
965 return ::rtl::OUString();
967 // -----------------------------------------------------------------------------
968 //.........................................................................
969 } // namespace dbtools
970 //.........................................................................