27#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
28#include <com/sun/star/sdbc/SQLException.hpp>
29#include <com/sun/star/sdbc/XConnection.hpp>
30#include <com/sun/star/sdbc/XDataSource.hpp>
31#include <com/sun/star/sdbc/ColumnValue.hpp>
32#include <com/sun/star/sdbc/DataType.hpp>
33#include <com/sun/star/sdbc/DriverManager.hpp>
34#include <com/sun/star/sdbc/XRow.hpp>
35#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
36#include <com/sun/star/sdbcx/XKeysSupplier.hpp>
37#include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
38#include <com/sun/star/sdbcx/Privilege.hpp>
39#include <com/sun/star/container/XIndexAccess.hpp>
40#include <com/sun/star/sdbc/KeyRule.hpp>
41#include <com/sun/star/sdbcx/KeyType.hpp>
44#include <com/sun/star/frame/XModel.hpp>
45#include <com/sun/star/container/XChild.hpp>
67OUString
createStandardTypePart(
const Reference< XPropertySet >& xColProp,
const Reference< XConnection>& _xConnection,std::u16string_view _sCreatePattern)
70 Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData();
76 sal_Int32 nPrecision = 0;
89 OUString sAutoIncrementValue;
90 Reference<XPropertySetInfo> xPropInfo = xColProp->getPropertySetInfo();
94 bool bUseLiteral =
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);
106 sPostfix = xRow->getString (5);
107 sCreateParams = xRow->getString(6);
110 sTypeName = sTypeName2Cmp;
112 if( sTypeName.equalsIgnoreAsciiCase(sTypeName2Cmp) &&
nType ==
nDataType && !sCreateParams.isEmpty() && !xRow->wasNull())
121 if ( !sAutoIncrementValue.isEmpty() )
123 sal_Int32
nIndex = sTypeName.indexOf(sAutoIncrementValue);
125 sTypeName = sTypeName.replaceAt(
nIndex,sTypeName.getLength() -
nIndex,
u"");
128 if ( (nPrecision > 0 || nScale > 0) && bUseLiteral )
130 sal_Int32 nParenPos = sTypeName.indexOf(
'(');
131 if ( nParenPos == -1 )
133 aSql.append(sTypeName +
"(");
137 aSql.append(sTypeName.subView(0, ++nParenPos));
140 if ( nPrecision > 0 &&
nDataType != DataType::TIMESTAMP )
142 aSql.append(nPrecision);
143 if ( (nScale > 0) || (!_sCreatePattern.empty() && sCreateParams.indexOf(_sCreatePattern) != -1) )
146 if ( (nScale > 0) || ( !_sCreatePattern.empty() && sCreateParams.indexOf(_sCreatePattern) != -1 ) ||
nDataType == DataType::TIMESTAMP )
149 if ( nParenPos == -1 )
153 nParenPos = sTypeName.indexOf(
')',nParenPos);
154 aSql.append(sTypeName.subView(nParenPos));
158 aSql.append(sTypeName);
161 if ( !aDefault.isEmpty() )
163 aSql.append(
" DEFAULT " +
sPrefix + aDefault + sPostfix);
166 return aSql.makeStringAndClear();
171 Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData();
175 bool bIsAutoIncrement =
false;
178 const OUString sQuoteString = xMetaData->getIdentifierQuoteString();
182 OUString sAutoIncrementValue;
183 Reference<XPropertySetInfo> xPropInfo = xColProp->getPropertySetInfo();
190 aSql.append(
" NOT NULL");
192 if ( bIsAutoIncrement && !sAutoIncrementValue.isEmpty())
194 aSql.append(
" " + sAutoIncrementValue);
200 return aSql.makeStringAndClear();
206 OUStringBuffer aSql(
"CREATE TABLE ");
209 Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData();
223 Reference<XColumnsSupplier> xColumnSup(descriptor,UNO_QUERY);
224 Reference<XIndexAccess> xColumns(xColumnSup->getColumns(),UNO_QUERY);
226 if(!xColumns.is() || !xColumns->getCount())
229 Reference< XPropertySet > xColProp;
231 sal_Int32
nCount = xColumns->getCount();
234 if ( (xColumns->getByIndex(
i) >>= xColProp) && xColProp.is() )
241 return aSql.makeStringAndClear();
245 OUString generateColumnNames(
const Reference<XIndexAccess>& _xColumns,
const Reference<XDatabaseMetaData>& _xMetaData)
249 const OUString
sQuote(_xMetaData->getIdentifierQuoteString());
250 OUStringBuffer sSql(
" (" );
251 Reference< XPropertySet > xColProp;
253 sal_Int32 nColCount = _xColumns->getCount();
254 for(sal_Int32 i=0;
i<nColCount;++
i)
256 if ( (_xColumns->getByIndex(i) >>= xColProp) && xColProp.is() )
262 sSql[sSql.getLength()-1] =
')';
263 return sSql.makeStringAndClear();
269 Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData();
274 Reference<XKeysSupplier> xKeySup(descriptor,UNO_QUERY);
275 Reference<XIndexAccess> xKeys = xKeySup->getKeys();
278 Reference< XPropertySet > xColProp;
279 Reference<XIndexAccess> xColumns;
280 Reference<XColumnsSupplier> xColumnSup;
283 for(sal_Int32
i=0;
i<xKeys->getCount();++
i)
285 if ( (xKeys->getByIndex(
i) >>= xColProp) && xColProp.is() )
290 if ( nKeyType == KeyType::PRIMARY )
296 xColumnSup.set(xColProp,UNO_QUERY);
297 xColumns.set(xColumnSup->getColumns(),UNO_QUERY);
298 if(!xColumns.is() || !xColumns->getCount())
301 aSql.append(
" PRIMARY KEY " + generateColumnNames(xColumns,xMetaData));
303 else if(nKeyType == KeyType::UNIQUE)
305 xColumnSup.set(xColProp,UNO_QUERY);
306 xColumns.set(xColumnSup->getColumns(),UNO_QUERY);
307 if(!xColumns.is() || !xColumns->getCount())
310 aSql.append(
" UNIQUE " + generateColumnNames(xColumns,xMetaData));
312 else if(nKeyType == KeyType::FOREIGN)
316 xColumnSup.set(xColProp,UNO_QUERY);
317 xColumns.set(xColumnSup->getColumns(),UNO_QUERY);
318 if(!xColumns.is() || !xColumns->getCount())
321 aSql.append(
" FOREIGN KEY ");
328 ::dbtools::EComposeRule::InDataManipulation);
335 aSql.append(generateColumnNames(xColumns,xMetaData));
339 case KeyRule::CASCADE:
340 aSql.append(
" ON DELETE CASCADE ");
342 case KeyRule::RESTRICT:
343 aSql.append(
" ON DELETE RESTRICT ");
345 case KeyRule::SET_NULL:
346 aSql.append(
" ON DELETE SET NULL ");
348 case KeyRule::SET_DEFAULT:
349 aSql.append(
" ON DELETE SET DEFAULT ");
359 if ( !aSql.isEmpty() )
361 if ( aSql[aSql.getLength() - 1] ==
',' )
362 aSql[aSql.getLength() - 1] =
')';
367 return aSql.makeStringAndClear();
372 const Reference< XConnection>& _xConnection)
376 if ( !sKeyStmt.isEmpty() )
380 if ( aSql.endsWith(
",") )
381 aSql = aSql.replaceAt(aSql.getLength()-1, 1,
u")");
389 Reference<XPropertySet> lcl_createSDBCXColumn(
const Reference<XNameAccess>& _xPrimaryKeyColumns,
390 const Reference<XConnection>& _xConnection,
391 const Any& _aCatalog,
392 const OUString& _aSchema,
393 const OUString& _aTable,
394 const OUString& _rQueryName,
395 const OUString& _rName,
398 bool _bIsAutoIncrement,
400 sal_Int32 _nDataType)
402 Reference<XPropertySet> xProp;
403 Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData();
404 Reference< XResultSet > xResult = xMetaData->getColumns(_aCatalog, _aSchema, _aTable, _rQueryName);
411 Reference< XRow > xRow(xResult,UNO_QUERY);
412 while( xResult->next() )
414 if ( aMixCompare(xRow->getString(4),_rName) )
416 sal_Int32 nField5 = xRow->getInt(5);
417 OUString aField6 = xRow->getString(6);
418 sal_Int32 nField7 = xRow->getInt(7)
419 , nField9 = xRow->getInt(9)
420 , nField11= xRow->getInt(11);
421 OUString sField12 = xRow->getString(12),
422 sField13 = xRow->getString(13);
423 ::comphelper::disposeComponent(xRow);
426 ,bIsCurrency = _bIsCurrency;
427 if ( _bQueryForInfo )
429 const OUString
sQuote = xMetaData->getIdentifierQuoteString();
435 ColumnInformationMap::const_iterator aIter = aInfo.begin();
436 if ( aIter != aInfo.end() )
439 bIsCurrency = aIter->second.first.second;
440 if ( DataType::OTHER == nField5 )
441 nField5 = aIter->second.second;
444 else if ( DataType::OTHER == nField5 )
445 nField5 = _nDataType;
447 if ( nField11 != ColumnValue::NO_NULLS )
451 if ( _xPrimaryKeyColumns.is() )
453 if ( _xPrimaryKeyColumns->hasByName(_rName) )
454 nField11 = ColumnValue::NO_NULLS;
459 Reference< XResultSet > xPKeys = xMetaData->getPrimaryKeys( _aCatalog, _aSchema, _aTable );
460 Reference< XRow > xPKeyRow( xPKeys, UNO_QUERY_THROW );
461 while( xPKeys->next() )
463 OUString sKeyColumn = xPKeyRow->getString(4);
464 if ( aMixCompare(_rName,sKeyColumn) )
466 nField11 = ColumnValue::NO_NULLS;
502 Reference< XModel> lcl_getXModel(
const Reference< XInterface>& _xIface)
504 Reference< XInterface > xParent = _xIface;
505 Reference< XModel >
xModel(xParent,UNO_QUERY);
506 while( xParent.is() && !
xModel.is() )
508 Reference<XChild> xChild(xParent,UNO_QUERY);
509 xParent.set(xChild.is() ? xChild->getParent() : Reference< XInterface >(),UNO_QUERY);
510 xModel.set(xParent,UNO_QUERY);
517 const Reference<XConnection>& _xConnection,
518 const OUString& _rName,
521 bool _bIsAutoIncrement,
523 sal_Int32 _nDataType)
525 Reference<XPropertySet> xProp;
526 OSL_ENSURE(_xTable.is(),
"Table is NULL!");
535 OUString aSchema, aTable;
541 xProp = lcl_createSDBCXColumn(xPrimaryKeyColumns,_xConnection,aCatalog, aSchema, aTable, _rName,_rName,_bCase,_bQueryForInfo,_bIsAutoIncrement,_bIsCurrency,_nDataType);
544 xProp = lcl_createSDBCXColumn(xPrimaryKeyColumns,_xConnection,aCatalog, aSchema, aTable,
"%",_rName,_bCase,_bQueryForInfo,_bIsAutoIncrement,_bIsCurrency,_nDataType);
547 OUString(),OUString(),OUString(),
548 ColumnValue::NULLABLE_UNKNOWN,
573 bool bValue(
false );
576 Reference< XPropertySet> xDataSourceProperties(
findDataSource( _rxConnection ), UNO_QUERY );
577 OSL_ENSURE( xDataSourceProperties.is(),
"::dbtools::getBooleanDataSourceSetting: somebody is using this with a non-SDB-level connection!" );
578 if ( xDataSourceProperties.is() )
580 Reference< XPropertySet > xSettings(
581 xDataSourceProperties->getPropertyValue(
"Settings"),
584 OSL_VERIFY( xSettings->getPropertyValue( rSettingName ) >>= bValue );
595 Any& _rSettingsValue )
597 bool bIsPresent =
false;
600 const Reference< XPropertySet> xDataSourceProperties(
findDataSource( _xChild ), UNO_QUERY );
601 if ( !xDataSourceProperties.is() )
604 const Reference< XPropertySet > xSettings(
605 xDataSourceProperties->getPropertyValue(
"Settings"),
609 _rSettingsValue = xSettings->getPropertyValue( _sAsciiSettingsName );
620 Any& _rSettingsValue )
622 OUString sAsciiSettingsName = OUString::createFromAscii(_pAsciiSettingsName);
628 bool bEnabled = _bDefault;
634 Sequence< PropertyValue > aInfo;
635 xProp->getPropertyValue(
"Info") >>= aInfo;
636 const PropertyValue* pValue =std::find_if(std::cbegin(aInfo),
638 [&_sProperty](
const PropertyValue& lhs)
639 {
return lhs.Name == _sProperty; });
640 if ( pValue != std::cend(aInfo) )
641 pValue->Value >>= bEnabled;
652 const OUString& _rsUrl,
653 const Reference< XConnection>& _xConnection,
654 const Reference< XComponentContext >& _rxContext)
656 Reference< XTablesSupplier> xTablesSup;
659 Reference< XDriverManager2 > xManager = DriverManager::create( _rxContext );
660 Reference< XDataDefinitionSupplier > xSupp( xManager->getDriverByURL( _rsUrl ), UNO_QUERY );
664 xTablesSup = xSupp->getDataDefinitionByConnection( _xConnection );
665 OSL_ENSURE(xTablesSup.is(),
"No table supplier!");
677 const OUString& _sCatalog,
678 const OUString& _sSchema,
679 const OUString& _sTable)
681 OSL_ENSURE(_xMetaData.is(),
"Invalid metadata!");
682 sal_Int32 nPrivileges = 0;
686 if(!_sCatalog.isEmpty())
688 Reference< XResultSet > xPrivileges = _xMetaData->getTablePrivileges(aVal, _sSchema, _sTable);
689 Reference< XRow > xCurrentRow(xPrivileges, UNO_QUERY);
691 const OUString sUserWorkingFor = _xMetaData->getUserName();
692 static const char sSELECT[] =
"SELECT";
693 static const char sINSERT[] =
"INSERT";
694 static const char sUPDATE[] =
"UPDATE";
695 static const char sDELETE[] =
"DELETE";
696 static const char sREAD[] =
"READ";
697 static const char sCREATE[] =
"CREATE";
698 static const char sALTER[] =
"ALTER";
699 static const char sREFERENCE[] =
"REFERENCE";
700 static const char sDROP[] =
"DROP";
702 if ( xCurrentRow.is() )
705 OUString sPrivilege, sGrantee;
706 while ( xPrivileges->next() )
708 sGrantee = xCurrentRow->getString(5);
709 sPrivilege = xCurrentRow->getString(6);
711 if (!sUserWorkingFor.equalsIgnoreAsciiCase(sGrantee))
714 if (sPrivilege.equalsIgnoreAsciiCase(sSELECT))
715 nPrivileges |= Privilege::SELECT;
716 else if (sPrivilege.equalsIgnoreAsciiCase(sINSERT))
717 nPrivileges |= Privilege::INSERT;
718 else if (sPrivilege.equalsIgnoreAsciiCase(sUPDATE))
719 nPrivileges |= Privilege::UPDATE;
720 else if (sPrivilege.equalsIgnoreAsciiCase(sDELETE))
721 nPrivileges |= Privilege::DELETE;
722 else if (sPrivilege.equalsIgnoreAsciiCase(sREAD))
723 nPrivileges |= Privilege::READ;
724 else if (sPrivilege.equalsIgnoreAsciiCase(sCREATE))
725 nPrivileges |= Privilege::CREATE;
726 else if (sPrivilege.equalsIgnoreAsciiCase(sALTER))
727 nPrivileges |= Privilege::ALTER;
728 else if (sPrivilege.equalsIgnoreAsciiCase(sREFERENCE))
729 nPrivileges |= Privilege::REFERENCE;
730 else if (sPrivilege.equalsIgnoreAsciiCase(sDROP))
731 nPrivileges |= Privilege::DROP;
739 Reference< XResultSet > xColumnPrivileges = _xMetaData->getColumnPrivileges(aVal, _sSchema, _sTable,
"%");
740 Reference< XRow > xColumnCurrentRow(xColumnPrivileges, UNO_QUERY);
741 if ( xColumnCurrentRow.is() )
744 OUString sPrivilege, sGrantee;
745 while ( xColumnPrivileges->next() )
747 sGrantee = xColumnCurrentRow->getString(6);
748 sPrivilege = xColumnCurrentRow->getString(7);
750 if (!sUserWorkingFor.equalsIgnoreAsciiCase(sGrantee))
753 if (sPrivilege.equalsIgnoreAsciiCase(sSELECT))
754 nPrivileges |= Privilege::SELECT;
755 else if (sPrivilege.equalsIgnoreAsciiCase(sINSERT))
756 nPrivileges |= Privilege::INSERT;
757 else if (sPrivilege.equalsIgnoreAsciiCase(sUPDATE))
758 nPrivileges |= Privilege::UPDATE;
759 else if (sPrivilege.equalsIgnoreAsciiCase(sDELETE))
760 nPrivileges |= Privilege::DELETE;
761 else if (sPrivilege.equalsIgnoreAsciiCase(sREAD))
762 nPrivileges |= Privilege::READ;
763 else if (sPrivilege.equalsIgnoreAsciiCase(sCREATE))
764 nPrivileges |= Privilege::CREATE;
765 else if (sPrivilege.equalsIgnoreAsciiCase(sALTER))
766 nPrivileges |= Privilege::ALTER;
767 else if (sPrivilege.equalsIgnoreAsciiCase(sREFERENCE))
768 nPrivileges |= Privilege::REFERENCE;
769 else if (sPrivilege.equalsIgnoreAsciiCase(sDROP))
770 nPrivileges |= Privilege::DROP;
775 catch(
const SQLException& e)
778 if(e.SQLState ==
"IM001")
779 nPrivileges |= Privilege::DROP |
780 Privilege::REFERENCE |
789 OSL_FAIL(
"Could not collect the privileges !");
796 std::u16string_view _sComposedName,
797 std::u16string_view _rName,
800 OUString sSelect = OUString::Concat(
"SELECT ") + _rName +
801 " FROM " + _sComposedName +
807 Reference< XPropertySet > xStatementProps( xStmt, UNO_QUERY_THROW );
809 Reference< XResultSet > xResult( xStmt->executeQuery( sSelect ), UNO_SET_THROW );
810 Reference< XResultSetMetaDataSupplier > xSuppMeta( xResult, UNO_QUERY_THROW );
811 Reference< XResultSetMetaData > xMeta( xSuppMeta->getMetaData(), UNO_SET_THROW );
813 sal_Int32
nCount = xMeta->getColumnCount();
814 OSL_ENSURE(
nCount != 0,
"::dbtools::collectColumnInformation: result set has empty (column-less) meta data!" );
817 _rInfo.emplace( xMeta->getColumnName(
i),
828bool isEmbeddedInDatabase(
const Reference< XInterface >& _rxComponent, Reference< XConnection >& _rxActualConnection )
830 bool bIsEmbedded =
false;
833 Reference< XModel >
xModel = lcl_getXModel( _rxComponent );
837 Sequence< PropertyValue > aArgs =
xModel->getArgs();
838 const PropertyValue* pIter = aArgs.getConstArray();
839 const PropertyValue* pEnd = pIter + aArgs.getLength();
840 for(;pIter != pEnd;++pIter)
842 if ( pIter->Name ==
"ComponentData" )
844 Sequence<PropertyValue> aDocumentContext;
845 pIter->Value >>= aDocumentContext;
846 const PropertyValue* pContextIter = aDocumentContext.getConstArray();
847 const PropertyValue* pContextEnd = pContextIter + aDocumentContext.getLength();
848 for(;pContextIter != pContextEnd;++pContextIter)
850 if ( pContextIter->Name ==
"ActiveConnection"
851 && ( pContextIter->Value >>= _rxActualConnection )
872 OUString lcl_getEncodingName( rtl_TextEncoding _eEncoding )
874 OUString sEncodingName;
878 OSL_ENSURE( aEncodingPos != aCharsets.
end(),
"lcl_getEncodingName: *which* encoding?" );
879 if ( aEncodingPos != aCharsets.
end() )
880 sEncodingName = (*aEncodingPos).getIanaName();
882 return sEncodingName;
889 if ( !rtl_convertUStringToString( &_rDest.pData, _rSource.getStr(), _rSource.getLength(),
891 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
892 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE |
893 RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 )
898 "$string$", _rSource,
899 "$charset$", lcl_getEncodingName( _eEncoding )
911 return _rDest.getLength();
916 sal_Int32 _nMaxLen, rtl_TextEncoding _eEncoding )
919 if ( nLen > _nMaxLen )
923 "$string$", _rSource,
924 "$maxlen$", OUString::number( _nMaxLen ),
925 "$charset$", lcl_getEncodingName( _eEncoding )
945 if ( aReportEngines.
isValid() )
947 OUString sDefaultReportEngineName;
948 aReportEngines.
getNodeValue(
"DefaultReportEngine") >>= sDefaultReportEngineName;
949 if ( !sDefaultReportEngineName.isEmpty() )
952 if ( aReportEngineNames.
isValid() )
964 return "org.libreoffice.report.pentaho.SOReportJobFactory";
967 return "org.libreoffice.report.pentaho.SOReportJobFactory";
971bool isAggregateColumn(
const Reference< XSingleSelectQueryComposer > &_xParser,
const Reference< XPropertySet > &_xField)
974 _xField->getPropertyValue(
"Name") >>=
sName;
975 Reference< XColumnsSupplier > xColumnsSupplier(_xParser, UNO_QUERY);
976 Reference< css::container::XNameAccess > xCols;
977 if (xColumnsSupplier.is())
978 xCols = xColumnsSupplier->getColumns();
985 if ( _xColumns.is() && _xColumns->hasByName(_sName) )
987 Reference<XPropertySet> xProp(_xColumns->getByName(_sName),UNO_QUERY);
998 static constexpr OUStringLiteral sAgg =
u"AggregateFunction";
999 if ( _xColumn->getPropertySetInfo()->hasPropertyByName(sAgg) )
1000 _xColumn->getPropertyValue(sAgg) >>= bAgg;
OptionalString sComposedName
helper class for accessing resources shared by different libraries in the connectivity module
OUString getResourceStringWithSubstitution(TranslateId pResId, const char *_pAsciiPatternToReplace, const OUString &_rStringToSubstitute) const
loads a string from the shared resource file, and replaces a given ASCII pattern with a given string
css::uno::Any getNodeValue(const OUString &_rPath) const noexcept
OConfigurationNode openNode(const OUString &_rPath) const noexcept
static OConfigurationTreeRoot createWithComponentContext(const css::uno::Reference< css::uno::XComponentContext > &_rxContext, const OUString &_rPath, sal_Int32 _nDepth=-1, CREATION_MODE _eMode=CM_UPDATABLE)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
void disposeComponent(css::uno::Reference< TYPE > &_rxComp)
sal_Int32 getINT32(const Any &_rAny)
OUString getString(const Any &_rAny)
#define PROPERTY_ID_REFERENCEDTABLE
#define PROPERTY_ID_AUTOINCREMENTCREATION
#define PROPERTY_ID_CATALOGNAME
#define PROPERTY_ID_ISNULLABLE
#define PROPERTY_ID_PRECISION
#define PROPERTY_ID_SCHEMANAME
#define PROPERTY_ID_ISAUTOINCREMENT
#define PROPERTY_ID_TYPENAME
#define PROPERTY_ID_DELETERULE
#define PROPERTY_ID_DEFAULTVALUE
#define PROPERTY_ID_ESCAPEPROCESSING
#define PROPERTY_ID_SCALE
Reference< XModel > xModel