1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "connectivity/dbtools.hxx"
21 #include "connectivity/dbconversion.hxx"
22 #include "connectivity/dbcharset.hxx"
23 #include "connectivity/SQLStatementHelper.hxx"
24 #include <unotools/confignode.hxx>
25 #include "resource/sharedresources.hxx"
26 #include "resource/common_res.hrc"
27 #include <com/sun/star/sdbc/XConnection.hpp>
28 #include <com/sun/star/sdbc/ColumnValue.hpp>
29 #include <com/sun/star/sdbc/DataType.hpp>
30 #include <com/sun/star/sdbc/DriverManager.hpp>
31 #include <com/sun/star/sdbc/XRow.hpp>
32 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
33 #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
34 #include <com/sun/star/sdbc/XDriverAccess.hpp>
35 #include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
36 #include <com/sun/star/sdbcx/Privilege.hpp>
37 #include <com/sun/star/container/XIndexAccess.hpp>
38 #include <com/sun/star/container/XEnumerationAccess.hpp>
39 #include <com/sun/star/sdbc/KeyRule.hpp>
40 #include <com/sun/star/sdbcx/KeyType.hpp>
41 #include "TConnection.hxx"
42 #include "connectivity/sdbcx/VColumn.hxx"
43 #include <com/sun/star/frame/XModel.hpp>
44 #include <com/sun/star/container/XChild.hpp>
46 #include <tools/diagnose_ex.h>
47 #include <unotools/sharedunocomponent.hxx>
49 //.........................................................................
52 //.........................................................................
53 using namespace ::com::sun::star::uno
;
54 using namespace ::com::sun::star::beans
;
55 using namespace ::com::sun::star::sdbc
;
56 using namespace ::com::sun::star::sdbcx
;
57 using namespace ::com::sun::star::lang
;
58 using namespace ::com::sun::star::container
;
59 using namespace ::com::sun::star::frame
;
60 using namespace connectivity
;
61 using namespace comphelper
;
63 OUString
createStandardColumnPart(const Reference
< XPropertySet
>& xColProp
,const Reference
< XConnection
>& _xConnection
,ISQLStatementHelper
* _pHelper
,const OUString
& _sCreatePattern
)
66 Reference
<XDatabaseMetaData
> xMetaData
= _xConnection
->getMetaData();
68 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
71 sal_Int32 nDataType
= 0;
72 sal_Int32 nPrecision
= 0;
75 const OUString sQuoteString
= xMetaData
->getIdentifierQuoteString();
76 OUStringBuffer aSql
= ::dbtools::quoteName(sQuoteString
,::comphelper::getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
))));
78 aSql
.appendAscii(" ");
80 nDataType
= nPrecision
= nScale
= 0;
81 sal_Bool bIsAutoIncrement
= sal_False
;
82 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_TYPENAME
)) >>= sTypeName
;
83 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_TYPE
)) >>= nDataType
;
84 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_PRECISION
)) >>= nPrecision
;
85 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_SCALE
)) >>= nScale
;
86 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT
)) >>= bIsAutoIncrement
;
88 // check if the user enter a specific string to create autoincrement values
89 OUString sAutoIncrementValue
;
90 Reference
<XPropertySetInfo
> xPropInfo
= xColProp
->getPropertySetInfo();
91 if ( xPropInfo
.is() && xPropInfo
->hasPropertyByName(rPropMap
.getNameByIndex(PROPERTY_ID_AUTOINCREMENTCREATION
)) )
92 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_AUTOINCREMENTCREATION
)) >>= sAutoIncrementValue
;
93 // look if we have to use precisions
94 sal_Bool bUseLiteral
= sal_False
;
95 OUString sPreFix
,sPostFix
,sCreateParams
;
97 Reference
<XResultSet
> xRes
= xMetaData
->getTypeInfo();
100 Reference
<XRow
> xRow(xRes
,UNO_QUERY
);
103 OUString sTypeName2Cmp
= xRow
->getString(1);
104 sal_Int32 nType
= xRow
->getShort(2);
105 sPreFix
= xRow
->getString (4);
106 sPostFix
= xRow
->getString (5);
107 sCreateParams
= xRow
->getString(6);
108 // first identical type will be used if typename is empty
109 if ( sTypeName
.isEmpty() && nType
== nDataType
)
110 sTypeName
= sTypeName2Cmp
;
112 if( sTypeName
.equalsIgnoreAsciiCase(sTypeName2Cmp
) && nType
== nDataType
&& !sCreateParams
.isEmpty() && !xRow
->wasNull())
114 bUseLiteral
= sal_True
;
121 sal_Int32 nIndex
= 0;
122 if ( !sAutoIncrementValue
.isEmpty() && (nIndex
= sTypeName
.indexOf(sAutoIncrementValue
)) != -1 )
124 sTypeName
= sTypeName
.replaceAt(nIndex
,sTypeName
.getLength() - nIndex
,OUString());
127 if ( (nPrecision
> 0 || nScale
> 0) && bUseLiteral
)
129 sal_Int32 nParenPos
= sTypeName
.indexOf('(');
130 if ( nParenPos
== -1 )
132 aSql
.append(sTypeName
);
133 aSql
.appendAscii("(");
137 aSql
.append(sTypeName
.copy(0,++nParenPos
));
140 if ( nPrecision
> 0 && nDataType
!= DataType::TIMESTAMP
)
142 aSql
.append(nPrecision
);
143 if ( (nScale
> 0) || (!_sCreatePattern
.isEmpty() && sCreateParams
.indexOf(_sCreatePattern
) != -1) )
144 aSql
.appendAscii(",");
146 if ( (nScale
> 0) || ( !_sCreatePattern
.isEmpty() && sCreateParams
.indexOf(_sCreatePattern
) != -1 ) || nDataType
== DataType::TIMESTAMP
)
149 if ( nParenPos
== -1 )
150 aSql
.appendAscii(")");
153 nParenPos
= sTypeName
.indexOf(')',nParenPos
);
154 aSql
.append(sTypeName
.copy(nParenPos
));
158 aSql
.append(sTypeName
); // simply add the type name
160 OUString aDefault
= ::comphelper::getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_DEFAULTVALUE
)));
161 if ( !aDefault
.isEmpty() )
163 aSql
.append(OUString(" DEFAULT "));
164 aSql
.append(sPreFix
);
165 aSql
.append(aDefault
);
166 aSql
.append(sPostFix
);
167 } // if ( aDefault.getLength() )
169 if(::comphelper::getINT32(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_ISNULLABLE
))) == ColumnValue::NO_NULLS
)
170 aSql
.append(OUString(" NOT NULL"));
172 if ( bIsAutoIncrement
&& !sAutoIncrementValue
.isEmpty())
174 aSql
.appendAscii(" ");
175 aSql
.append(sAutoIncrementValue
);
179 _pHelper
->addComment(xColProp
,aSql
);
181 return aSql
.makeStringAndClear();
183 // -----------------------------------------------------------------------------
185 OUString
createStandardCreateStatement(const Reference
< XPropertySet
>& descriptor
,const Reference
< XConnection
>& _xConnection
,ISQLStatementHelper
* _pHelper
,const OUString
& _sCreatePattern
)
187 OUStringBuffer
aSql(OUString("CREATE TABLE "));
188 OUString sCatalog
,sSchema
,sTable
,sComposedName
;
190 Reference
<XDatabaseMetaData
> xMetaData
= _xConnection
->getMetaData();
191 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
193 descriptor
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_CATALOGNAME
)) >>= sCatalog
;
194 descriptor
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_SCHEMANAME
)) >>= sSchema
;
195 descriptor
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)) >>= sTable
;
197 sComposedName
= ::dbtools::composeTableName( xMetaData
, sCatalog
, sSchema
, sTable
, sal_True
, ::dbtools::eInTableDefinitions
);
198 if ( sComposedName
.isEmpty() )
199 ::dbtools::throwFunctionSequenceException(_xConnection
);
201 aSql
.append(sComposedName
);
202 aSql
.append(OUString(" ("));
205 Reference
<XColumnsSupplier
> xColumnSup(descriptor
,UNO_QUERY
);
206 Reference
<XIndexAccess
> xColumns(xColumnSup
->getColumns(),UNO_QUERY
);
207 // check if there are columns
208 if(!xColumns
.is() || !xColumns
->getCount())
209 ::dbtools::throwFunctionSequenceException(_xConnection
);
211 Reference
< XPropertySet
> xColProp
;
213 sal_Int32 nCount
= xColumns
->getCount();
214 for(sal_Int32 i
=0;i
<nCount
;++i
)
216 if ( (xColumns
->getByIndex(i
) >>= xColProp
) && xColProp
.is() )
218 aSql
.append(createStandardColumnPart(xColProp
,_xConnection
,_pHelper
,_sCreatePattern
));
219 aSql
.appendAscii(",");
222 return aSql
.makeStringAndClear();
226 OUString
generateColumnNames(const Reference
<XIndexAccess
>& _xColumns
,const Reference
<XDatabaseMetaData
>& _xMetaData
)
228 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
229 static const OUString
sComma(OUString(","));
231 const OUString
sQuote(_xMetaData
->getIdentifierQuoteString());
232 OUString
sSql( " (" );
233 Reference
< XPropertySet
> xColProp
;
235 sal_Int32 nColCount
= _xColumns
->getCount();
236 for(sal_Int32 i
=0;i
<nColCount
;++i
)
238 if ( (_xColumns
->getByIndex(i
) >>= xColProp
) && xColProp
.is() )
239 sSql
+= ::dbtools::quoteName(sQuote
,::comphelper::getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
))))
244 sSql
= sSql
.replaceAt(sSql
.getLength()-1,1,OUString(")"));
248 // -----------------------------------------------------------------------------
249 OUString
createStandardKeyStatement(const Reference
< XPropertySet
>& descriptor
,const Reference
< XConnection
>& _xConnection
)
251 Reference
<XDatabaseMetaData
> xMetaData
= _xConnection
->getMetaData();
252 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
256 Reference
<XKeysSupplier
> xKeySup(descriptor
,UNO_QUERY
);
257 Reference
<XIndexAccess
> xKeys
= xKeySup
->getKeys();
260 Reference
< XPropertySet
> xColProp
;
261 Reference
<XIndexAccess
> xColumns
;
262 Reference
<XColumnsSupplier
> xColumnSup
;
263 OUString sCatalog
,sSchema
,sTable
,sComposedName
;
264 sal_Bool bPKey
= sal_False
;
265 for(sal_Int32 i
=0;i
<xKeys
->getCount();++i
)
267 if ( (xKeys
->getByIndex(i
) >>= xColProp
) && xColProp
.is() )
270 sal_Int32 nKeyType
= ::comphelper::getINT32(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_TYPE
)));
272 if ( nKeyType
== KeyType::PRIMARY
)
275 ::dbtools::throwFunctionSequenceException(_xConnection
);
278 xColumnSup
= Reference
<XColumnsSupplier
>(xColProp
,UNO_QUERY
);
279 xColumns
= Reference
<XIndexAccess
>(xColumnSup
->getColumns(),UNO_QUERY
);
280 if(!xColumns
.is() || !xColumns
->getCount())
281 ::dbtools::throwFunctionSequenceException(_xConnection
);
283 aSql
.append(OUString(" PRIMARY KEY "));
284 aSql
.append(generateColumnNames(xColumns
,xMetaData
));
286 else if(nKeyType
== KeyType::UNIQUE
)
288 xColumnSup
= Reference
<XColumnsSupplier
>(xColProp
,UNO_QUERY
);
289 xColumns
= Reference
<XIndexAccess
>(xColumnSup
->getColumns(),UNO_QUERY
);
290 if(!xColumns
.is() || !xColumns
->getCount())
291 ::dbtools::throwFunctionSequenceException(_xConnection
);
293 aSql
.append(OUString(" UNIQUE "));
294 aSql
.append(generateColumnNames(xColumns
,xMetaData
));
296 else if(nKeyType
== KeyType::FOREIGN
)
298 sal_Int32 nDeleteRule
= getINT32(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_DELETERULE
)));
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 aSql
.append(OUString(" FOREIGN KEY "));
306 OUString sRefTable
= getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_REFERENCEDTABLE
)));
307 ::dbtools::qualifiedNameComponents(xMetaData
,
312 ::dbtools::eInDataManipulation
);
313 sComposedName
= ::dbtools::composeTableName( xMetaData
, sCatalog
, sSchema
, sTable
, sal_True
, ::dbtools::eInTableDefinitions
);
316 if ( sComposedName
.isEmpty() )
317 ::dbtools::throwFunctionSequenceException(_xConnection
);
319 aSql
.append(generateColumnNames(xColumns
,xMetaData
));
323 case KeyRule::CASCADE
:
324 aSql
.append(OUString(" ON DELETE CASCADE "));
326 case KeyRule::RESTRICT
:
327 aSql
.append(OUString(" ON DELETE RESTRICT "));
329 case KeyRule::SET_NULL
:
330 aSql
.append(OUString(" ON DELETE SET NULL "));
332 case KeyRule::SET_DEFAULT
:
333 aSql
.append(OUString(" ON DELETE SET DEFAULT "));
343 if ( !aSql
.isEmpty() )
345 if ( aSql
[aSql
.getLength() - 1] == ',' )
346 aSql
[aSql
.getLength() - 1] = ')';
348 aSql
.appendAscii(")");
351 return aSql
.makeStringAndClear();
354 // -----------------------------------------------------------------------------
355 OUString
createSqlCreateTableStatement( const Reference
< XPropertySet
>& descriptor
,
356 const Reference
< XConnection
>& _xConnection
,
357 ISQLStatementHelper
* _pHelper
,
358 const OUString
& _sCreatePattern
)
360 OUString aSql
= ::dbtools::createStandardCreateStatement(descriptor
,_xConnection
,_pHelper
,_sCreatePattern
);
361 const OUString sKeyStmt
= ::dbtools::createStandardKeyStatement(descriptor
,_xConnection
);
362 if ( !sKeyStmt
.isEmpty() )
366 if ( aSql
.lastIndexOf(',') == (aSql
.getLength()-1) )
367 aSql
= aSql
.replaceAt(aSql
.getLength()-1,1,OUString(")"));
369 aSql
+= OUString(")");
375 Reference
<XPropertySet
> lcl_createSDBCXColumn(const Reference
<XNameAccess
>& _xPrimaryKeyColumns
,
376 const Reference
<XConnection
>& _xConnection
,
377 const Any
& _aCatalog
,
378 const OUString
& _aSchema
,
379 const OUString
& _aTable
,
380 const OUString
& _rQueryName
,
381 const OUString
& _rName
,
383 sal_Bool _bQueryForInfo
,
384 sal_Bool _bIsAutoIncrement
,
385 sal_Bool _bIsCurrency
,
386 sal_Int32 _nDataType
)
388 Reference
<XPropertySet
> xProp
;
389 Reference
<XDatabaseMetaData
> xMetaData
= _xConnection
->getMetaData();
390 Reference
< XResultSet
> xResult
= xMetaData
->getColumns(_aCatalog
, _aSchema
, _aTable
, _rQueryName
);
392 _aCatalog
>>= sCatalog
;
396 UStringMixEqual
aMixCompare(_bCase
);
397 Reference
< XRow
> xRow(xResult
,UNO_QUERY
);
398 while( xResult
->next() )
400 if ( aMixCompare(xRow
->getString(4),_rName
) )
402 sal_Int32 nField5
= xRow
->getInt(5);
403 OUString aField6
= xRow
->getString(6);
404 sal_Int32 nField7
= xRow
->getInt(7)
405 , nField9
= xRow
->getInt(9)
406 , nField11
= xRow
->getInt(11);
407 OUString sField12
= xRow
->getString(12),
408 sField13
= xRow
->getString(13);
409 ::comphelper::disposeComponent(xRow
);
411 sal_Bool bAutoIncrement
= _bIsAutoIncrement
412 ,bIsCurrency
= _bIsCurrency
;
413 if ( _bQueryForInfo
)
415 const OUString sQuote
= xMetaData
->getIdentifierQuoteString();
416 OUString sQuotedName
= ::dbtools::quoteName(sQuote
,_rName
);
417 OUString sComposedName
;
418 sComposedName
= composeTableNameForSelect(_xConnection
, getString( _aCatalog
), _aSchema
, _aTable
);
420 ColumnInformationMap
aInfo(_bCase
);
421 collectColumnInformation(_xConnection
,sComposedName
,sQuotedName
,aInfo
);
422 ColumnInformationMap::iterator aIter
= aInfo
.begin();
423 if ( aIter
!= aInfo
.end() )
425 bAutoIncrement
= aIter
->second
.first
.first
;
426 bIsCurrency
= aIter
->second
.first
.second
;
427 if ( DataType::OTHER
== nField5
)
428 nField5
= aIter
->second
.second
;
431 else if ( DataType::OTHER
== nField5
)
432 nField5
= _nDataType
;
434 if ( nField11
!= ColumnValue::NO_NULLS
)
438 if ( _xPrimaryKeyColumns
.is() )
440 if ( _xPrimaryKeyColumns
->hasByName(_rName
) )
441 nField11
= ColumnValue::NO_NULLS
;
446 Reference
< XResultSet
> xPKeys
= xMetaData
->getPrimaryKeys( _aCatalog
, _aSchema
, _aTable
);
447 Reference
< XRow
> xPKeyRow( xPKeys
, UNO_QUERY_THROW
);
448 while( xPKeys
->next() ) // there can be only one primary key
450 OUString sKeyColumn
= xPKeyRow
->getString(4);
451 if ( aMixCompare(_rName
,sKeyColumn
) )
453 nField11
= ColumnValue::NO_NULLS
;
461 OSL_FAIL( "lcl_createSDBCXColumn: caught an exception!" );
465 connectivity::sdbcx::OColumn
* pRet
= new connectivity::sdbcx::OColumn(_rName
,
489 //------------------------------------------------------------------
490 Reference
< XModel
> lcl_getXModel(const Reference
< XInterface
>& _xIface
)
492 Reference
< XInterface
> xParent
= _xIface
;
493 Reference
< XModel
> xModel(xParent
,UNO_QUERY
);;
494 while( xParent
.is() && !xModel
.is() )
496 Reference
<XChild
> xChild(xParent
,UNO_QUERY
);
497 xParent
.set(xChild
.is() ? xChild
->getParent() : Reference
< XInterface
>(),UNO_QUERY
);
498 xModel
.set(xParent
,UNO_QUERY
);
503 // -----------------------------------------------------------------------------
504 Reference
<XPropertySet
> createSDBCXColumn(const Reference
<XPropertySet
>& _xTable
,
505 const Reference
<XConnection
>& _xConnection
,
506 const OUString
& _rName
,
508 sal_Bool _bQueryForInfo
,
509 sal_Bool _bIsAutoIncrement
,
510 sal_Bool _bIsCurrency
,
511 sal_Int32 _nDataType
)
513 Reference
<XPropertySet
> xProp
;
514 OSL_ENSURE(_xTable
.is(),"Table is NULL!");
518 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
519 Reference
<XDatabaseMetaData
> xMetaData
= _xConnection
->getMetaData();
521 aCatalog
= _xTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_CATALOGNAME
));
523 aCatalog
>>= sCatalog
;
525 OUString aSchema
, aTable
;
526 _xTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_SCHEMANAME
)) >>= aSchema
;
527 _xTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)) >>= aTable
;
529 Reference
<XNameAccess
> xPrimaryKeyColumns
= getPrimaryKeyColumns_throw(_xTable
);
531 xProp
= lcl_createSDBCXColumn(xPrimaryKeyColumns
,_xConnection
,aCatalog
, aSchema
, aTable
, _rName
,_rName
,_bCase
,_bQueryForInfo
,_bIsAutoIncrement
,_bIsCurrency
,_nDataType
);
534 xProp
= lcl_createSDBCXColumn(xPrimaryKeyColumns
,_xConnection
,aCatalog
, aSchema
, aTable
, OUString("%"),_rName
,_bCase
,_bQueryForInfo
,_bIsAutoIncrement
,_bIsCurrency
,_nDataType
);
536 xProp
= new connectivity::sdbcx::OColumn(_rName
,
537 OUString(),OUString(),OUString(),
538 ColumnValue::NULLABLE_UNKNOWN
,
555 // -----------------------------------------------------------------------------
556 bool getBooleanDataSourceSetting( const Reference
< XConnection
>& _rxConnection
, const sal_Char
* _pAsciiSettingName
)
558 bool bValue( false );
561 Reference
< XPropertySet
> xDataSourceProperties( findDataSource( _rxConnection
), UNO_QUERY
);
562 OSL_ENSURE( xDataSourceProperties
.is(), "::dbtools::getBooleanDataSourceSetting: somebody is using this with a non-SDB-level connection!" );
563 if ( xDataSourceProperties
.is() )
565 Reference
< XPropertySet
> xSettings(
566 xDataSourceProperties
->getPropertyValue( OUString( "Settings") ),
569 OSL_VERIFY( xSettings
->getPropertyValue( OUString::createFromAscii( _pAsciiSettingName
) ) >>= bValue
);
572 catch( const Exception
& )
574 DBG_UNHANDLED_EXCEPTION();
578 // -------------------------------------------------------------------------
579 bool getDataSourceSetting( const Reference
< XInterface
>& _xChild
, const OUString
& _sAsciiSettingsName
,
580 Any
& /* [out] */ _rSettingsValue
)
582 bool bIsPresent
= false;
585 const Reference
< XPropertySet
> xDataSourceProperties( findDataSource( _xChild
), UNO_QUERY
);
586 if ( !xDataSourceProperties
.is() )
589 const Reference
< XPropertySet
> xSettings(
590 xDataSourceProperties
->getPropertyValue( OUString( "Settings") ),
594 _rSettingsValue
= xSettings
->getPropertyValue( _sAsciiSettingsName
);
597 catch( const Exception
& )
603 // -------------------------------------------------------------------------
604 bool getDataSourceSetting( const Reference
< XInterface
>& _rxDataSource
, const sal_Char
* _pAsciiSettingsName
,
605 Any
& /* [out] */ _rSettingsValue
)
607 OUString sAsciiSettingsName
= OUString::createFromAscii(_pAsciiSettingsName
);
608 return getDataSourceSetting( _rxDataSource
, sAsciiSettingsName
,_rSettingsValue
);
610 // -----------------------------------------------------------------------------
611 sal_Bool
isDataSourcePropertyEnabled(const Reference
<XInterface
>& _xProp
,const OUString
& _sProperty
,sal_Bool _bDefault
)
613 sal_Bool bEnabled
= _bDefault
;
616 Reference
< XPropertySet
> xProp(findDataSource(_xProp
),UNO_QUERY
);
619 Sequence
< PropertyValue
> aInfo
;
620 xProp
->getPropertyValue(OUString("Info")) >>= aInfo
;
621 const PropertyValue
* pValue
=::std::find_if(aInfo
.getConstArray(),
622 aInfo
.getConstArray() + aInfo
.getLength(),
623 ::std::bind2nd(TPropertyValueEqualFunctor(),_sProperty
));
624 if ( pValue
&& pValue
!= (aInfo
.getConstArray() + aInfo
.getLength()) )
625 pValue
->Value
>>= bEnabled
;
630 DBG_UNHANDLED_EXCEPTION();
634 // -----------------------------------------------------------------------------
635 Reference
< XTablesSupplier
> getDataDefinitionByURLAndConnection(
636 const OUString
& _rsUrl
,
637 const Reference
< XConnection
>& _xConnection
,
638 const Reference
< XComponentContext
>& _rxContext
)
640 Reference
< XTablesSupplier
> xTablesSup
;
643 Reference
< XDriverManager2
> xManager
= DriverManager::create( _rxContext
);
644 Reference
< XDataDefinitionSupplier
> xSupp( xManager
->getDriverByURL( _rsUrl
), UNO_QUERY
);
648 xTablesSup
= xSupp
->getDataDefinitionByConnection( _xConnection
);
649 OSL_ENSURE(xTablesSup
.is(),"No table supplier!");
652 catch( const Exception
& )
654 DBG_UNHANDLED_EXCEPTION();
659 // -----------------------------------------------------------------------------
660 sal_Int32
getTablePrivileges(const Reference
< XDatabaseMetaData
>& _xMetaData
,
661 const OUString
& _sCatalog
,
662 const OUString
& _sSchema
,
663 const OUString
& _sTable
)
665 OSL_ENSURE(_xMetaData
.is(),"Invalid metadata!");
666 sal_Int32 nPrivileges
= 0;
670 if(!_sCatalog
.isEmpty())
672 Reference
< XResultSet
> xPrivileges
= _xMetaData
->getTablePrivileges(aVal
, _sSchema
, _sTable
);
673 Reference
< XRow
> xCurrentRow(xPrivileges
, UNO_QUERY
);
675 const OUString sUserWorkingFor
= _xMetaData
->getUserName();
676 static const OUString
sSELECT( "SELECT" );
677 static const OUString
sINSERT( "INSERT" );
678 static const OUString
sUPDATE( "UPDATE" );
679 static const OUString
sDELETE( "DELETE" );
680 static const OUString
sREAD( "READ" );
681 static const OUString
sCREATE( "CREATE" );
682 static const OUString
sALTER( "ALTER" );
683 static const OUString
sREFERENCE( "REFERENCE" );
684 static const OUString
sDROP( "DROP" );
686 if ( xCurrentRow
.is() )
688 // after creation the set is positioned before the first record, per definition
689 OUString sPrivilege
, sGrantee
;
690 while ( xPrivileges
->next() )
693 OUString sCat
, sSchema
, sName
, sGrantor
, sGrantable
;
694 sCat
= xCurrentRow
->getString(1);
695 sSchema
= xCurrentRow
->getString(2);
696 sName
= xCurrentRow
->getString(3);
697 sGrantor
= xCurrentRow
->getString(4);
699 sGrantee
= xCurrentRow
->getString(5);
700 sPrivilege
= xCurrentRow
->getString(6);
702 sGrantable
= xCurrentRow
->getString(7);
705 if (!sUserWorkingFor
.equalsIgnoreAsciiCase(sGrantee
))
708 if (sPrivilege
.equalsIgnoreAsciiCase(sSELECT
))
709 nPrivileges
|= Privilege::SELECT
;
710 else if (sPrivilege
.equalsIgnoreAsciiCase(sINSERT
))
711 nPrivileges
|= Privilege::INSERT
;
712 else if (sPrivilege
.equalsIgnoreAsciiCase(sUPDATE
))
713 nPrivileges
|= Privilege::UPDATE
;
714 else if (sPrivilege
.equalsIgnoreAsciiCase(sDELETE
))
715 nPrivileges
|= Privilege::DELETE
;
716 else if (sPrivilege
.equalsIgnoreAsciiCase(sREAD
))
717 nPrivileges
|= Privilege::READ
;
718 else if (sPrivilege
.equalsIgnoreAsciiCase(sCREATE
))
719 nPrivileges
|= Privilege::CREATE
;
720 else if (sPrivilege
.equalsIgnoreAsciiCase(sALTER
))
721 nPrivileges
|= Privilege::ALTER
;
722 else if (sPrivilege
.equalsIgnoreAsciiCase(sREFERENCE
))
723 nPrivileges
|= Privilege::REFERENCE
;
724 else if (sPrivilege
.equalsIgnoreAsciiCase(sDROP
))
725 nPrivileges
|= Privilege::DROP
;
728 disposeComponent(xPrivileges
);
730 // Some drivers put a table privilege as soon as any column has the privilege,
731 // some drivers only if all columns have the privilege.
732 // To unifiy the situation, collect column privileges here, too.
733 Reference
< XResultSet
> xColumnPrivileges
= _xMetaData
->getColumnPrivileges(aVal
, _sSchema
, _sTable
, OUString("%"));
734 Reference
< XRow
> xColumnCurrentRow(xColumnPrivileges
, UNO_QUERY
);
735 if ( xColumnCurrentRow
.is() )
737 // after creation the set is positioned before the first record, per definition
738 OUString sPrivilege
, sGrantee
;
739 while ( xColumnPrivileges
->next() )
742 OUString sCat
, sSchema
, sTableName
, sColumnName
, sGrantor
, sGrantable
;
743 sCat
= xColumnCurrentRow
->getString(1);
744 sSchema
= xColumnCurrentRow
->getString(2);
745 sTableName
= xColumnCurrentRow
->getString(3);
746 sColumnName
= xColumnCurrentRow
->getString(4);
747 sGrantor
= xColumnCurrentRow
->getString(5);
749 sGrantee
= xColumnCurrentRow
->getString(6);
750 sPrivilege
= xColumnCurrentRow
->getString(7);
752 sGrantable
= xColumnCurrentRow
->getString(8);
755 if (!sUserWorkingFor
.equalsIgnoreAsciiCase(sGrantee
))
758 if (sPrivilege
.equalsIgnoreAsciiCase(sSELECT
))
759 nPrivileges
|= Privilege::SELECT
;
760 else if (sPrivilege
.equalsIgnoreAsciiCase(sINSERT
))
761 nPrivileges
|= Privilege::INSERT
;
762 else if (sPrivilege
.equalsIgnoreAsciiCase(sUPDATE
))
763 nPrivileges
|= Privilege::UPDATE
;
764 else if (sPrivilege
.equalsIgnoreAsciiCase(sDELETE
))
765 nPrivileges
|= Privilege::DELETE
;
766 else if (sPrivilege
.equalsIgnoreAsciiCase(sREAD
))
767 nPrivileges
|= Privilege::READ
;
768 else if (sPrivilege
.equalsIgnoreAsciiCase(sCREATE
))
769 nPrivileges
|= Privilege::CREATE
;
770 else if (sPrivilege
.equalsIgnoreAsciiCase(sALTER
))
771 nPrivileges
|= Privilege::ALTER
;
772 else if (sPrivilege
.equalsIgnoreAsciiCase(sREFERENCE
))
773 nPrivileges
|= Privilege::REFERENCE
;
774 else if (sPrivilege
.equalsIgnoreAsciiCase(sDROP
))
775 nPrivileges
|= Privilege::DROP
;
778 disposeComponent(xColumnPrivileges
);
780 catch(const SQLException
& e
)
782 static OUString
sNotSupportedState( "IM001" );
783 // some drivers don't support any privileges so we assume that we are allowed to do all we want :-)
784 if(e
.SQLState
== sNotSupportedState
)
785 nPrivileges
|= Privilege::DROP
|
786 Privilege::REFERENCE
|
795 OSL_FAIL("Could not collect the privileges !");
799 // -----------------------------------------------------------------------------
800 // we need some more information about the column
801 void collectColumnInformation(const Reference
< XConnection
>& _xConnection
,
802 const OUString
& _sComposedName
,
803 const OUString
& _rName
,
804 ColumnInformationMap
& _rInfo
)
806 static OUString STR_WHERE
= OUString(" WHERE ");
808 OUString sSelect
= OUString("SELECT ");
810 sSelect
+= OUString(" FROM ");
811 sSelect
+= _sComposedName
;
812 sSelect
+= STR_WHERE
;
813 sSelect
+= OUString("0 = 1");
817 ::utl::SharedUNOComponent
< XStatement
> xStmt( _xConnection
->createStatement() );
818 Reference
< XPropertySet
> xStatementProps( xStmt
, UNO_QUERY_THROW
);
819 xStatementProps
->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_ESCAPEPROCESSING
), makeAny( (sal_Bool
)sal_False
) );
820 Reference
< XResultSet
> xResult( xStmt
->executeQuery( sSelect
), UNO_QUERY_THROW
);
821 Reference
< XResultSetMetaDataSupplier
> xSuppMeta( xResult
, UNO_QUERY_THROW
);
822 Reference
< XResultSetMetaData
> xMeta( xSuppMeta
->getMetaData(), UNO_QUERY_THROW
);
824 sal_Int32 nCount
= xMeta
->getColumnCount();
825 OSL_ENSURE( nCount
!= 0, "::dbtools::collectColumnInformation: result set has empty (column-less) meta data!" );
826 for (sal_Int32 i
=1; i
<= nCount
; ++i
)
828 _rInfo
.insert(ColumnInformationMap::value_type(xMeta
->getColumnName(i
),
829 ColumnInformation(TBoolPair(xMeta
->isAutoIncrement(i
),xMeta
->isCurrency(i
)),xMeta
->getColumnType(i
))));
832 catch( const Exception
& )
834 DBG_UNHANDLED_EXCEPTION();
838 // -----------------------------------------------------------------------------
839 bool isEmbeddedInDatabase( const Reference
< XInterface
>& _rxComponent
, Reference
< XConnection
>& _rxActualConnection
)
841 bool bIsEmbedded
= false;
844 Reference
< XModel
> xModel
= lcl_getXModel( _rxComponent
);
848 Sequence
< PropertyValue
> aArgs
= xModel
->getArgs();
849 const PropertyValue
* pIter
= aArgs
.getConstArray();
850 const PropertyValue
* pEnd
= pIter
+ aArgs
.getLength();
851 for(;pIter
!= pEnd
;++pIter
)
853 if ( pIter
->Name
== "ComponentData" )
855 Sequence
<PropertyValue
> aDocumentContext
;
856 pIter
->Value
>>= aDocumentContext
;
857 const PropertyValue
* pContextIter
= aDocumentContext
.getConstArray();
858 const PropertyValue
* pContextEnd
= pContextIter
+ aDocumentContext
.getLength();
859 for(;pContextIter
!= pContextEnd
;++pContextIter
)
861 if ( pContextIter
->Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ActiveConnection" ) )
862 && ( pContextIter
->Value
>>= _rxActualConnection
)
876 // not intereseted in
880 // -----------------------------------------------------------------------------
883 OUString
lcl_getEncodingName( rtl_TextEncoding _eEncoding
)
885 OUString sEncodingName
;
887 OCharsetMap aCharsets
;
888 OCharsetMap::CharsetIterator aEncodingPos
= aCharsets
.find( _eEncoding
);
889 OSL_ENSURE( aEncodingPos
!= aCharsets
.end(), "lcl_getEncodingName: *which* encoding?" );
890 if ( aEncodingPos
!= aCharsets
.end() )
891 sEncodingName
= (*aEncodingPos
).getIanaName();
893 return sEncodingName
;
897 // -----------------------------------------------------------------------------
898 sal_Int32
DBTypeConversion::convertUnicodeString( const OUString
& _rSource
, OString
& _rDest
, rtl_TextEncoding _eEncoding
) SAL_THROW((com::sun::star::sdbc::SQLException
))
900 if ( !rtl_convertUStringToString( &_rDest
.pData
, _rSource
.getStr(), _rSource
.getLength(),
902 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
|
903 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE
|
904 RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0
|
905 RTL_UNICODETOTEXT_FLAGS_NOCOMPOSITE
)
908 SharedResources aResources
;
909 OUString sMessage
= aResources
.getResourceStringWithSubstitution( STR_CANNOT_CONVERT_STRING
,
910 "$string$", _rSource
,
911 "$charset$", lcl_getEncodingName( _eEncoding
)
923 return _rDest
.getLength();
926 // -----------------------------------------------------------------------------
927 sal_Int32
DBTypeConversion::convertUnicodeStringToLength( const OUString
& _rSource
, OString
& _rDest
,
928 sal_Int32 _nMaxLen
, rtl_TextEncoding _eEncoding
) SAL_THROW((SQLException
))
930 sal_Int32 nLen
= convertUnicodeString( _rSource
, _rDest
, _eEncoding
);
931 if ( nLen
> _nMaxLen
)
933 SharedResources aResources
;
934 OUString sMessage
= aResources
.getResourceStringWithSubstitution( STR_STRING_LENGTH_EXCEEDED
,
935 "$string$", _rSource
,
936 "$maxlen$", OUString::valueOf( _nMaxLen
),
937 "$charset$", lcl_getEncodingName( _eEncoding
)
951 OUString
lcl_getReportEngines()
953 static OUString
s_sNodeName("org.openoffice.Office.DataAccess/ReportEngines");
956 // -----------------------------------------------------------------------------
957 OUString
lcl_getDefaultReportEngine()
959 static OUString
s_sNodeName("DefaultReportEngine");
962 // -----------------------------------------------------------------------------
963 OUString
lcl_getReportEngineNames()
965 static OUString
s_sNodeName("ReportEngineNames");
968 // -----------------------------------------------------------------------------
969 OUString
getDefaultReportEngineServiceName(const Reference
< XComponentContext
>& _rxORB
)
971 ::utl::OConfigurationTreeRoot aReportEngines
= ::utl::OConfigurationTreeRoot::createWithComponentContext(
972 _rxORB
, lcl_getReportEngines(), -1, ::utl::OConfigurationTreeRoot::CM_READONLY
);
974 if ( aReportEngines
.isValid() )
976 OUString sDefaultReportEngineName
;
977 aReportEngines
.getNodeValue(lcl_getDefaultReportEngine()) >>= sDefaultReportEngineName
;
978 if ( !sDefaultReportEngineName
.isEmpty() )
980 ::utl::OConfigurationNode aReportEngineNames
= aReportEngines
.openNode(lcl_getReportEngineNames());
981 if ( aReportEngineNames
.isValid() )
983 ::utl::OConfigurationNode aReportEngine
= aReportEngineNames
.openNode(sDefaultReportEngineName
);
984 if ( aReportEngine
.isValid() )
987 const static OUString
s_sService("ServiceName");
988 aReportEngine
.getNodeValue(s_sService
) >>= sRet
;
994 return OUString("org.libreoffice.report.pentaho.SOReportJobFactory");
997 return OUString("org.libreoffice.report.pentaho.SOReportJobFactory");
1000 // -----------------------------------------------------------------------------
1001 //.........................................................................
1002 } // namespace dbtools
1003 //.........................................................................
1005 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */