1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "connectivity/dbtools.hxx"
30 #include "connectivity/dbconversion.hxx"
31 #include "connectivity/dbcharset.hxx"
32 #include "connectivity/SQLStatementHelper.hxx"
33 #include <unotools/confignode.hxx>
34 #include "resource/sharedresources.hxx"
35 #include "resource/common_res.hrc"
36 #include <com/sun/star/sdbc/XConnection.hpp>
37 #include <com/sun/star/sdbc/ColumnValue.hpp>
38 #include <com/sun/star/sdbc/DataType.hpp>
39 #include <com/sun/star/sdbc/XRow.hpp>
40 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
41 #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
42 #include <com/sun/star/sdbc/XDriverAccess.hpp>
43 #include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
44 #include <com/sun/star/sdbcx/Privilege.hpp>
45 #include <com/sun/star/container/XIndexAccess.hpp>
46 #include <com/sun/star/container/XEnumerationAccess.hpp>
47 #include <com/sun/star/sdbc/KeyRule.hpp>
48 #include <com/sun/star/sdbcx/KeyType.hpp>
49 #include "TConnection.hxx"
50 #include "connectivity/sdbcx/VColumn.hxx"
51 #include <com/sun/star/frame/XModel.hpp>
52 #include <com/sun/star/container/XChild.hpp>
54 #include <tools/diagnose_ex.h>
55 #include <unotools/sharedunocomponent.hxx>
57 //.........................................................................
60 //.........................................................................
61 using namespace ::com::sun::star::uno
;
62 using namespace ::com::sun::star::beans
;
63 using namespace ::com::sun::star::sdbc
;
64 using namespace ::com::sun::star::sdbcx
;
65 using namespace ::com::sun::star::lang
;
66 using namespace ::com::sun::star::container
;
67 using namespace ::com::sun::star::frame
;
68 using namespace connectivity
;
69 using namespace comphelper
;
71 ::rtl::OUString
createStandardColumnPart(const Reference
< XPropertySet
>& xColProp
,const Reference
< XConnection
>& _xConnection
,ISQLStatementHelper
* _pHelper
,const ::rtl::OUString
& _sCreatePattern
)
74 Reference
<XDatabaseMetaData
> xMetaData
= _xConnection
->getMetaData();
76 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
78 ::rtl::OUString sTypeName
;
79 sal_Int32 nDataType
= 0;
80 sal_Int32 nPrecision
= 0;
83 const ::rtl::OUString sQuoteString
= xMetaData
->getIdentifierQuoteString();
84 ::rtl::OUStringBuffer aSql
= ::dbtools::quoteName(sQuoteString
,::comphelper::getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
))));
86 aSql
.appendAscii(" ");
88 nDataType
= nPrecision
= nScale
= 0;
89 sal_Bool bIsAutoIncrement
= sal_False
;
90 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_TYPENAME
)) >>= sTypeName
;
91 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_TYPE
)) >>= nDataType
;
92 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_PRECISION
)) >>= nPrecision
;
93 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_SCALE
)) >>= nScale
;
94 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT
)) >>= bIsAutoIncrement
;
96 // check if the user enter a specific string to create autoincrement values
97 ::rtl::OUString sAutoIncrementValue
;
98 Reference
<XPropertySetInfo
> xPropInfo
= xColProp
->getPropertySetInfo();
99 if ( xPropInfo
.is() && xPropInfo
->hasPropertyByName(rPropMap
.getNameByIndex(PROPERTY_ID_AUTOINCREMENTCREATION
)) )
100 xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_AUTOINCREMENTCREATION
)) >>= sAutoIncrementValue
;
101 // look if we have to use precisions
102 sal_Bool bUseLiteral
= sal_False
;
103 ::rtl::OUString sPreFix
,sPostFix
,sCreateParams
;
105 Reference
<XResultSet
> xRes
= xMetaData
->getTypeInfo();
108 Reference
<XRow
> xRow(xRes
,UNO_QUERY
);
111 ::rtl::OUString sTypeName2Cmp
= xRow
->getString(1);
112 sal_Int32 nType
= xRow
->getShort(2);
113 sPreFix
= xRow
->getString (4);
114 sPostFix
= xRow
->getString (5);
115 sCreateParams
= xRow
->getString(6);
116 // first identical type will be used if typename is empty
117 if ( sTypeName
.isEmpty() && nType
== nDataType
)
118 sTypeName
= sTypeName2Cmp
;
120 if( sTypeName
.equalsIgnoreAsciiCase(sTypeName2Cmp
) && nType
== nDataType
&& !sCreateParams
.isEmpty() && !xRow
->wasNull())
122 bUseLiteral
= sal_True
;
129 sal_Int32 nIndex
= 0;
130 if ( !sAutoIncrementValue
.isEmpty() && (nIndex
= sTypeName
.indexOf(sAutoIncrementValue
)) != -1 )
132 sTypeName
= sTypeName
.replaceAt(nIndex
,sTypeName
.getLength() - nIndex
,::rtl::OUString());
135 if ( (nPrecision
> 0 || nScale
> 0) && bUseLiteral
)
137 sal_Int32 nParenPos
= sTypeName
.indexOf('(');
138 if ( nParenPos
== -1 )
140 aSql
.append(sTypeName
);
141 aSql
.appendAscii("(");
145 aSql
.append(sTypeName
.copy(0,++nParenPos
));
148 if ( nPrecision
> 0 && nDataType
!= DataType::TIMESTAMP
)
150 aSql
.append(nPrecision
);
151 if ( (nScale
> 0) || (!_sCreatePattern
.isEmpty() && sCreateParams
.indexOf(_sCreatePattern
) != -1) )
152 aSql
.appendAscii(",");
154 if ( (nScale
> 0) || ( !_sCreatePattern
.isEmpty() && sCreateParams
.indexOf(_sCreatePattern
) != -1 ) || nDataType
== DataType::TIMESTAMP
)
157 if ( nParenPos
== -1 )
158 aSql
.appendAscii(")");
161 nParenPos
= sTypeName
.indexOf(')',nParenPos
);
162 aSql
.append(sTypeName
.copy(nParenPos
));
166 aSql
.append(sTypeName
); // simply add the type name
168 ::rtl::OUString aDefault
= ::comphelper::getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_DEFAULTVALUE
)));
169 if ( !aDefault
.isEmpty() )
171 aSql
.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" DEFAULT ")));
172 aSql
.append(sPreFix
);
173 aSql
.append(aDefault
);
174 aSql
.append(sPostFix
);
175 } // if ( aDefault.getLength() )
177 if(::comphelper::getINT32(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_ISNULLABLE
))) == ColumnValue::NO_NULLS
)
178 aSql
.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" NOT NULL")));
180 if ( bIsAutoIncrement
&& !sAutoIncrementValue
.isEmpty())
182 aSql
.appendAscii(" ");
183 aSql
.append(sAutoIncrementValue
);
187 _pHelper
->addComment(xColProp
,aSql
);
189 return aSql
.makeStringAndClear();
191 // -----------------------------------------------------------------------------
193 ::rtl::OUString
createStandardCreateStatement(const Reference
< XPropertySet
>& descriptor
,const Reference
< XConnection
>& _xConnection
,ISQLStatementHelper
* _pHelper
,const ::rtl::OUString
& _sCreatePattern
)
195 ::rtl::OUStringBuffer
aSql(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CREATE TABLE ")));
196 ::rtl::OUString sCatalog
,sSchema
,sTable
,sComposedName
;
198 Reference
<XDatabaseMetaData
> xMetaData
= _xConnection
->getMetaData();
199 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
201 descriptor
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_CATALOGNAME
)) >>= sCatalog
;
202 descriptor
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_SCHEMANAME
)) >>= sSchema
;
203 descriptor
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)) >>= sTable
;
205 sComposedName
= ::dbtools::composeTableName( xMetaData
, sCatalog
, sSchema
, sTable
, sal_True
, ::dbtools::eInTableDefinitions
);
206 if ( sComposedName
.isEmpty() )
207 ::dbtools::throwFunctionSequenceException(_xConnection
);
209 aSql
.append(sComposedName
);
210 aSql
.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" (")));
213 Reference
<XColumnsSupplier
> xColumnSup(descriptor
,UNO_QUERY
);
214 Reference
<XIndexAccess
> xColumns(xColumnSup
->getColumns(),UNO_QUERY
);
215 // check if there are columns
216 if(!xColumns
.is() || !xColumns
->getCount())
217 ::dbtools::throwFunctionSequenceException(_xConnection
);
219 Reference
< XPropertySet
> xColProp
;
221 sal_Int32 nCount
= xColumns
->getCount();
222 for(sal_Int32 i
=0;i
<nCount
;++i
)
224 if ( (xColumns
->getByIndex(i
) >>= xColProp
) && xColProp
.is() )
226 aSql
.append(createStandardColumnPart(xColProp
,_xConnection
,_pHelper
,_sCreatePattern
));
227 aSql
.appendAscii(",");
230 return aSql
.makeStringAndClear();
234 ::rtl::OUString
generateColumnNames(const Reference
<XIndexAccess
>& _xColumns
,const Reference
<XDatabaseMetaData
>& _xMetaData
)
236 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
237 static const ::rtl::OUString
sComma(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(",")));
239 const ::rtl::OUString
sQuote(_xMetaData
->getIdentifierQuoteString());
240 ::rtl::OUString
sSql( RTL_CONSTASCII_USTRINGPARAM( " (" ));
241 Reference
< XPropertySet
> xColProp
;
243 sal_Int32 nColCount
= _xColumns
->getCount();
244 for(sal_Int32 i
=0;i
<nColCount
;++i
)
246 if ( (_xColumns
->getByIndex(i
) >>= xColProp
) && xColProp
.is() )
247 sSql
+= ::dbtools::quoteName(sQuote
,::comphelper::getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
))))
252 sSql
= sSql
.replaceAt(sSql
.getLength()-1,1,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")")));
256 // -----------------------------------------------------------------------------
257 ::rtl::OUString
createStandardKeyStatement(const Reference
< XPropertySet
>& descriptor
,const Reference
< XConnection
>& _xConnection
)
259 Reference
<XDatabaseMetaData
> xMetaData
= _xConnection
->getMetaData();
260 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
262 ::rtl::OUStringBuffer aSql
;
264 Reference
<XKeysSupplier
> xKeySup(descriptor
,UNO_QUERY
);
265 Reference
<XIndexAccess
> xKeys
= xKeySup
->getKeys();
268 Reference
< XPropertySet
> xColProp
;
269 Reference
<XIndexAccess
> xColumns
;
270 Reference
<XColumnsSupplier
> xColumnSup
;
271 ::rtl::OUString sCatalog
,sSchema
,sTable
,sComposedName
;
272 sal_Bool bPKey
= sal_False
;
273 for(sal_Int32 i
=0;i
<xKeys
->getCount();++i
)
275 if ( (xKeys
->getByIndex(i
) >>= xColProp
) && xColProp
.is() )
278 sal_Int32 nKeyType
= ::comphelper::getINT32(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_TYPE
)));
280 if ( nKeyType
== KeyType::PRIMARY
)
283 ::dbtools::throwFunctionSequenceException(_xConnection
);
286 xColumnSup
= Reference
<XColumnsSupplier
>(xColProp
,UNO_QUERY
);
287 xColumns
= Reference
<XIndexAccess
>(xColumnSup
->getColumns(),UNO_QUERY
);
288 if(!xColumns
.is() || !xColumns
->getCount())
289 ::dbtools::throwFunctionSequenceException(_xConnection
);
291 const ::rtl::OUString sQuote
= xMetaData
->getIdentifierQuoteString();
292 aSql
.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" PRIMARY KEY ")));
293 aSql
.append(generateColumnNames(xColumns
,xMetaData
));
295 else if(nKeyType
== KeyType::UNIQUE
)
297 xColumnSup
= Reference
<XColumnsSupplier
>(xColProp
,UNO_QUERY
);
298 xColumns
= Reference
<XIndexAccess
>(xColumnSup
->getColumns(),UNO_QUERY
);
299 if(!xColumns
.is() || !xColumns
->getCount())
300 ::dbtools::throwFunctionSequenceException(_xConnection
);
302 const ::rtl::OUString sQuote
= xMetaData
->getIdentifierQuoteString();
303 aSql
.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" UNIQUE ")));
304 aSql
.append(generateColumnNames(xColumns
,xMetaData
));
306 else if(nKeyType
== KeyType::FOREIGN
)
308 sal_Int32 nDeleteRule
= getINT32(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_DELETERULE
)));
310 xColumnSup
= Reference
<XColumnsSupplier
>(xColProp
,UNO_QUERY
);
311 xColumns
= Reference
<XIndexAccess
>(xColumnSup
->getColumns(),UNO_QUERY
);
312 if(!xColumns
.is() || !xColumns
->getCount())
313 ::dbtools::throwFunctionSequenceException(_xConnection
);
315 aSql
.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FOREIGN KEY ")));
316 ::rtl::OUString sRefTable
= getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_REFERENCEDTABLE
)));
317 ::dbtools::qualifiedNameComponents(xMetaData
,
322 ::dbtools::eInDataManipulation
);
323 sComposedName
= ::dbtools::composeTableName( xMetaData
, sCatalog
, sSchema
, sTable
, sal_True
, ::dbtools::eInTableDefinitions
);
326 if ( sComposedName
.isEmpty() )
327 ::dbtools::throwFunctionSequenceException(_xConnection
);
329 aSql
.append(generateColumnNames(xColumns
,xMetaData
));
333 case KeyRule::CASCADE
:
334 aSql
.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ON DELETE CASCADE ")));
336 case KeyRule::RESTRICT
:
337 aSql
.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ON DELETE RESTRICT ")));
339 case KeyRule::SET_NULL
:
340 aSql
.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ON DELETE SET NULL ")));
342 case KeyRule::SET_DEFAULT
:
343 aSql
.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ON DELETE SET DEFAULT ")));
353 if ( aSql
.getLength() )
355 if ( aSql
[aSql
.getLength() - 1] == ',' )
356 aSql
[aSql
.getLength() - 1] = ')';
358 aSql
.appendAscii(")");
361 return aSql
.makeStringAndClear();
364 // -----------------------------------------------------------------------------
365 ::rtl::OUString
createSqlCreateTableStatement( const Reference
< XPropertySet
>& descriptor
,
366 const Reference
< XConnection
>& _xConnection
,
367 ISQLStatementHelper
* _pHelper
,
368 const ::rtl::OUString
& _sCreatePattern
)
370 ::rtl::OUString aSql
= ::dbtools::createStandardCreateStatement(descriptor
,_xConnection
,_pHelper
,_sCreatePattern
);
371 const ::rtl::OUString sKeyStmt
= ::dbtools::createStandardKeyStatement(descriptor
,_xConnection
);
372 if ( !sKeyStmt
.isEmpty() )
376 if ( aSql
.lastIndexOf(',') == (aSql
.getLength()-1) )
377 aSql
= aSql
.replaceAt(aSql
.getLength()-1,1,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")")));
379 aSql
+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
385 Reference
<XPropertySet
> lcl_createSDBCXColumn(const Reference
<XNameAccess
>& _xPrimaryKeyColumns
,
386 const Reference
<XConnection
>& _xConnection
,
387 const Any
& _aCatalog
,
388 const ::rtl::OUString
& _aSchema
,
389 const ::rtl::OUString
& _aTable
,
390 const ::rtl::OUString
& _rQueryName
,
391 const ::rtl::OUString
& _rName
,
393 sal_Bool _bQueryForInfo
,
394 sal_Bool _bIsAutoIncrement
,
395 sal_Bool _bIsCurrency
,
396 sal_Int32 _nDataType
)
398 Reference
<XPropertySet
> xProp
;
399 Reference
<XDatabaseMetaData
> xMetaData
= _xConnection
->getMetaData();
400 Reference
< XResultSet
> xResult
= xMetaData
->getColumns(_aCatalog
, _aSchema
, _aTable
, _rQueryName
);
404 UStringMixEqual
aMixCompare(_bCase
);
405 Reference
< XRow
> xRow(xResult
,UNO_QUERY
);
406 while( xResult
->next() )
408 if ( aMixCompare(xRow
->getString(4),_rName
) )
410 sal_Int32 nField5
= xRow
->getInt(5);
411 ::rtl::OUString aField6
= xRow
->getString(6);
412 sal_Int32 nField7
= xRow
->getInt(7)
413 , nField9
= xRow
->getInt(9)
414 , nField11
= xRow
->getInt(11);
415 ::rtl::OUString sField12
= xRow
->getString(12),
416 sField13
= xRow
->getString(13);
417 ::comphelper::disposeComponent(xRow
);
419 sal_Bool bAutoIncrement
= _bIsAutoIncrement
420 ,bIsCurrency
= _bIsCurrency
;
421 if ( _bQueryForInfo
)
423 const ::rtl::OUString sQuote
= xMetaData
->getIdentifierQuoteString();
424 ::rtl::OUString sQuotedName
= ::dbtools::quoteName(sQuote
,_rName
);
425 ::rtl::OUString sComposedName
;
426 sComposedName
= composeTableNameForSelect(_xConnection
, getString( _aCatalog
), _aSchema
, _aTable
);
428 ColumnInformationMap
aInfo(_bCase
);
429 collectColumnInformation(_xConnection
,sComposedName
,sQuotedName
,aInfo
);
430 ColumnInformationMap::iterator aIter
= aInfo
.begin();
431 if ( aIter
!= aInfo
.end() )
433 bAutoIncrement
= aIter
->second
.first
.first
;
434 bIsCurrency
= aIter
->second
.first
.second
;
435 if ( DataType::OTHER
== nField5
)
436 nField5
= aIter
->second
.second
;
439 else if ( DataType::OTHER
== nField5
)
440 nField5
= _nDataType
;
442 if ( nField11
!= ColumnValue::NO_NULLS
)
446 if ( _xPrimaryKeyColumns
.is() )
448 if ( _xPrimaryKeyColumns
->hasByName(_rName
) )
449 nField11
= ColumnValue::NO_NULLS
;
454 Reference
< XResultSet
> xPKeys
= xMetaData
->getPrimaryKeys( _aCatalog
, _aSchema
, _aTable
);
455 Reference
< XRow
> xPKeyRow( xPKeys
, UNO_QUERY_THROW
);
456 while( xPKeys
->next() ) // there can be only one primary key
458 ::rtl::OUString sKeyColumn
= xPKeyRow
->getString(4);
459 if ( aMixCompare(_rName
,sKeyColumn
) )
461 nField11
= ColumnValue::NO_NULLS
;
469 OSL_FAIL( "lcl_createSDBCXColumn: caught an exception!" );
473 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
<XNameAccess
> xPrimaryKeyColumns
= getPrimaryKeyColumns_throw(_xTable
);
534 xProp
= lcl_createSDBCXColumn(xPrimaryKeyColumns
,_xConnection
,aCatalog
, aSchema
, aTable
, _rName
,_rName
,_bCase
,_bQueryForInfo
,_bIsAutoIncrement
,_bIsCurrency
,_nDataType
);
537 xProp
= lcl_createSDBCXColumn(xPrimaryKeyColumns
,_xConnection
,aCatalog
, aSchema
, aTable
, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("%")),_rName
,_bCase
,_bQueryForInfo
,_bIsAutoIncrement
,_bIsCurrency
,_nDataType
);
539 xProp
= new connectivity::sdbcx::OColumn(_rName
,
540 ::rtl::OUString(),::rtl::OUString(),::rtl::OUString(),
541 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( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Settings") ) ),
569 OSL_VERIFY( xSettings
->getPropertyValue( ::rtl::OUString::createFromAscii( _pAsciiSettingName
) ) >>= bValue
);
572 catch( const Exception
& )
574 DBG_UNHANDLED_EXCEPTION();
578 // -------------------------------------------------------------------------
579 bool getDataSourceSetting( const Reference
< XInterface
>& _xChild
, const ::rtl::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( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "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 ::rtl::OUString sAsciiSettingsName
= ::rtl::OUString::createFromAscii(_pAsciiSettingsName
);
608 return getDataSourceSetting( _rxDataSource
, sAsciiSettingsName
,_rSettingsValue
);
610 // -----------------------------------------------------------------------------
611 sal_Bool
isDataSourcePropertyEnabled(const Reference
<XInterface
>& _xProp
,const ::rtl::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(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("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 ::rtl::OUString
& _rsUrl
,
637 const Reference
< XConnection
>& _xConnection
,
638 const Reference
< XMultiServiceFactory
>& _rxFactory
)
640 Reference
< XTablesSupplier
> xTablesSup
;
643 Reference
< XDriverAccess
> xManager(
644 _rxFactory
->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdbc.DriverManager")) ),
646 Reference
< XDataDefinitionSupplier
> xSupp( xManager
->getDriverByURL( _rsUrl
), UNO_QUERY
);
650 xTablesSup
= xSupp
->getDataDefinitionByConnection( _xConnection
);
651 OSL_ENSURE(xTablesSup
.is(),"No table supplier!");
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
.isEmpty())
674 Reference
< XResultSet
> xPrivileges
= _xMetaData
->getTablePrivileges(aVal
, _sSchema
, _sTable
);
675 Reference
< XRow
> xCurrentRow(xPrivileges
, UNO_QUERY
);
677 const ::rtl::OUString sUserWorkingFor
= _xMetaData
->getUserName();
678 static const ::rtl::OUString
sSELECT( RTL_CONSTASCII_USTRINGPARAM( "SELECT" ));
679 static const ::rtl::OUString
sINSERT( RTL_CONSTASCII_USTRINGPARAM( "INSERT" ));
680 static const ::rtl::OUString
sUPDATE( RTL_CONSTASCII_USTRINGPARAM( "UPDATE" ));
681 static const ::rtl::OUString
sDELETE( RTL_CONSTASCII_USTRINGPARAM( "DELETE" ));
682 static const ::rtl::OUString
sREAD( RTL_CONSTASCII_USTRINGPARAM( "READ" ));
683 static const ::rtl::OUString
sCREATE( RTL_CONSTASCII_USTRINGPARAM( "CREATE" ));
684 static const ::rtl::OUString
sALTER( RTL_CONSTASCII_USTRINGPARAM( "ALTER" ));
685 static const ::rtl::OUString
sREFERENCE( RTL_CONSTASCII_USTRINGPARAM( "REFERENCE" ));
686 static const ::rtl::OUString
sDROP( RTL_CONSTASCII_USTRINGPARAM( "DROP" ));
688 if ( xCurrentRow
.is() )
690 // after creation the set is positioned before the first record, per definition
692 Reference
< XResultSetMetaDataSupplier
> xSup(xPrivileges
,UNO_QUERY
);
695 Reference
< XResultSetMetaData
> xRsMetaData
= xSup
->getMetaData();
696 if ( xRsMetaData
.is() )
698 sal_Int32 nCount
= xRsMetaData
->getColumnCount();
699 for (sal_Int32 i
=1; i
<=nCount
; ++i
)
701 ::rtl::OUString sColumnName
= xRsMetaData
->getColumnName(i
);
707 ::rtl::OUString sPrivilege
, sGrantee
;
708 while ( xPrivileges
->next() )
711 ::rtl::OUString sCat
, sSchema
, sName
, sGrantor
, sGrantable
;
712 sCat
= xCurrentRow
->getString(1);
713 sSchema
= xCurrentRow
->getString(2);
714 sName
= xCurrentRow
->getString(3);
715 sGrantor
= xCurrentRow
->getString(4);
717 sGrantee
= xCurrentRow
->getString(5);
718 sPrivilege
= xCurrentRow
->getString(6);
720 sGrantable
= xCurrentRow
->getString(7);
723 if (!sUserWorkingFor
.equalsIgnoreAsciiCase(sGrantee
))
726 if (sPrivilege
.equalsIgnoreAsciiCase(sSELECT
))
727 nPrivileges
|= Privilege::SELECT
;
728 else if (sPrivilege
.equalsIgnoreAsciiCase(sINSERT
))
729 nPrivileges
|= Privilege::INSERT
;
730 else if (sPrivilege
.equalsIgnoreAsciiCase(sUPDATE
))
731 nPrivileges
|= Privilege::UPDATE
;
732 else if (sPrivilege
.equalsIgnoreAsciiCase(sDELETE
))
733 nPrivileges
|= Privilege::DELETE
;
734 else if (sPrivilege
.equalsIgnoreAsciiCase(sREAD
))
735 nPrivileges
|= Privilege::READ
;
736 else if (sPrivilege
.equalsIgnoreAsciiCase(sCREATE
))
737 nPrivileges
|= Privilege::CREATE
;
738 else if (sPrivilege
.equalsIgnoreAsciiCase(sALTER
))
739 nPrivileges
|= Privilege::ALTER
;
740 else if (sPrivilege
.equalsIgnoreAsciiCase(sREFERENCE
))
741 nPrivileges
|= Privilege::REFERENCE
;
742 else if (sPrivilege
.equalsIgnoreAsciiCase(sDROP
))
743 nPrivileges
|= Privilege::DROP
;
746 disposeComponent(xPrivileges
);
748 // Some drivers put a table privilege as soon as any column has the privilege,
749 // some drivers only if all columns have the privilege.
750 // To unifiy the situation, collect column privileges here, too.
751 Reference
< XResultSet
> xColumnPrivileges
= _xMetaData
->getColumnPrivileges(aVal
, _sSchema
, _sTable
, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("%")));
752 Reference
< XRow
> xColumnCurrentRow(xColumnPrivileges
, UNO_QUERY
);
753 if ( xColumnCurrentRow
.is() )
755 // after creation the set is positioned before the first record, per definition
756 ::rtl::OUString sPrivilege
, sGrantee
;
757 while ( xColumnPrivileges
->next() )
760 ::rtl::OUString sCat
, sSchema
, sTableName
, sColumnName
, sGrantor
, sGrantable
;
761 sCat
= xColumnCurrentRow
->getString(1);
762 sSchema
= xColumnCurrentRow
->getString(2);
763 sTableName
= xColumnCurrentRow
->getString(3);
764 sColumnName
= xColumnCurrentRow
->getString(4);
765 sGrantor
= xColumnCurrentRow
->getString(5);
767 sGrantee
= xColumnCurrentRow
->getString(6);
768 sPrivilege
= xColumnCurrentRow
->getString(7);
770 sGrantable
= xColumnCurrentRow
->getString(8);
773 if (!sUserWorkingFor
.equalsIgnoreAsciiCase(sGrantee
))
776 if (sPrivilege
.equalsIgnoreAsciiCase(sSELECT
))
777 nPrivileges
|= Privilege::SELECT
;
778 else if (sPrivilege
.equalsIgnoreAsciiCase(sINSERT
))
779 nPrivileges
|= Privilege::INSERT
;
780 else if (sPrivilege
.equalsIgnoreAsciiCase(sUPDATE
))
781 nPrivileges
|= Privilege::UPDATE
;
782 else if (sPrivilege
.equalsIgnoreAsciiCase(sDELETE
))
783 nPrivileges
|= Privilege::DELETE
;
784 else if (sPrivilege
.equalsIgnoreAsciiCase(sREAD
))
785 nPrivileges
|= Privilege::READ
;
786 else if (sPrivilege
.equalsIgnoreAsciiCase(sCREATE
))
787 nPrivileges
|= Privilege::CREATE
;
788 else if (sPrivilege
.equalsIgnoreAsciiCase(sALTER
))
789 nPrivileges
|= Privilege::ALTER
;
790 else if (sPrivilege
.equalsIgnoreAsciiCase(sREFERENCE
))
791 nPrivileges
|= Privilege::REFERENCE
;
792 else if (sPrivilege
.equalsIgnoreAsciiCase(sDROP
))
793 nPrivileges
|= Privilege::DROP
;
796 disposeComponent(xColumnPrivileges
);
798 catch(const SQLException
& e
)
800 static ::rtl::OUString
sNotSupportedState( RTL_CONSTASCII_USTRINGPARAM( "IM001" ));
801 // some drivers don't support any privileges so we assume that we are allowed to do all we want :-)
802 if(e
.SQLState
== sNotSupportedState
)
803 nPrivileges
|= Privilege::DROP
|
804 Privilege::REFERENCE
|
813 OSL_FAIL("Could not collect the privileges !");
817 // -----------------------------------------------------------------------------
818 // we need some more information about the column
819 void collectColumnInformation(const Reference
< XConnection
>& _xConnection
,
820 const ::rtl::OUString
& _sComposedName
,
821 const ::rtl::OUString
& _rName
,
822 ColumnInformationMap
& _rInfo
)
824 static ::rtl::OUString STR_WHERE
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" WHERE "));
826 ::rtl::OUString sSelect
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT "));
828 sSelect
+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM "));
829 sSelect
+= _sComposedName
;
830 sSelect
+= STR_WHERE
;
831 sSelect
+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0 = 1"));
835 ::utl::SharedUNOComponent
< XStatement
> xStmt( _xConnection
->createStatement() );
836 Reference
< XPropertySet
> xStatementProps( xStmt
, UNO_QUERY_THROW
);
837 xStatementProps
->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_ESCAPEPROCESSING
), makeAny( (sal_Bool
)sal_False
) );
838 Reference
< XResultSet
> xResult( xStmt
->executeQuery( sSelect
), UNO_QUERY_THROW
);
839 Reference
< XResultSetMetaDataSupplier
> xSuppMeta( xResult
, UNO_QUERY_THROW
);
840 Reference
< XResultSetMetaData
> xMeta( xSuppMeta
->getMetaData(), UNO_QUERY_THROW
);
842 sal_Int32 nCount
= xMeta
->getColumnCount();
843 OSL_ENSURE( nCount
!= 0, "::dbtools::collectColumnInformation: result set has empty (column-less) meta data!" );
844 for (sal_Int32 i
=1; i
<= nCount
; ++i
)
846 _rInfo
.insert(ColumnInformationMap::value_type(xMeta
->getColumnName(i
),
847 ColumnInformation(TBoolPair(xMeta
->isAutoIncrement(i
),xMeta
->isCurrency(i
)),xMeta
->getColumnType(i
))));
850 catch( const Exception
& )
852 DBG_UNHANDLED_EXCEPTION();
856 // -----------------------------------------------------------------------------
857 bool isEmbeddedInDatabase( const Reference
< XInterface
>& _rxComponent
, Reference
< XConnection
>& _rxActualConnection
)
859 bool bIsEmbedded
= false;
862 Reference
< XModel
> xModel
= lcl_getXModel( _rxComponent
);
866 Sequence
< PropertyValue
> aArgs
= xModel
->getArgs();
867 const PropertyValue
* pIter
= aArgs
.getConstArray();
868 const PropertyValue
* pEnd
= pIter
+ aArgs
.getLength();
869 for(;pIter
!= pEnd
;++pIter
)
871 if ( pIter
->Name
== "ComponentData" )
873 Sequence
<PropertyValue
> aDocumentContext
;
874 pIter
->Value
>>= aDocumentContext
;
875 const PropertyValue
* pContextIter
= aDocumentContext
.getConstArray();
876 const PropertyValue
* pContextEnd
= pContextIter
+ aDocumentContext
.getLength();
877 for(;pContextIter
!= pContextEnd
;++pContextIter
)
879 if ( pContextIter
->Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ActiveConnection" ) )
880 && ( pContextIter
->Value
>>= _rxActualConnection
)
894 // not intereseted in
898 // -----------------------------------------------------------------------------
901 ::rtl::OUString
lcl_getEncodingName( rtl_TextEncoding _eEncoding
)
903 ::rtl::OUString sEncodingName
;
905 OCharsetMap aCharsets
;
906 OCharsetMap::CharsetIterator aEncodingPos
= aCharsets
.find( _eEncoding
);
907 OSL_ENSURE( aEncodingPos
!= aCharsets
.end(), "lcl_getEncodingName: *which* encoding?" );
908 if ( aEncodingPos
!= aCharsets
.end() )
909 sEncodingName
= (*aEncodingPos
).getIanaName();
911 return sEncodingName
;
915 // -----------------------------------------------------------------------------
916 sal_Int32
DBTypeConversion::convertUnicodeString( const ::rtl::OUString
& _rSource
, ::rtl::OString
& _rDest
, rtl_TextEncoding _eEncoding
) SAL_THROW((com::sun::star::sdbc::SQLException
))
918 if ( !rtl_convertUStringToString( &_rDest
.pData
, _rSource
.getStr(), _rSource
.getLength(),
920 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
|
921 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE
|
922 RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0
|
923 RTL_UNICODETOTEXT_FLAGS_NOCOMPOSITE
)
926 SharedResources aResources
;
927 ::rtl::OUString sMessage
= aResources
.getResourceStringWithSubstitution( STR_CANNOT_CONVERT_STRING
,
928 "$string$", _rSource
,
929 "$charset$", lcl_getEncodingName( _eEncoding
)
935 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "22018" ) ),
941 return _rDest
.getLength();
944 // -----------------------------------------------------------------------------
945 sal_Int32
DBTypeConversion::convertUnicodeStringToLength( const ::rtl::OUString
& _rSource
, ::rtl::OString
& _rDest
,
946 sal_Int32 _nMaxLen
, rtl_TextEncoding _eEncoding
) SAL_THROW((SQLException
))
948 sal_Int32 nLen
= convertUnicodeString( _rSource
, _rDest
, _eEncoding
);
949 if ( nLen
> _nMaxLen
)
951 SharedResources aResources
;
952 ::rtl::OUString sMessage
= aResources
.getResourceStringWithSubstitution( STR_STRING_LENGTH_EXCEEDED
,
953 "$string$", _rSource
,
954 "$maxlen$", ::rtl::OUString::valueOf( _nMaxLen
),
955 "$charset$", lcl_getEncodingName( _eEncoding
)
961 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "22001" ) ),
969 ::rtl::OUString
lcl_getReportEngines()
971 static ::rtl::OUString
s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.DataAccess/ReportEngines"));
974 // -----------------------------------------------------------------------------
975 ::rtl::OUString
lcl_getDefaultReportEngine()
977 static ::rtl::OUString
s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("DefaultReportEngine"));
980 // -----------------------------------------------------------------------------
981 ::rtl::OUString
lcl_getReportEngineNames()
983 static ::rtl::OUString
s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("ReportEngineNames"));
986 // -----------------------------------------------------------------------------
987 ::rtl::OUString
getDefaultReportEngineServiceName(const Reference
< XMultiServiceFactory
>& _rxORB
)
989 ::utl::OConfigurationTreeRoot aReportEngines
= ::utl::OConfigurationTreeRoot::createWithServiceFactory(
990 _rxORB
, lcl_getReportEngines(), -1, ::utl::OConfigurationTreeRoot::CM_READONLY
);
992 if ( aReportEngines
.isValid() )
994 ::rtl::OUString sDefaultReportEngineName
;
995 aReportEngines
.getNodeValue(lcl_getDefaultReportEngine()) >>= sDefaultReportEngineName
;
996 if ( !sDefaultReportEngineName
.isEmpty() )
998 ::utl::OConfigurationNode aReportEngineNames
= aReportEngines
.openNode(lcl_getReportEngineNames());
999 if ( aReportEngineNames
.isValid() )
1001 ::utl::OConfigurationNode aReportEngine
= aReportEngineNames
.openNode(sDefaultReportEngineName
);
1002 if ( aReportEngine
.isValid() )
1004 ::rtl::OUString sRet
;
1005 const static ::rtl::OUString
s_sService(RTL_CONSTASCII_USTRINGPARAM("ServiceName"));
1006 aReportEngine
.getNodeValue(s_sService
) >>= sRet
;
1012 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.report.pentaho.SOReportJobFactory"));
1015 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.report.pentaho.SOReportJobFactory"));
1016 return ::rtl::OUString();
1018 // -----------------------------------------------------------------------------
1019 //.........................................................................
1020 } // namespace dbtools
1021 //.........................................................................
1023 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */