Kaydet (Commit) 3fc48998 authored tarafından Ocke Janssen's avatar Ocke Janssen

change for insert , delete and update rows

üst d29d890f
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
* *
* $RCSfile: KeySet.cxx,v $ * $RCSfile: KeySet.cxx,v $
* *
* $Revision: 1.10 $ * $Revision: 1.11 $
* *
* last change: $Author: oj $ $Date: 2001-01-31 12:35:35 $ * last change: $Author: oj $ $Date: 2001-02-01 14:23:57 $
* *
* The Contents of this file are made available subject to the terms of * The Contents of this file are made available subject to the terms of
* either of the following licenses * either of the following licenses
...@@ -89,6 +89,9 @@ ...@@ -89,6 +89,9 @@
#ifndef _COM_SUN_STAR_SDBCX_XKEYSSUPPLIER_HPP_ #ifndef _COM_SUN_STAR_SDBCX_XKEYSSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XKeysSupplier.hpp> #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
#endif #endif
#ifndef _COM_SUN_STAR_SDBCX_XINDEXESSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XIndexesSupplier.hpp>
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx> #include <cppuhelper/typeprovider.hxx>
#endif #endif
...@@ -101,6 +104,9 @@ ...@@ -101,6 +104,9 @@
#ifndef _CONNECTIVITY_DBTOOLS_HXX_ #ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include <connectivity/dbtools.hxx> #include <connectivity/dbtools.hxx>
#endif #endif
#ifndef _LIST_
#include <list>
#endif
using namespace dbaccess; using namespace dbaccess;
using namespace connectivity; using namespace connectivity;
...@@ -118,46 +124,26 @@ using namespace ::osl; ...@@ -118,46 +124,26 @@ using namespace ::osl;
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
OKeySet::OKeySet(const Reference< XResultSet>& _xDriverSet, OKeySet::OKeySet(const Reference< XResultSet>& _xDriverSet,
const connectivity::OSQLTable& _xTable, const connectivity::OSQLTable& _xTable,
const ::rtl::OUString& _rUpdateTableName, // this can be the alias or the full qualified name
const Reference< XSQLQueryComposer >& _xComposer) const Reference< XSQLQueryComposer >& _xComposer)
: OCacheSet(_xDriverSet) : OCacheSet(_xDriverSet)
,m_xTable(_xTable) ,m_xTable(_xTable)
,m_bRowCountFinal(sal_False) ,m_bRowCountFinal(sal_False)
,m_xComposer(_xComposer)
,m_sUpdateTableName(_rUpdateTableName)
,m_aKeyColumnNames(m_xConnection->getMetaData()->storesMixedCaseQuotedIdentifiers())
,m_aColumnNames(m_xConnection->getMetaData()->storesMixedCaseQuotedIdentifiers())
{ {
try try
{ {
m_aColumnNames = getColumnNames(); Reference<XNameAccess> xKeyColumns = getKeyColumns();
sal_Int32 nSize = m_aColumnNames.size(); Reference<XColumnsSupplier> xSup(m_xComposer,UNO_QUERY);
::dbaccess::getColumnPositions(xSup->getColumns(),xKeyColumns,m_sUpdateTableName,m_aKeyColumnNames);
::dbaccess::getColumnPositions(xSup->getColumns(),_xTable->getColumns(),m_sUpdateTableName,m_aColumnNames);
Reference<XColumnLocate> xColumnLocate(_xDriverSet,UNO_QUERY);
if(xColumnLocate.is())
{
::std::vector< ::rtl::OUString>::const_iterator aIter;
for(aIter = m_aColumnNames.begin();aIter != m_aColumnNames.end();++aIter)
m_aColumnPos.push_back(xColumnLocate->findColumn(*aIter));
}
else
{
Reference<XPropertySet> xTableProp(_xTable,UNO_QUERY);
::std::vector< ::rtl::OUString>::const_iterator aIter;
::comphelper::UStringMixEqual bCase(m_xConnection->getMetaData()->storesMixedCaseQuotedIdentifiers());
sal_Int32 nColumnCount = m_xSetMetaData->getColumnCount();
for(sal_Int32 i=1;i<=nColumnCount;++i)
{
for(aIter = m_aColumnNames.begin();aIter != m_aColumnNames.end();++aIter)
{
if(bCase(m_xSetMetaData->getColumnName(i),*aIter) &&
bCase(m_xSetMetaData->getTableName(i),connectivity::getString(xTableProp->getPropertyValue(PROPERTY_NAME))))
{
m_aColumnPos.push_back(i);
break;
}
}
}
}
OSL_ENSURE(m_aColumnPos.size() == nSize,"Error not all pkey columns are found!");
// the first row is empty because it's now easier for us to distinguish when we are beforefirst or first // the first row is empty because it's now easier for us to distinguish when we are beforefirst or first
// without extra varaible to be set // without extra varaible to be set
m_aKeyMap.insert(OKeySetMatrix::value_type(0,NULL)); m_aKeyMap.insert(OKeySetMatrix::value_type(0,OKeySetValue(NULL,0)));
m_aKeyIter = m_aKeyMap.begin(); m_aKeyIter = m_aKeyMap.begin();
...@@ -173,15 +159,16 @@ OKeySet::OKeySet(const Reference< XResultSet>& _xDriverSet, ...@@ -173,15 +159,16 @@ OKeySet::OKeySet(const Reference< XResultSet>& _xDriverSet,
::dbtools::composeTableName(m_xConnection->getMetaData(),aCatalog,aSchema,aTable,aComposedName,sal_True); ::dbtools::composeTableName(m_xConnection->getMetaData(),aCatalog,aSchema,aTable,aComposedName,sal_True);
::std::vector< ::rtl::OUString>::const_iterator aIter = m_aColumnNames.begin(); // create the where clause
for(;aIter != m_aColumnNames.end();) OColumnNamePos::const_iterator aIter;
for(aIter = m_aKeyColumnNames.begin();aIter != m_aKeyColumnNames.end();)
{ {
aFilter += aComposedName; aFilter += aComposedName;
aFilter += ::rtl::OUString::createFromAscii("."); aFilter += ::rtl::OUString::createFromAscii(".");
aFilter += ::dbtools::quoteName( aQuote,*aIter); aFilter += ::dbtools::quoteName( aQuote,aIter->first);
aFilter += ::rtl::OUString::createFromAscii(" = ?"); aFilter += ::rtl::OUString::createFromAscii(" = ?");
++aIter; ++aIter;
if(aIter != m_aColumnNames.end()) if(aIter != m_aKeyColumnNames.end())
aFilter += aAnd; aFilter += aAnd;
} }
_xComposer->setFilter(aFilter); _xComposer->setFilter(aFilter);
...@@ -258,63 +245,36 @@ Sequence< sal_Int32 > SAL_CALL OKeySet::deleteRows( const Sequence< Any >& rows ...@@ -258,63 +245,36 @@ Sequence< sal_Int32 > SAL_CALL OKeySet::deleteRows( const Sequence< Any >& rows
static ::rtl::OUString aQuote = m_xConnection->getMetaData()->getIdentifierQuoteString(); static ::rtl::OUString aQuote = m_xConnection->getMetaData()->getIdentifierQuoteString();
static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND "); static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND ");
static ::rtl::OUString aOr = ::rtl::OUString::createFromAscii(" OR "); static ::rtl::OUString aOr = ::rtl::OUString::createFromAscii(" OR ");
static ::rtl::OUString aEqual = ::rtl::OUString::createFromAscii(" = ?");
// use keys and indexes for excat postioning // use keys and indexes for excat postioning
// first the keys // first the keys
Reference<XKeysSupplier> xKeySup(_xTable,UNO_QUERY); Reference<XNameAccess> xKeyColumns = getKeyColumns();
Reference<XIndexAccess> xKeys;
if(xKeySup.is())
xKeys = xKeySup->getKeys();
Reference<XColumnsSupplier> xKeyColsSup; ::rtl::OUString aCondition = ::rtl::OUString::createFromAscii("( ");
Reference<XNameAccess> xKeyColumns; OColumnNamePos::const_iterator aIter = m_aKeyColumnNames.begin();
if(xKeys.is()) for(;aIter != m_aKeyColumnNames.end();++aIter)
{ {
Reference<XPropertySet> xProp; aCondition += ::dbtools::quoteName( aQuote,aIter->first);
for(sal_Int32 i=0;i< xKeys->getCount();++i) aCondition += aEqual;
{ aCondition += aAnd;
xKeys->getByIndex(i) >>= xProp;
sal_Int32 nKeyType = 0;
xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;
if(KeyType::PRIMARY == nKeyType)
{
xKeyColsSup = Reference<XColumnsSupplier>(xProp,UNO_QUERY);
break;
}
}
if(xKeyColsSup.is())
xKeyColumns = xKeyColsSup->getColumns();
} }
aCondition = aCondition.replaceAt(aCondition.getLength()-5,5,::rtl::OUString::createFromAscii(" )"));
if(!xKeyColumns.is())
throw SQLException();
::rtl::OUString aColumnName;
const Any* pBegin = rows.getConstArray(); const Any* pBegin = rows.getConstArray();
const Any* pEnd = pBegin + rows.getLength(); const Any* pEnd = pBegin + rows.getLength();
Sequence< ::rtl::OUString> aColumnNames = xKeyColumns->getElementNames();
Sequence< Any > aKeys; Sequence< Any > aKeys;
for(;pBegin != pEnd;++pBegin) for(;pBegin != pEnd;++pBegin)
{ {
aSql += ::rtl::OUString::createFromAscii("( "); aSql += aCondition;
// pBegin >>= aKeys;
const ::rtl::OUString*pColumnBegin = aColumnNames.getConstArray();
const ::rtl::OUString*pColumnEnd = pColumnBegin + aColumnNames.getLength();
for(;pColumnBegin != pColumnEnd;++pColumnBegin)
{
aSql += ::dbtools::quoteName( aQuote,*pColumnBegin);
aSql += ::rtl::OUString::createFromAscii(" = ?");
aSql += aAnd;
}
aSql = aSql.replaceAt(aSql.getLength()-5,5,::rtl::OUString::createFromAscii(" )"));
aSql += aOr; aSql += aOr;
} }
aSql = aSql.replaceAt(aSql.getLength()-3,3,::rtl::OUString::createFromAscii(" ")); aSql = aSql.replaceAt(aSql.getLength()-3,3,::rtl::OUString::createFromAscii(" "));
// now create end execute the prepared statement // now create end execute the prepared statement
Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(aSql)); Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(aSql));
Reference< XParameters > xParameter(xPrep,UNO_QUERY); Reference< XParameters > xParameter(xPrep,UNO_QUERY);
...@@ -322,44 +282,14 @@ Sequence< sal_Int32 > SAL_CALL OKeySet::deleteRows( const Sequence< Any >& rows ...@@ -322,44 +282,14 @@ Sequence< sal_Int32 > SAL_CALL OKeySet::deleteRows( const Sequence< Any >& rows
sal_Int32 i=1; sal_Int32 i=1;
for(;pBegin != pEnd;++pBegin) for(;pBegin != pEnd;++pBegin)
{ {
Sequence< Any >* pValuePair = (Sequence< Any >*)pBegin->getValue(); m_aKeyIter = m_aKeyMap.find(::comphelper::getINT32(*pBegin));
if(m_aKeyIter != m_aKeyMap.end())
const Any* pValBegin = pValuePair->getConstArray();
const Any* pValEnd = pValBegin + pValuePair->getLength();
for(;pValBegin != pValEnd; ++pValBegin,++i)
{ {
switch(pValBegin->getValueTypeClass()) connectivity::ORowVector< ORowSetValue >::iterator aKeyIter = m_aKeyIter->second.first->begin();
for(;aKeyIter != m_aKeyIter->second.first->end();++aKeyIter)
{ {
case TypeClass_STRING: setParameter(i++,xParameter,*aKeyIter);
case TypeClass_CHAR: }
{
::rtl::OUString aVal;
*pValBegin >>= aVal;
xParameter->setString(i,aVal);
}
break;
case TypeClass_BOOLEAN:
xParameter->setBoolean(i,*(sal_Bool*)pValBegin->getValue());
break;
case TypeClass_BYTE:
xParameter->setByte(i,*(sal_Int8*)pValBegin->getValue());
break;
case TypeClass_SHORT:
case TypeClass_UNSIGNED_SHORT:
xParameter->setShort(i,*(sal_Int16*)pValBegin->getValue());
break;
case TypeClass_LONG:
case TypeClass_UNSIGNED_LONG:
xParameter->setInt(i,*(sal_Int32*)pValBegin->getValue());
break;
case TypeClass_FLOAT:
xParameter->setFloat(i,*(float*)pValBegin->getValue());
break;
case TypeClass_DOUBLE:
xParameter->setDouble(i,*(double*)pValBegin->getValue());
break;
};
} }
} }
...@@ -383,31 +313,193 @@ Sequence< sal_Int32 > SAL_CALL OKeySet::deleteRows( const Sequence< Any >& rows ...@@ -383,31 +313,193 @@ Sequence< sal_Int32 > SAL_CALL OKeySet::deleteRows( const Sequence< Any >& rows
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void SAL_CALL OKeySet::updateRow(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException) void SAL_CALL OKeySet::updateRow(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
{ {
OCacheSet::updateRow( _rInsertRow,_rOrginalRow,_xTable); Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
if(rowUpdated()) fillTableName(xSet);
::rtl::OUString aSql = ::rtl::OUString::createFromAscii("UPDATE ");
aSql += m_aComposedTableName;
aSql += ::rtl::OUString::createFromAscii(" SET ");
// list all cloumns that should be set
static ::rtl::OUString aPara = ::rtl::OUString::createFromAscii(" = ?,");
static ::rtl::OUString aQuote = m_xConnection->getMetaData()->getIdentifierQuoteString();
static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND ");
// use keys and indexes for excat postioning
// first the keys
Reference<XNameAccess> xKeyColumns = getKeyColumns();
// second the indexes
Reference<XIndexesSupplier> xIndexSup(_xTable,UNO_QUERY);
Reference<XIndexAccess> xIndexes;
if(xIndexSup.is())
xIndexes = Reference<XIndexAccess>(xIndexSup->getIndexes(),UNO_QUERY);
Reference<XPropertySet> xIndexColsSup;
Reference<XNameAccess> xIndexColumns;
::std::vector< Reference<XNameAccess> > aAllIndexColumns;
OSL_ENSURE(xIndexes.is(),"No indexes!");
if(xIndexes.is())
{
for(sal_Int32 j=0;j<xIndexes->getCount();++j)
{
xIndexes->getByIndex(j) >>= xIndexColsSup;
if( xIndexColsSup.is()
&& connectivity::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISUNIQUE))
&& !connectivity::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISPRIMARYKEYINDEX))
)
aAllIndexColumns.push_back(Reference<XColumnsSupplier>(xIndexColsSup,UNO_QUERY)->getColumns());
}
}
::rtl::OUString aColumnName;
::rtl::OUString aCondition,sSetValues;
// here we build the condition part for the update statement
OColumnNamePos::const_iterator aIter = m_aColumnNames.begin();
for(;aIter != m_aColumnNames.end();++aIter)
{
if(xKeyColumns.is() && xKeyColumns->hasByName(aIter->first))
{
aCondition += ::dbtools::quoteName( aQuote,aIter->first);
if((*_rOrginalRow)[aIter->second].isNull())
aCondition += ::rtl::OUString::createFromAscii(" IS NULL");
else
aCondition += ::rtl::OUString::createFromAscii(" = ?");
aCondition += aAnd;
}
for( ::std::vector< Reference<XNameAccess> >::const_iterator aIndexIter = aAllIndexColumns.begin();
aIndexIter != aAllIndexColumns.end();++aIndexIter)
{
if((*aIndexIter)->hasByName(aIter->first))
{
aCondition += ::dbtools::quoteName( aQuote,aIter->first);
if((*_rOrginalRow)[aIter->second].isNull())
aCondition += ::rtl::OUString::createFromAscii(" IS NULL");
else
aCondition += ::rtl::OUString::createFromAscii(" = ?");
aCondition += aAnd;
break;
}
}
if((*_rInsertRow)[aIter->second].isModified())
{
sSetValues += ::dbtools::quoteName( aQuote,aIter->first);
sSetValues += aPara;
}
}
if(sSetValues.getLength())
{
sSetValues = sSetValues.replaceAt(sSetValues.getLength()-1,1,::rtl::OUString::createFromAscii(" "));
aSql += sSetValues;
}
else
throw SQLException(::rtl::OUString::createFromAscii("No modified Values!"),m_xConnection,::rtl::OUString::createFromAscii("HY0000"),1000,Any());
if(aCondition.getLength())
{
aCondition = aCondition.replaceAt(aCondition.getLength()-5,5,::rtl::OUString::createFromAscii(" "));
aSql += ::rtl::OUString::createFromAscii(" WHERE ");
aSql += aCondition;
}
else
throw SQLException(::rtl::OUString::createFromAscii("No where condition!"),m_xConnection,::rtl::OUString::createFromAscii("HY0000"),1000,Any());
// now create end execute the prepared statement
Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(aSql));
Reference< XParameters > xParameter(xPrep,UNO_QUERY);
sal_Int32 i = 1;
// first the set values
aIter = m_aColumnNames.begin();
for(;aIter != m_aColumnNames.end();++aIter)
{
if((*_rInsertRow)[aIter->second].isModified())
setParameter(i++,xParameter,(*_rInsertRow)[aIter->second]);
}
// and then the values of the where condition
aIter = m_aKeyColumnNames.begin();
for(;aIter != m_aKeyColumnNames.end();++aIter,++i)
{
setParameter(i,xParameter,(*_rOrginalRow)[aIter->second]);
}
m_bUpdated = xPrep->executeUpdate() > 0;
if(m_bUpdated)
{ {
m_aKeyIter = m_aKeyMap.find(::comphelper::getINT32((*_rInsertRow)[0].getAny())); m_aKeyIter = m_aKeyMap.find(::comphelper::getINT32((*_rInsertRow)[0].getAny()));
connectivity::ORowVector< ORowSetValue >::iterator aIter = m_aKeyIter->second->begin(); OSL_ENSURE(m_aKeyIter != m_aKeyMap.end(),"New inserted row not found!");
::std::vector< sal_Int32>::const_iterator aPosIter = m_aColumnPos.begin(); m_aKeyIter->second.second = 2;
for(;aPosIter != m_aColumnPos.end();++aPosIter,++aIter) connectivity::ORowVector< ORowSetValue >::iterator aIter = m_aKeyIter->second.first->begin();
*aIter = (*_rInsertRow)[*aPosIter]; OColumnNamePos::const_iterator aPosIter = m_aKeyColumnNames.begin();
for(;aPosIter != m_aKeyColumnNames.end();++aPosIter,++aIter)
*aIter = (*_rInsertRow)[aPosIter->second];
} }
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void SAL_CALL OKeySet::insertRow( const ORowSetRow& _rInsertRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException) void SAL_CALL OKeySet::insertRow( const ORowSetRow& _rInsertRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
{ {
OCacheSet::insertRow( _rInsertRow,_xTable); ::rtl::OUString aSql(::rtl::OUString::createFromAscii("INSERT INTO "));
if(rowInserted()) Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
fillTableName(xSet);
aSql += m_aComposedTableName;
aSql += ::rtl::OUString::createFromAscii(" ( ");
// set values and column names
::rtl::OUString aValues = ::rtl::OUString::createFromAscii(" VALUES ( ");
static ::rtl::OUString aPara = ::rtl::OUString::createFromAscii("?,");
static ::rtl::OUString aQuote = m_xConnection->getMetaData()->getIdentifierQuoteString();
static ::rtl::OUString aComma = ::rtl::OUString::createFromAscii(",");
OColumnNamePos::const_iterator aIter = m_aColumnNames.begin();
for(;aIter != m_aColumnNames.end();++aIter)
{ {
ORowSetRow aKeyRow = new connectivity::ORowVector< ORowSetValue >(m_aColumnPos.size()); aSql += ::dbtools::quoteName( aQuote,aIter->first);
aSql += aComma;
aValues += aPara;
}
aSql = aSql.replaceAt(aSql.getLength()-1,1,::rtl::OUString::createFromAscii(")"));
aValues = aValues.replaceAt(aValues.getLength()-1,1,::rtl::OUString::createFromAscii(")"));
aSql += aValues;
// now create,fill and execute the prepared statement
Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(aSql));
Reference< XParameters > xParameter(xPrep,UNO_QUERY);
OColumnNamePos::const_iterator aPosIter = m_aColumnNames.begin();
// for(aIter = _rInsertRow->begin()+1; aIter != _rInsertRow->end();++aIter,++i)
for(sal_Int32 i = 1;aPosIter != m_aColumnNames.end();++aPosIter,++i)
{
if((*_rInsertRow)[aPosIter->second].isNull())
xParameter->setNull(i,(*_rInsertRow)[aPosIter->second].getTypeKind());
else
setParameter(i,xParameter,(*_rInsertRow)[aPosIter->second]);
// if(aIter->isNull())
// xParameter->setNull(i,aIter->getTypeKind());
// else
// setParameter(i,xParameter,*aIter);
}
m_bInserted = xPrep->executeUpdate() > 0;
// OCacheSet::insertRow( _rInsertRow,_xTable);
if(m_bInserted)
{
ORowSetRow aKeyRow = new connectivity::ORowVector< ORowSetValue >(m_aKeyColumnNames.size());
connectivity::ORowVector< ORowSetValue >::iterator aIter = aKeyRow->begin(); connectivity::ORowVector< ORowSetValue >::iterator aIter = aKeyRow->begin();
::std::vector< sal_Int32>::const_iterator aPosIter = m_aColumnPos.begin(); OColumnNamePos::const_iterator aPosIter = m_aKeyColumnNames.begin();
for(;aPosIter != m_aColumnPos.end();++aPosIter,++aIter) for(;aPosIter != m_aKeyColumnNames.end();++aPosIter,++aIter)
*aIter = (*_rInsertRow)[*aPosIter]; *aIter = (*_rInsertRow)[aPosIter->second];
OKeySetMatrix::iterator aKeyIter = m_aKeyMap.end(); OKeySetMatrix::iterator aKeyIter = m_aKeyMap.end();
--aKeyIter; --aKeyIter;
m_aKeyIter = m_aKeyMap.insert(OKeySetMatrix::value_type(aKeyIter->first + 1,aKeyRow)).first; m_aKeyIter = m_aKeyMap.insert(OKeySetMatrix::value_type(aKeyIter->first + 1,OKeySetValue(aKeyRow,1))).first;
// now we set the bookmark for this row // now we set the bookmark for this row
(*_rInsertRow)[0] = makeAny((sal_Int32)m_aKeyIter->first); (*_rInsertRow)[0] = makeAny((sal_Int32)m_aKeyIter->first);
} }
...@@ -415,8 +507,89 @@ void SAL_CALL OKeySet::insertRow( const ORowSetRow& _rInsertRow,const connectivi ...@@ -415,8 +507,89 @@ void SAL_CALL OKeySet::insertRow( const ORowSetRow& _rInsertRow,const connectivi
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void SAL_CALL OKeySet::deleteRow(const ORowSetRow& _rDeleteRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException) void SAL_CALL OKeySet::deleteRow(const ORowSetRow& _rDeleteRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
{ {
OCacheSet::deleteRow(_rDeleteRow,_xTable); Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
if(rowDeleted()) fillTableName(xSet);
::rtl::OUString aSql = ::rtl::OUString::createFromAscii("DELETE FROM ");
aSql += m_aComposedTableName;
aSql += ::rtl::OUString::createFromAscii(" WHERE ");
// list all cloumns that should be set
static ::rtl::OUString aQuote = m_xConnection->getMetaData()->getIdentifierQuoteString();
static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND ");
// use keys and indexes for excat postioning
Reference<XNameAccess> xKeyColumns = getKeyColumns();
// second the indexes
Reference<XIndexesSupplier> xIndexSup(_xTable,UNO_QUERY);
Reference<XIndexAccess> xIndexes;
if(xIndexSup.is())
xIndexes = Reference<XIndexAccess>(xIndexSup->getIndexes(),UNO_QUERY);
// Reference<XColumnsSupplier>
Reference<XPropertySet> xIndexColsSup;
Reference<XNameAccess> xIndexColumns;
::std::vector< Reference<XNameAccess> > aAllIndexColumns;
if(xIndexes.is())
{
for(sal_Int32 j=0;j<xIndexes->getCount();++j)
{
xIndexes->getByIndex(j) >>= xIndexColsSup;
if( xIndexColsSup.is()
&& connectivity::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISUNIQUE))
&& !connectivity::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISPRIMARYKEYINDEX))
)
aAllIndexColumns.push_back(Reference<XColumnsSupplier>(xIndexColsSup,UNO_QUERY)->getColumns());
}
}
::rtl::OUString aColumnName;
OColumnNamePos::const_iterator aIter = m_aColumnNames.begin();
for(;aIter != m_aColumnNames.end();++aIter)
{
if(xKeyColumns.is() && xKeyColumns->hasByName(aIter->first))
{
aSql += ::dbtools::quoteName( aQuote,aIter->first);
if((*_rDeleteRow)[aIter->second].isNull())
{
OSL_ENSURE(0,"can a primary key be null");
aSql += ::rtl::OUString::createFromAscii(" IS NULL");
}
else
aSql += ::rtl::OUString::createFromAscii(" = ?");
aSql += aAnd;
}
// for( ::std::vector< Reference<XNameAccess> >::const_iterator aIndexIter = aAllIndexColumns.begin();
// aIndexIter != aAllIndexColumns.end();++aIndexIter)
// {
// if((*aIndexIter)->hasByName(aIter->first))
// {
// aSql += ::dbtools::quoteName( aQuote,aIter->first);
// if((*_rDeleteRow)[aIter->second].isNull())
// aSql += ::rtl::OUString::createFromAscii(" IS NULL");
// else
// aSql += ::rtl::OUString::createFromAscii(" = ?");
// aSql += aAnd;
// break;
// }
// }
}
aSql = aSql.replaceAt(aSql.getLength()-5,5,::rtl::OUString::createFromAscii(" "));
// now create end execute the prepared statement
Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(aSql));
Reference< XParameters > xParameter(xPrep,UNO_QUERY);
aIter = m_aKeyColumnNames.begin();
for(sal_Int32 i = 1;aIter != m_aKeyColumnNames.end();++aIter,++i)
{
setParameter(i,xParameter,(*_rDeleteRow)[aIter->second]);
}
m_bDeleted = xPrep->executeUpdate() > 0;
if(m_bDeleted)
{ {
sal_Int32 nPos = ::comphelper::getINT32((*_rDeleteRow)[0].getAny()); sal_Int32 nPos = ::comphelper::getINT32((*_rDeleteRow)[0].getAny());
m_aKeyMap.erase(nPos); m_aKeyMap.erase(nPos);
...@@ -437,7 +610,7 @@ void SAL_CALL OKeySet::moveToCurrentRow( ) throw(SQLException, RuntimeException ...@@ -437,7 +610,7 @@ void SAL_CALL OKeySet::moveToCurrentRow( ) throw(SQLException, RuntimeException
{ {
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
::std::vector< ::rtl::OUString> OKeySet::getColumnNames() Reference<XNameAccess> OKeySet::getKeyColumns() const
{ {
// use keys and indexes for excat postioning // use keys and indexes for excat postioning
// first the keys // first the keys
...@@ -448,7 +621,6 @@ void SAL_CALL OKeySet::moveToCurrentRow( ) throw(SQLException, RuntimeException ...@@ -448,7 +621,6 @@ void SAL_CALL OKeySet::moveToCurrentRow( ) throw(SQLException, RuntimeException
Reference<XColumnsSupplier> xKeyColsSup; Reference<XColumnsSupplier> xKeyColsSup;
Reference<XNameAccess> xKeyColumns; Reference<XNameAccess> xKeyColumns;
::std::vector< ::rtl::OUString> aColumnNames;
if(xKeys.is()) if(xKeys.is())
{ {
Reference<XPropertySet> xProp; Reference<XPropertySet> xProp;
...@@ -462,20 +634,12 @@ void SAL_CALL OKeySet::moveToCurrentRow( ) throw(SQLException, RuntimeException ...@@ -462,20 +634,12 @@ void SAL_CALL OKeySet::moveToCurrentRow( ) throw(SQLException, RuntimeException
xKeyColsSup = Reference<XColumnsSupplier>(xProp,UNO_QUERY); xKeyColsSup = Reference<XColumnsSupplier>(xProp,UNO_QUERY);
OSL_ENSURE(xKeyColsSup.is(),"Columnsupplier is null!"); OSL_ENSURE(xKeyColsSup.is(),"Columnsupplier is null!");
xKeyColumns = xKeyColsSup->getColumns(); xKeyColumns = xKeyColsSup->getColumns();
if(xKeyColumns.is())
{
Sequence< ::rtl::OUString> aSeqNames = xKeyColumns->getElementNames();
const ::rtl::OUString*pColumnBegin = aSeqNames.getConstArray();
const ::rtl::OUString*pColumnEnd = pColumnBegin + aSeqNames.getLength();
for(;pColumnBegin != pColumnEnd;++pColumnBegin)
aColumnNames.push_back(*pColumnBegin);
}
break; break;
} }
} }
} }
return aColumnNames; return xKeyColumns;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
sal_Bool SAL_CALL OKeySet::next( ) throw(SQLException, RuntimeException) sal_Bool SAL_CALL OKeySet::next( ) throw(SQLException, RuntimeException)
...@@ -645,9 +809,9 @@ void SAL_CALL OKeySet::refreshRow() throw(SQLException, RuntimeException) ...@@ -645,9 +809,9 @@ void SAL_CALL OKeySet::refreshRow() throw(SQLException, RuntimeException)
// we just areassign the base members // we just areassign the base members
Reference< XParameters > xParameter(m_xStatement,UNO_QUERY); Reference< XParameters > xParameter(m_xStatement,UNO_QUERY);
connectivity::ORowVector< ORowSetValue >::iterator aIter = m_aKeyIter->second->begin(); connectivity::ORowVector< ORowSetValue >::iterator aIter = m_aKeyIter->second.first->begin();
::std::vector< ::rtl::OUString>::const_iterator aPosIter = m_aColumnNames.begin(); OColumnNamePos::const_iterator aPosIter = m_aKeyColumnNames.begin();
for(sal_Int32 nPos=1;aPosIter != m_aColumnNames.end();++aPosIter,++aIter,++nPos) for(sal_Int32 nPos=1;aPosIter != m_aKeyColumnNames.end();++aPosIter,++aIter,++nPos)
{ {
switch(aIter->getTypeKind()) switch(aIter->getTypeKind())
{ {
...@@ -705,59 +869,59 @@ sal_Bool OKeySet::fetchRow() ...@@ -705,59 +869,59 @@ sal_Bool OKeySet::fetchRow()
sal_Bool bRet; sal_Bool bRet;
if(!m_bRowCountFinal && (bRet = m_xDriverSet->next())) if(!m_bRowCountFinal && (bRet = m_xDriverSet->next()))
{ {
ORowSetRow aKeyRow = new connectivity::ORowVector< ORowSetValue >(m_aColumnPos.size()); ORowSetRow aKeyRow = new connectivity::ORowVector< ORowSetValue >(m_aKeyColumnNames.size());
connectivity::ORowVector< ORowSetValue >::iterator aIter = aKeyRow->begin(); connectivity::ORowVector< ORowSetValue >::iterator aIter = aKeyRow->begin();
::std::vector< sal_Int32>::const_iterator aPosIter = m_aColumnPos.begin(); OColumnNamePos::const_iterator aPosIter = m_aKeyColumnNames.begin();
for(;aPosIter != m_aColumnPos.end();++aPosIter,++aIter) for(;aPosIter != m_aKeyColumnNames.end();++aPosIter,++aIter)
{ {
sal_Int32 nType = m_xSetMetaData->getColumnType(*aPosIter); sal_Int32 nType = m_xSetMetaData->getColumnType(aPosIter->second);
switch(nType) switch(nType)
{ {
case DataType::CHAR: case DataType::CHAR:
case DataType::VARCHAR: case DataType::VARCHAR:
(*aIter) = m_xDriverRow->getString(*aPosIter); (*aIter) = m_xDriverRow->getString(aPosIter->second);
break; break;
case DataType::DOUBLE: case DataType::DOUBLE:
case DataType::FLOAT: case DataType::FLOAT:
case DataType::REAL: case DataType::REAL:
case DataType::DECIMAL: case DataType::DECIMAL:
case DataType::NUMERIC: case DataType::NUMERIC:
(*aIter) = m_xDriverRow->getDouble(*aPosIter); (*aIter) = m_xDriverRow->getDouble(aPosIter->second);
break; break;
case DataType::DATE: case DataType::DATE:
(*aIter) = m_xDriverRow->getDate(*aPosIter); (*aIter) = m_xDriverRow->getDate(aPosIter->second);
break; break;
case DataType::TIME: case DataType::TIME:
(*aIter) = m_xDriverRow->getTime(*aPosIter); (*aIter) = m_xDriverRow->getTime(aPosIter->second);
break; break;
case DataType::TIMESTAMP: case DataType::TIMESTAMP:
(*aIter) = m_xDriverRow->getTimestamp(*aPosIter); (*aIter) = m_xDriverRow->getTimestamp(aPosIter->second);
break; break;
case DataType::BINARY: case DataType::BINARY:
case DataType::VARBINARY: case DataType::VARBINARY:
case DataType::LONGVARBINARY: case DataType::LONGVARBINARY:
case DataType::LONGVARCHAR: case DataType::LONGVARCHAR:
(*aIter) = m_xDriverRow->getBytes(*aPosIter); (*aIter) = m_xDriverRow->getBytes(aPosIter->second);
break; break;
case DataType::BIT: case DataType::BIT:
(*aIter) = m_xDriverRow->getBoolean(*aPosIter); (*aIter) = m_xDriverRow->getBoolean(aPosIter->second);
break; break;
case DataType::TINYINT: case DataType::TINYINT:
(*aIter) = (sal_Int32)m_xDriverRow->getByte(*aPosIter); (*aIter) = (sal_Int32)m_xDriverRow->getByte(aPosIter->second);
break; break;
case DataType::SMALLINT: case DataType::SMALLINT:
(*aIter) = (sal_Int32)m_xDriverRow->getShort(*aPosIter); (*aIter) = (sal_Int32)m_xDriverRow->getShort(aPosIter->second);
break; break;
case DataType::INTEGER: case DataType::INTEGER:
(*aIter) = m_xDriverRow->getInt(*aPosIter); (*aIter) = m_xDriverRow->getInt(aPosIter->second);
break; break;
} }
if(m_xDriverRow->wasNull()) if(m_xDriverRow->wasNull())
aIter->setNull(); aIter->setNull();
aIter->setTypeKind(nType); aIter->setTypeKind(nType);
} }
m_aKeyIter = m_aKeyMap.insert(OKeySetMatrix::value_type(m_aKeyMap.size(),aKeyRow)).first; m_aKeyIter = m_aKeyMap.insert(OKeySetMatrix::value_type(m_aKeyMap.size(),OKeySetValue(aKeyRow,0))).first;
} }
else else
m_bRowCountFinal = sal_True; m_bRowCountFinal = sal_True;
...@@ -773,10 +937,54 @@ void OKeySet::fillAllRows() ...@@ -773,10 +937,54 @@ void OKeySet::fillAllRows()
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
namespace dbaccess
{
void getColumnPositions(const Reference<XNameAccess>& _rxQueryColumns,
const Reference<XNameAccess>& _rxColumns,
const ::rtl::OUString& _rsUpdateTableName,
OColumnNamePos& _rColumnNames)
{
// get the real name of the columns
Sequence< ::rtl::OUString> aSelNames(_rxQueryColumns->getElementNames());
const ::rtl::OUString* pSelBegin = aSelNames.getConstArray();
const ::rtl::OUString* pSelEnd = pSelBegin + aSelNames.getLength();
Sequence< ::rtl::OUString> aTableNames(_rxColumns->getElementNames());
const ::rtl::OUString* pTableBegin = aTableNames.getConstArray();
const ::rtl::OUString* pTableEnd = pTableBegin + aTableNames.getLength();
::comphelper::UStringMixEqual bCase(static_cast<::comphelper::UStringMixLess*>(&_rColumnNames.key_comp())->isCaseSensitive());
for(sal_Int32 nPos = 1;pSelBegin != pSelEnd;++pSelBegin,++nPos)
{
Reference<XPropertySet> xColumnProp;
_rxQueryColumns->getByName(*pSelBegin) >>= xColumnProp;
::rtl::OUString sRealName,sTableName;
OSL_ENSURE(xColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME),"Property REALNAME not available!");
OSL_ENSURE(xColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME),"Property TABLENAME not available!");
xColumnProp->getPropertyValue(PROPERTY_REALNAME) >>= sRealName;
xColumnProp->getPropertyValue(PROPERTY_TABLENAME) >>= sTableName;
for(;pTableBegin != pTableEnd;++pTableBegin)
{
if(bCase(sRealName,*pTableBegin) && bCase(_rsUpdateTableName,sTableName) && _rColumnNames.find(*pTableBegin) == _rColumnNames.end())
{
_rColumnNames[sRealName] = nPos;
if(_rColumnNames.size() == aTableNames.getLength())
return; // early break we found all columns
break;
}
}
pTableBegin = aTableNames.getConstArray();
}
}
}
/*------------------------------------------------------------------------ /*------------------------------------------------------------------------
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.10 2001/01/31 12:35:35 oj
use of qouteName
Revision 1.9 2001/01/30 14:27:46 oj Revision 1.9 2001/01/30 14:27:46 oj
new member which holds the column names new member which holds the column names
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
* *
* $RCSfile: KeySet.hxx,v $ * $RCSfile: KeySet.hxx,v $
* *
* $Revision: 1.6 $ * $Revision: 1.7 $
* *
* last change: $Author: oj $ $Date: 2001-01-30 14:27:47 $ * last change: $Author: oj $ $Date: 2001-02-01 14:23:57 $
* *
* The Contents of this file are made available subject to the terms of * The Contents of this file are made available subject to the terms of
* either of the following licenses * either of the following licenses
...@@ -78,33 +78,48 @@ ...@@ -78,33 +78,48 @@
#ifndef _COM_SUN_STAR_SDB_XSQLQUERYCOMPOSER_HPP_ #ifndef _COM_SUN_STAR_SDB_XSQLQUERYCOMPOSER_HPP_
#include <com/sun/star/sdb/XSQLQueryComposer.hpp> #include <com/sun/star/sdb/XSQLQueryComposer.hpp>
#endif #endif
#ifndef _COMPHELPER_STLTYPES_HXX_
#include <comphelper/stl_types.hxx>
#endif
namespace dbaccess namespace dbaccess
{ {
typedef ::std::map<sal_Int32,ORowSetRow> OKeySetMatrix; DECLARE_STL_MAP(::rtl::OUString,sal_Int32,::comphelper::UStringMixLess,OColumnNamePos);
// the elements of _rxQueryColumns must have the properties PROPERTY_REALNAME and PROPERTY_TABLENAME
void getColumnPositions(const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxQueryColumns,
const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxColumns,
const ::rtl::OUString& _rsUpdateTableName,
OColumnNamePos& _rColumnNames /* out */);
typedef ::std::pair<ORowSetRow,sal_Int32> OKeySetValue;
typedef ::std::map<sal_Int32,OKeySetValue > OKeySetMatrix;
// is used when the source supports keys // is used when the source supports keys
class OKeySet : public OCacheSet class OKeySet : public OCacheSet
{ {
OKeySetMatrix m_aKeyMap; OKeySetMatrix m_aKeyMap;
OKeySetMatrix::iterator m_aKeyIter; OKeySetMatrix::iterator m_aKeyIter;
::std::vector< sal_Int32> m_aColumnPos; OColumnNamePos m_aKeyColumnNames; // contains all key column names
::std::vector< ::rtl::OUString> m_aColumnNames; OColumnNamePos m_aColumnNames; // contains all column names
connectivity::OSQLTable m_xTable; // reference to our table connectivity::OSQLTable m_xTable; // reference to our table
::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement> m_xStatement; ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement> m_xStatement;
::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet> m_xSet; ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet> m_xSet;
::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow> m_xRow; ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow> m_xRow;
::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLQueryComposer > m_xComposer;
::rtl::OUString m_sUpdateTableName;
// ::std::vector< OKeySetMatrix::iterator> m_aKeyPosition; // ::std::vector< OKeySetMatrix::iterator> m_aKeyPosition;
// ::std::vector< OKeySetMatrix::iterator>::iterator m_aKeyIter; // ::std::vector< OKeySetMatrix::iterator>::iterator m_aKeyIter;
sal_Bool m_bRowCountFinal; sal_Bool m_bRowCountFinal;
::std::vector< ::rtl::OUString> getColumnNames(); ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > getKeyColumns() const;
void fillAllRows(); void fillAllRows();
sal_Bool fetchRow(); sal_Bool fetchRow();
public: public:
OKeySet(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet>& _xDriverSet, OKeySet(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet>& _xDriverSet,
const connectivity::OSQLTable& _xTable, const connectivity::OSQLTable& _xTable,
const ::rtl::OUString& _rUpdateTableName,
const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLQueryComposer >& _xComposer); const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLQueryComposer >& _xComposer);
~OKeySet(); ~OKeySet();
...@@ -230,17 +245,17 @@ namespace dbaccess ...@@ -230,17 +245,17 @@ namespace dbaccess
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
virtual sal_Bool SAL_CALL rowUpdated( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) virtual sal_Bool SAL_CALL rowUpdated( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{ {
return m_bUpdated; return m_aKeyIter != m_aKeyMap.begin() && m_aKeyIter != m_aKeyMap.end() && m_aKeyIter->second.second == 2;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
virtual sal_Bool SAL_CALL rowInserted( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) virtual sal_Bool SAL_CALL rowInserted( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{ {
return m_bInserted; return m_aKeyIter != m_aKeyMap.begin() && m_aKeyIter != m_aKeyMap.end() && m_aKeyIter->second.second == 1;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
virtual sal_Bool SAL_CALL rowDeleted( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) virtual sal_Bool SAL_CALL rowDeleted( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{ {
return m_bDeleted; return sal_False;
} }
// ::com::sun::star::sdbc::XResultSet // ::com::sun::star::sdbc::XResultSet
...@@ -286,6 +301,9 @@ namespace dbaccess ...@@ -286,6 +301,9 @@ namespace dbaccess
/*------------------------------------------------------------------------ /*------------------------------------------------------------------------
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.6 2001/01/30 14:27:47 oj
new member which holds the column names
Revision 1.5 2001/01/24 09:50:49 oj Revision 1.5 2001/01/24 09:50:49 oj
#82628# rowset modifications #82628# rowset modifications
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
* *
* $RCSfile: RowSetCache.cxx,v $ * $RCSfile: RowSetCache.cxx,v $
* *
* $Revision: 1.23 $ * $Revision: 1.24 $
* *
* last change: $Author: oj $ $Date: 2001-01-26 15:18:17 $ * last change: $Author: oj $ $Date: 2001-02-01 14:23:57 $
* *
* The Contents of this file are made available subject to the terms of * The Contents of this file are made available subject to the terms of
* either of the following licenses * either of the following licenses
...@@ -95,6 +95,9 @@ ...@@ -95,6 +95,9 @@
#ifndef _COM_SUN_STAR_SDBC_RESULTSETCONCURRENCY_HPP_ #ifndef _COM_SUN_STAR_SDBC_RESULTSETCONCURRENCY_HPP_
#include <com/sun/star/sdbc/ResultSetConcurrency.hpp> #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
#endif #endif
#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
#include <com/sun/star/sdbc/ColumnValue.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_PRIVILEGE_HPP_ #ifndef _COM_SUN_STAR_SDBCX_PRIVILEGE_HPP_
#include <com/sun/star/sdbcx/Privilege.hpp> #include <com/sun/star/sdbcx/Privilege.hpp>
#endif #endif
...@@ -156,16 +159,22 @@ ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs, ...@@ -156,16 +159,22 @@ ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs,
// check if all keys of the updateable table are fetched // check if all keys of the updateable table are fetched
sal_Bool bAllKeysFound = sal_False; sal_Bool bAllKeysFound = sal_False;
::rtl::OUString aUpdateTableName = _rUpdateTableName;
Reference< XConnection> xConnection;
if(_xComposer.is()) if(_xComposer.is())
{ {
Reference<XTablesSupplier> xTabSup(_xComposer,UNO_QUERY); Reference<XTablesSupplier> xTabSup(_xComposer,UNO_QUERY);
OSL_ENSURE(xTabSup.is(),"ORowSet::execute composer isn't a tablesupplier!"); OSL_ENSURE(xTabSup.is(),"ORowSet::execute composer isn't a tablesupplier!");
Reference<XNameAccess> xTables = xTabSup->getTables(); Reference<XNameAccess> xTables = xTabSup->getTables();
if(_rUpdateTableName.getLength())
if(_rUpdateTableName.getLength() && xTables->hasByName(_rUpdateTableName))
xTables->getByName(_rUpdateTableName) >>= m_aUpdateTable; xTables->getByName(_rUpdateTableName) >>= m_aUpdateTable;
else else
xTables->getByName(xTables->getElementNames()[0]) >>= m_aUpdateTable; {
aUpdateTableName = xTables->getElementNames()[0];
xTables->getByName(aUpdateTableName) >>= m_aUpdateTable;
}
if(m_aUpdateTable.is()) if(m_aUpdateTable.is())
{ {
...@@ -190,19 +199,24 @@ ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs, ...@@ -190,19 +199,24 @@ ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs,
if(xColumnsSupplier.is()) if(xColumnsSupplier.is())
{ {
Reference<XNameAccess> xColumns = xColumnsSupplier->getColumns(); // first we need a connection
Reference< XStatement> xStmt(_xRs->getStatement(),UNO_QUERY);
Sequence< ::rtl::OUString> aNames(xColumns->getElementNames()); if(xStmt.is())
const ::rtl::OUString* pBegin = aNames.getConstArray(); xConnection = xStmt->getConnection();
const ::rtl::OUString* pEnd = pBegin + aNames.getLength(); else
{
Reference< XPreparedStatement> xPrepStmt(_xRs->getStatement(),UNO_QUERY);
xConnection = xPrepStmt->getConnection();
}
OSL_ENSURE(xConnection.is(),"No connection!");
Reference<XNameAccess> xColumns = xColumnsSupplier->getColumns();
Reference<XColumnsSupplier> xColSup(_xComposer,UNO_QUERY); Reference<XColumnsSupplier> xColSup(_xComposer,UNO_QUERY);
Reference<XNameAccess> xSelColumns = xColSup->getColumns(); Reference<XNameAccess> xSelColumns = xColSup->getColumns();
for(;pBegin != pEnd ;++pBegin)
{ OColumnNamePos aColumnNames(xConnection->getMetaData()->storesMixedCaseQuotedIdentifiers());
if(!(bAllKeysFound = xSelColumns->hasByName(*pBegin))) // found a column which is not refetched ::dbaccess::getColumnPositions(xSelColumns,xColumns,aUpdateTableName,aColumnNames);
break; bAllKeysFound = aColumnNames.size() == xColumns->getElementNames().getLength();
}
} }
} }
} }
...@@ -242,9 +256,38 @@ ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs, ...@@ -242,9 +256,38 @@ ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs,
} }
else else
{ {
m_pCacheSet = new OKeySet(_xRs,m_aUpdateTable,_xComposer); OColumnNamePos aColumnNames(xConnection->getMetaData()->storesMixedCaseQuotedIdentifiers());
Reference<XColumnsSupplier> xColSup(_xComposer,UNO_QUERY);
Reference<XNameAccess> xSelColumns = xColSup->getColumns();
Reference<XNameAccess> xColumns = m_aUpdateTable->getColumns();
::dbaccess::getColumnPositions(xSelColumns,xColumns,aUpdateTableName,aColumnNames);
// check privileges // check privileges
m_nPrivileges = Privilege::SELECT; m_nPrivileges = Privilege::SELECT;
sal_Bool bNoInsert = sal_False;
Sequence< ::rtl::OUString> aNames(xColumns->getElementNames());
const ::rtl::OUString* pBegin = aNames.getConstArray();
const ::rtl::OUString* pEnd = pBegin + aNames.getLength();
for(;pBegin != pEnd;++pBegin)
{
Reference<XPropertySet> xColumn;
xColumns->getByName(*pBegin) >>= xColumn;
OSL_ENSURE(xColumn.is(),"Column in table is null!");
if(xColumn.is())
{
sal_Int32 nNullable = 0;
xColumn->getPropertyValue(PROPERTY_ISNULLABLE) >>= nNullable;
if(nNullable == ColumnValue::NO_NULLS && aColumnNames.find(*pBegin) == aColumnNames.end())
{ // we found a column where null is not allowed so we can't insert new values
bNoInsert = sal_True;
break; // one column is enough
}
}
}
m_pCacheSet = new OKeySet(_xRs,m_aUpdateTable,aUpdateTableName ,_xComposer);
if(Reference<XResultSetUpdate>(_xRs,UNO_QUERY).is()) // this interface is optional so we have to check it if(Reference<XResultSetUpdate>(_xRs,UNO_QUERY).is()) // this interface is optional so we have to check it
{ {
Reference<XPropertySet> xTable(m_aUpdateTable,UNO_QUERY); Reference<XPropertySet> xTable(m_aUpdateTable,UNO_QUERY);
...@@ -256,6 +299,8 @@ ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs, ...@@ -256,6 +299,8 @@ ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs,
m_nPrivileges = Privilege::SELECT; m_nPrivileges = Privilege::SELECT;
} }
} }
if(bNoInsert)
m_nPrivileges |= ~Privilege::INSERT; // remove the insert privilege
} }
} }
...@@ -282,7 +327,7 @@ ORowSetCache::~ORowSetCache() ...@@ -282,7 +327,7 @@ ORowSetCache::~ORowSetCache()
delete m_pInsertMatrix; delete m_pInsertMatrix;
} }
m_xStatement = NULL; m_xStatement = NULL;
m_xSet = ::com::sun::star::uno::WeakReference< ::com::sun::star::sdbc::XResultSet>(); m_xSet = WeakReference< XResultSet>();
m_xMetaData = NULL; m_xMetaData = NULL;
m_aUpdateTable = NULL; m_aUpdateTable = NULL;
} }
...@@ -1714,9 +1759,13 @@ void ORowSetCache::setUpdateIterator(const ORowSetMatrix::iterator& _rOriginalRo ...@@ -1714,9 +1759,13 @@ void ORowSetCache::setUpdateIterator(const ORowSetMatrix::iterator& _rOriginalRo
for(;aIter != (*m_aInsertRow)->end();++aIter) for(;aIter != (*m_aInsertRow)->end();++aIter)
aIter->setModified(sal_False); aIter->setModified(sal_False);
} }
// -----------------------------------------------------------------------------
/*------------------------------------------------------------------------ /*------------------------------------------------------------------------
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.23 2001/01/26 15:18:17 oj
#83216# check if we stands after the last row after a next
Revision 1.22 2001/01/24 09:52:19 oj Revision 1.22 2001/01/24 09:52:19 oj
#82628# rowset modifications #82628# rowset modifications
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
* *
* $RCSfile: RowSetCache.hxx,v $ * $RCSfile: RowSetCache.hxx,v $
* *
* $Revision: 1.6 $ * $Revision: 1.7 $
* *
* last change: $Author: oj $ $Date: 2001-01-22 07:38:24 $ * last change: $Author: oj $ $Date: 2001-02-01 14:23:57 $
* *
* The Contents of this file are made available subject to the terms of * The Contents of this file are made available subject to the terms of
* either of the following licenses * either of the following licenses
...@@ -364,6 +364,9 @@ namespace dbaccess ...@@ -364,6 +364,9 @@ namespace dbaccess
/*------------------------------------------------------------------------ /*------------------------------------------------------------------------
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.6 2001/01/22 07:38:24 oj
#82632# change member
Revision 1.5 2000/10/17 10:18:12 oj Revision 1.5 2000/10/17 10:18:12 oj
some changes for the rowset some changes for the rowset
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment