This commit is contained in:
Ocke Janssen [oj] 2010-02-15 10:24:00 +01:00
commit fd68260cab
19 changed files with 342 additions and 152 deletions

View file

@ -229,6 +229,15 @@ namespace dbtools
const ::rtl::OUString& _rName
);
/** returns the primary key columns of the table
*/
OOO_DLLPUBLIC_DBTOOLS ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess> getPrimaryKeyColumns_throw(
const ::com::sun::star::uno::Any& i_aTable
);
OOO_DLLPUBLIC_DBTOOLS ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess> getPrimaryKeyColumns_throw(
const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& i_xTable
);
/** get fields for a result set given by a "command descriptor"
<p>A command descriptor here means:

View file

@ -43,6 +43,7 @@
#include <map>
#include <memory>
#include <vector>
namespace connectivity
{
@ -50,6 +51,8 @@ namespace connectivity
class OSQLParseNode;
class OSQLParser;
typedef ::std::pair<const OSQLParseNode*,const OSQLParseNode* > TNodePair;
enum OSQLStatementType {
SQL_STATEMENT_UNKNOWN,
SQL_STATEMENT_SELECT,
@ -282,6 +285,10 @@ namespace connectivity
// tries to find the correct type of the function
sal_Int32 getFunctionReturnType(const OSQLParseNode* _pNode );
// returns a lis of all joined columns
::std::vector< TNodePair >& getJoinConditions() const;
private:
/** traverses the list of table names, and filles _rTables
*/
@ -354,6 +361,7 @@ namespace connectivity
{
m_aErrors = ::com::sun::star::sdbc::SQLException();
}
void impl_fillJoinConditions(const OSQLParseNode* i_pJoinCondition);
};
}

View file

@ -232,6 +232,8 @@ namespace connectivity
comparison_predicate_part_2,
parenthesized_boolean_value_expression,
character_string_type,
other_like_predicate_part_2,
between_predicate_part_2,
rule_count, // letzter_wert
UNKNOWN_RULE // ID indicating that a node is no rule with a matching Rule-enum value (see getKnownRuleID)
};

View file

@ -288,7 +288,7 @@ public class CRMDatabase
m_database.getDataSource().createQuery( "parseable", "SELECT * FROM \"customers\"" );
m_database.getDataSource().createQuery( "parseable native", "SELECT * FROM INFORMATION_SCHEMA.SYSTEM_VIEWS", false );
m_database.getDataSource().createQuery( "unparseable",
"SELECT CAST( \"ID\" AS VARCHAR(3) ) AS \"ID_VARCHAR\" FROM \"products\"", false );
"SELECT {fn DAYOFMONTH ('2001-01-01')} AS \"ID_VARCHAR\" FROM \"products\"", false );
validateUnparseable();
}

View file

@ -124,29 +124,7 @@ sdbcx::ObjectType OColumnsHelper::createObject(const ::rtl::OUString& _rName)
if ( pColDesc )
{
Reference<XPropertySet> xPr = m_pTable;
Reference<XKeysSupplier> xKeysSup(xPr,UNO_QUERY);
Reference<XNameAccess> xPrimaryKeyColumns;
if ( xKeysSup.is() )
{
const Reference<XIndexAccess> xKeys = xKeysSup->getKeys();
if ( xKeys.is() )
{
::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
const sal_Int32 nKeyCount = xKeys->getCount();
for(sal_Int32 nKeyIter = 0; nKeyIter < nKeyCount;++nKeyIter)
{
const Reference<XPropertySet> xKey(xKeys->getByIndex(nKeyIter),UNO_QUERY_THROW);
sal_Int32 nType = 0;
xKey->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPE)) >>= nType;
if ( nType == KeyType::PRIMARY )
{
const Reference<XColumnsSupplier> xColS(xKey,UNO_QUERY_THROW);
xPrimaryKeyColumns = xColS->getColumns();
break;
}
} // for(sal_Int32 nKeyIter = 0; nKeyIter < nKeyCount;++)
}
}
const Reference<XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(xPr);
sal_Int32 nField11 = pColDesc->nField11;
if ( nField11 != ColumnValue::NO_NULLS && xPrimaryKeyColumns.is() && xPrimaryKeyColumns->hasByName(_rName) )
{

View file

@ -63,8 +63,10 @@
#include <com/sun/star/sdbc/XRow.hpp>
#include <com/sun/star/sdbc/XRowSet.hpp>
#include <com/sun/star/sdbc/XRowUpdate.hpp>
#include <com/sun/star/sdbcx/KeyType.hpp>
#include <com/sun/star/sdbcx/Privilege.hpp>
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#include <com/sun/star/sdbcx/XKeysSupplier.hpp>
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/task/XInteractionRequest.hpp>
@ -531,6 +533,46 @@ Reference< XNameAccess> getTableFields(const Reference< XConnection>& _rxConn,co
Reference< XComponent > xDummy;
return getFieldsByCommandDescriptor( _rxConn, CommandType::TABLE, _rName, xDummy );
}
//------------------------------------------------------------------------------
Reference< XNameAccess> getPrimaryKeyColumns_throw(const Any& i_aTable)
{
const Reference< XPropertySet > xTable(i_aTable,UNO_QUERY_THROW);
return getPrimaryKeyColumns_throw(xTable);
}
//------------------------------------------------------------------------------
Reference< XNameAccess> getPrimaryKeyColumns_throw(const Reference< XPropertySet >& i_xTable)
{
Reference<XNameAccess> xKeyColumns;
const Reference<XKeysSupplier> xKeySup(i_xTable,UNO_QUERY);
if ( xKeySup.is() )
{
const Reference<XIndexAccess> xKeys = xKeySup->getKeys();
if ( xKeys.is() )
{
::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
const ::rtl::OUString sPropName = rPropMap.getNameByIndex(PROPERTY_ID_TYPE);
Reference<XPropertySet> xProp;
const sal_Int32 nCount = xKeys->getCount();
for(sal_Int32 i = 0;i< nCount;++i)
{
xProp.set(xKeys->getByIndex(i),UNO_QUERY_THROW);
if ( xProp.is() )
{
sal_Int32 nKeyType = 0;
xProp->getPropertyValue(sPropName) >>= nKeyType;
if(KeyType::PRIMARY == nKeyType)
{
const Reference<XColumnsSupplier> xKeyColsSup(xProp,UNO_QUERY_THROW);
xKeyColumns = xKeyColsSup->getColumns();
break;
}
}
}
}
}
return xKeyColumns;
}
//------------------------------------------------------------------------------
namespace
@ -2054,7 +2096,7 @@ namespace connectivity
void release(oslInterlockedCount& _refCount,
::cppu::OBroadcastHelper& rBHelper,
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface,
Reference< XInterface >& _xInterface,
::com::sun::star::lang::XComponent* _pObject)
{
if (osl_decrementInterlockedCount( &_refCount ) == 0)
@ -2064,7 +2106,7 @@ void release(oslInterlockedCount& _refCount,
if (!rBHelper.bDisposed && !rBHelper.bInDispose)
{
// remember the parent
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xParent;
Reference< XInterface > xParent;
{
::osl::MutexGuard aGuard( rBHelper.rMutex );
xParent = _xInterface;

View file

@ -534,28 +534,7 @@ Reference<XPropertySet> createSDBCXColumn(const Reference<XPropertySet>& _xTable
_xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= aSchema;
_xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= aTable;
Reference<XKeysSupplier> xKeysSup(_xTable,UNO_QUERY);
Reference<XNameAccess> xPrimaryKeyColumns;
if ( xKeysSup.is() )
{
const Reference<XIndexAccess> xKeys = xKeysSup->getKeys();
if ( xKeys.is() )
{
const sal_Int32 nKeyCount = xKeys->getCount();
for(sal_Int32 nKeyIter = 0; nKeyIter < nKeyCount;++nKeyIter)
{
const Reference<XPropertySet> xKey(xKeys->getByIndex(nKeyIter),UNO_QUERY_THROW);
sal_Int32 nType = 0;
xKey->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPE)) >>= nType;
if ( nType == KeyType::PRIMARY )
{
const Reference<XColumnsSupplier> xColS(xKey,UNO_QUERY_THROW);
xPrimaryKeyColumns = xColS->getColumns();
break;
}
} // for(sal_Int32 nKeyIter = 0; nKeyIter < nKeyCount;++)
}
}
Reference<XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(_xTable);
xProp = lcl_createSDBCXColumn(xPrimaryKeyColumns,_xConnection,aCatalog, aSchema, aTable, _rName,_rName,_bCase,_bQueryForInfo,_bIsAutoIncrement,_bIsCurrency,_nDataType);
if ( !xProp.is() )

View file

@ -381,15 +381,16 @@ EBookQuery *OCommonStatement::whereAnalysis( const OSQLParseNode* parseTree )
// SQL like
else if( SQL_ISRULE( parseTree, like_predicate ) )
{
ENSURE_OR_THROW( parseTree->count() >= 4, "unexpected like_predicate structure" );
ENSURE_OR_THROW( parseTree->count() == 2, "unexpected like_predicate structure" );
const OSQLParseNode* pPart2 = parseTree->getChild(1);
if( ! SQL_ISRULE( parseTree->getChild( 0 ), column_ref) )
m_pConnection->throwGenericSQLException(STR_QUERY_INVALID_LIKE_COLUMN,*this);
::rtl::OUString aColumnName( impl_getColumnRefColumnName_throw( *parseTree->getChild( 0 ) ) );
OSQLParseNode *pAtom = parseTree->getChild( parseTree->count() - 2 ); // Match String
bool bNotLike = parseTree->count() == 5;
OSQLParseNode *pAtom = pPart2->getChild( pPart2->count() - 2 ); // Match String
bool bNotLike = pPart2->getChild(0)->isToken();
if( !( pAtom->getNodeType() == SQL_NODE_STRING ||
pAtom->getNodeType() == SQL_NODE_NAME ||

View file

@ -291,17 +291,14 @@ OOperand* OPredicateCompiler::execute_COMPARE(OSQLParseNode* pPredicateNode) th
//------------------------------------------------------------------
OOperand* OPredicateCompiler::execute_LIKE(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
{
DBG_ASSERT(pPredicateNode->count() >= 4,"OFILECursor: Fehler im Parse Tree");
DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Fehler im Parse Tree");
const OSQLParseNode* pPart2 = pPredicateNode->getChild(1);
sal_Int32 ePredicateType;
sal_Unicode cEscape = L'\0';
if (pPredicateNode->count() == 5)
ePredicateType = SQLFilterOperator::NOT_LIKE;
else
ePredicateType = SQLFilterOperator::LIKE;
const bool bNotLike = pPart2->getChild(0)->isToken();
OSQLParseNode* pAtom = pPredicateNode->getChild(pPredicateNode->count()-2);
OSQLParseNode* pOptEscape = pPredicateNode->getChild(pPredicateNode->count()-1);
OSQLParseNode* pAtom = pPart2->getChild(pPredicateNode->count()-2);
OSQLParseNode* pOptEscape = pPart2->getChild(pPredicateNode->count()-1);
if (!(pAtom->getNodeType() == SQL_NODE_STRING || SQL_ISRULE(pAtom,parameter)))
{
@ -325,9 +322,9 @@ OOperand* OPredicateCompiler::execute_LIKE(OSQLParseNode* pPredicateNode) throw(
execute(pPredicateNode->getChild(0));
execute(pAtom);
OBoolOperator* pOperator = (ePredicateType == SQLFilterOperator::LIKE)
? new OOp_LIKE(cEscape)
: new OOp_NOTLIKE(cEscape);
OBoolOperator* pOperator = bNotLike
? new OOp_NOTLIKE(cEscape)
: new OOp_LIKE(cEscape);
m_aCodeList.push_back(pOperator);
return NULL;
@ -335,11 +332,12 @@ OOperand* OPredicateCompiler::execute_LIKE(OSQLParseNode* pPredicateNode) throw(
//------------------------------------------------------------------
OOperand* OPredicateCompiler::execute_BETWEEN(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
{
DBG_ASSERT(pPredicateNode->count() == 6,"OFILECursor: Fehler im Parse Tree");
DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Fehler im Parse Tree");
OSQLParseNode* pColumn = pPredicateNode->getChild(0);
OSQLParseNode* p1stValue = pPredicateNode->getChild(3);
OSQLParseNode* p2ndtValue = pPredicateNode->getChild(5);
const OSQLParseNode* pPart2 = pPredicateNode->getChild(1);
OSQLParseNode* p1stValue = pPart2->getChild(3);
OSQLParseNode* p2ndtValue = pPart2->getChild(5);
if (
!(p1stValue->getNodeType() == SQL_NODE_STRING || SQL_ISRULE(p1stValue,parameter))
@ -349,7 +347,7 @@ OOperand* OPredicateCompiler::execute_BETWEEN(OSQLParseNode* pPredicateNode) thr
m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_BETWEEN,NULL);
}
sal_Bool bNot = SQL_ISTOKEN(pPredicateNode->getChild(1),NOT);
sal_Bool bNot = SQL_ISTOKEN(pPart2->getChild(0),NOT);
OOperand* pColumnOp = execute(pColumn);
OOperand* pOb1 = execute(p1stValue);
@ -414,11 +412,12 @@ OOperand* OPredicateCompiler::execute_BETWEEN(OSQLParseNode* pPredicateNode) thr
//------------------------------------------------------------------
OOperand* OPredicateCompiler::execute_ISNULL(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
{
DBG_ASSERT(pPredicateNode->count() >= 3,"OFILECursor: Fehler im Parse Tree");
DBG_ASSERT(SQL_ISTOKEN(pPredicateNode->getChild(1),IS),"OFILECursor: Fehler im Parse Tree");
DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Fehler im Parse Tree");
const OSQLParseNode* pPart2 = pPredicateNode->getChild(1);
DBG_ASSERT(SQL_ISTOKEN(pPart2->getChild(0),IS),"OFILECursor: Fehler im Parse Tree");
sal_Int32 ePredicateType;
if (SQL_ISTOKEN(pPredicateNode->getChild(2),NOT))
if (SQL_ISTOKEN(pPart2->getChild(1),NOT))
ePredicateType = SQLFilterOperator::NOT_SQLNULL;
else
ePredicateType = SQLFilterOperator::SQLNULL;

View file

@ -188,12 +188,13 @@ KabCondition *KabCommonStatement::analyseWhereClause(const OSQLParseNode *pParse
}
}
}
else if (pParseNode->count() == 4)
else if (SQL_ISRULE(pParseNode, test_for_null) || SQL_ISRULE(pParseNode, like_predicate))
{
const OSQLParseNode *pLeft = pParseNode->getChild(0),
*pMiddleLeft = pParseNode->getChild(1),
*pMiddleRight = pParseNode->getChild(2),
*pRight = pParseNode->getChild(3);
const OSQLParseNode *pLeft = pParseNode->getChild(0);
const OSQLParseNode* pPart2 = pParseNode->getChild(1);
const OSQLParseNode *pMiddleLeft = pPart2->getChild(0),
*pMiddleRight = pPart2->getChild(1),
*pRight = pPart2->getChild(2);
if (SQL_ISRULE(pParseNode, test_for_null))
{

View file

@ -191,12 +191,13 @@ MacabCondition *MacabCommonStatement::analyseWhereClause(const OSQLParseNode *pP
}
}
}
else if (pParseNode->count() == 4)
else if (SQL_ISRULE(pParseNode, test_for_null) || SQL_ISRULE(pParseNode, like_predicate))
{
const OSQLParseNode *pLeft = pParseNode->getChild(0),
*pMiddleLeft = pParseNode->getChild(1),
*pMiddleRight = pParseNode->getChild(2),
*pRight = pParseNode->getChild(3);
const OSQLParseNode *pLeft = pParseNode->getChild(0);
const OSQLParseNode* pPart2 = pParseNode->getChild(1);
const OSQLParseNode *pMiddleLeft = pPart2->getChild(0),
*pMiddleRight = pPart2->getChild(1),
*pRight = pPart2->getChild(2);
if (SQL_ISRULE(pParseNode, test_for_null))
{

View file

@ -885,7 +885,7 @@ void OResultSet::analyseWhereClause( const OSQLParseNode* parseT
}
else if (SQL_ISRULE(parseTree,like_predicate))
{
OSL_ENSURE(parseTree->count() >= 4, "Error parsing LIKE predicate");
OSL_ENSURE(parseTree->count() == 2, "Error parsing LIKE predicate");
OSL_TRACE("analyseSQL : Got LIKE rule\n");
@ -898,9 +898,11 @@ void OResultSet::analyseWhereClause( const OSQLParseNode* parseT
OSQLParseNode *pColumn;
OSQLParseNode *pAtom;
OSQLParseNode *pOptEscape;
const OSQLParseNode* pPart2 = parseTree->getChild(1);
pColumn = parseTree->getChild(0); // Match Item
pAtom = parseTree->getChild(parseTree->count()-2); // Match String
pOptEscape = parseTree->getChild(parseTree->count()-1); // Opt Escape Rule
pAtom = pPart2->getChild(parseTree->count()-2); // Match String
pOptEscape = pPart2->getChild(parseTree->count()-1); // Opt Escape Rule
const bool bNot = SQL_ISTOKEN(pPart2->getChild(0), NOT);
if (!(pAtom->getNodeType() == SQL_NODE_STRING ||
pAtom->getNodeType() == SQL_NODE_NAME ||
@ -948,7 +950,7 @@ void OResultSet::analyseWhereClause( const OSQLParseNode* parseT
matchString.indexOf ( MATCHCHAR ) == -1 )
{
// Simple string , eg. "to match"
if ( parseTree->count() == 5 )
if ( bNot )
op = MQueryOp::DoesNotContain;
else
op = MQueryOp::Contains;
@ -964,12 +966,12 @@ void OResultSet::analyseWhereClause( const OSQLParseNode* parseT
matchString = matchString.replaceAt( 0, 1, rtl::OUString() );
matchString = matchString.replaceAt( matchString.getLength() -1 , 1, rtl::OUString() );
if ( parseTree->count() == 5 )
if (bNot)
op = MQueryOp::DoesNotContain;
else
op = MQueryOp::Contains;
}
else if ( parseTree->count() == 5 )
else if ( bNot )
{
// We currently can't handle a 'NOT LIKE' when there are '%' or
// '_' dispersed throughout
@ -1023,15 +1025,16 @@ void OResultSet::analyseWhereClause( const OSQLParseNode* parseT
}
else if (SQL_ISRULE(parseTree,test_for_null))
{
OSL_ENSURE(parseTree->count() >= 3,"Error in ParseTree");
OSL_ENSURE(SQL_ISTOKEN(parseTree->getChild(1),IS),"Error in ParseTree");
OSL_ENSURE(parseTree->count() == 2,"Error in ParseTree");
const OSQLParseNode* pPart2 = parseTree->getChild(1);
OSL_ENSURE(SQL_ISTOKEN(pPart2->getChild(0),IS),"Error in ParseTree");
if (!SQL_ISRULE(parseTree->getChild(0),column_ref))
{
m_pStatement->getOwnConnection()->throwSQLException( STR_QUERY_INVALID_IS_NULL_COLUMN, *this );
}
if (SQL_ISTOKEN(parseTree->getChild(2),NOT))
if (SQL_ISTOKEN(pPart2->getChild(1),NOT))
{
op = MQueryOp::Exists;
}

View file

@ -53,6 +53,10 @@
#include "diagnose_ex.h"
#include <rtl/logfile.hxx>
#define SQL_ISRULEOR2(pParseNode, e1,e2) ((pParseNode)->isRule() && (\
(pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e1) || \
(pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e2)))
using namespace ::comphelper;
using namespace ::connectivity;
using namespace ::connectivity::sdbcx;
@ -70,6 +74,7 @@ namespace connectivity
{
struct OSQLParseTreeIteratorImpl
{
::std::vector< TNodePair > m_aJoinConditions;
Reference< XConnection > m_xConnection;
Reference< XDatabaseMetaData > m_xDatabaseMetaData;
Reference< XNameAccess > m_xTableContainer;
@ -479,7 +484,42 @@ void OSQLParseTreeIterator::traverseOneTableName( OSQLTables& _rTables,const OSQ
if ( aTable.is() )
_rTables[ aTableRange ] = aTable;
}
//-----------------------------------------------------------------------------
void OSQLParseTreeIterator::impl_fillJoinConditions(const OSQLParseNode* i_pJoinCondition)
{
if (i_pJoinCondition->count() == 3 && // Ausdruck is geklammert
SQL_ISPUNCTUATION(i_pJoinCondition->getChild(0),"(") &&
SQL_ISPUNCTUATION(i_pJoinCondition->getChild(2),")"))
{
impl_fillJoinConditions(i_pJoinCondition->getChild(1));
}
else if (SQL_ISRULEOR2(i_pJoinCondition,search_condition,boolean_term) && // AND/OR-Verknuepfung:
i_pJoinCondition->count() == 3)
{
// nur AND Verknüpfung zulassen
if ( SQL_ISTOKEN(i_pJoinCondition->getChild(1),AND) )
{
impl_fillJoinConditions(i_pJoinCondition->getChild(0));
impl_fillJoinConditions(i_pJoinCondition->getChild(1));
}
}
else if (SQL_ISRULE(i_pJoinCondition,comparison_predicate))
{
// only the comparison of columns is allowed
OSL_ENSURE(i_pJoinCondition->count() == 3,"OQueryDesignView::InsertJoinConnection: Fehler im Parse Tree");
if (SQL_ISRULE(i_pJoinCondition->getChild(0),column_ref) &&
SQL_ISRULE(i_pJoinCondition->getChild(2),column_ref) &&
i_pJoinCondition->getChild(1)->getNodeType() == SQL_NODE_EQUAL)
{
m_pImpl->m_aJoinConditions.push_back( TNodePair(i_pJoinCondition->getChild(0),i_pJoinCondition->getChild(2)) );
}
}
}
//-----------------------------------------------------------------------------
::std::vector< TNodePair >& OSQLParseTreeIterator::getJoinConditions() const
{
return m_pImpl->m_aJoinConditions;
}
//-----------------------------------------------------------------------------
void OSQLParseTreeIterator::getQualified_join( OSQLTables& _rTables, const OSQLParseNode *pTableRef, ::rtl::OUString& aTableRange )
{
@ -494,8 +534,30 @@ void OSQLParseTreeIterator::getQualified_join( OSQLTables& _rTables, const OSQLP
traverseOneTableName( _rTables, pNode, aTableRange );
sal_uInt32 nPos = 4;
if(SQL_ISRULE(pTableRef,cross_union) || pTableRef->getChild(1)->getTokenID() != SQL_TOKEN_NATURAL)
if( SQL_ISRULE(pTableRef,cross_union) || pTableRef->getChild(1)->getTokenID() != SQL_TOKEN_NATURAL)
{
nPos = 3;
// join_condition,named_columns_join
if ( SQL_ISRULE( pTableRef, qualified_join ) )
{
const OSQLParseNode* pJoin_spec = pTableRef->getChild(4);
if ( SQL_ISRULE( pJoin_spec, join_condition ) )
{
impl_fillJoinConditions(pJoin_spec->getChild(1));
}
else
{
const OSQLParseNode* pColumnCommalist = pJoin_spec->getChild(2);
// Alle Columns in der column_commalist ...
for (sal_uInt32 i = 0; i < pColumnCommalist->count(); i++)
{
const OSQLParseNode * pCol = pColumnCommalist->getChild(i);
// add twice because the column must exists in both tables
m_pImpl->m_aJoinConditions.push_back( TNodePair(pCol,pCol) );
}
}
}
}
pNode = getTableNode(_rTables,pTableRef->getChild(nPos),aTableRange);
if ( isTableNode( pNode ) )
@ -1118,17 +1180,17 @@ void OSQLParseTreeIterator::traverseParameters(const OSQLParseNode* _pNode)
else
pOther->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
} // if ( SQL_ISRULE(pParent,comparison_predicate) ) // x = X
else if ( SQL_ISRULE(pParent,like_predicate) )
else if ( SQL_ISRULE(pParent,other_like_predicate_part_2) )
{
const OSQLParseNode* pOther = pParent->getChild(0);
const OSQLParseNode* pOther = pParent->getParent()->getChild(0);
if ( SQL_ISRULE( pOther, column_ref ) )
getColumnRange( pOther, sColumnName, sTableRange, aColumnAlias);
else
pOther->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
}
else if ( SQL_ISRULE(pParent,between_predicate) )
else if ( SQL_ISRULE(pParent,between_predicate_part_2) )
{
const OSQLParseNode* pOther = pParent->getChild(0);
const OSQLParseNode* pOther = pParent->getParent()->getChild(0);
if ( SQL_ISRULE( pOther, column_ref ) )
getColumnRange( pOther, sColumnName, sTableRange, aColumnAlias);
else
@ -1307,17 +1369,19 @@ void OSQLParseTreeIterator::traverseANDCriteria(OSQLParseNode * pSearchCondition
::rtl::OUString aValue;
pSearchCondition->getChild(2)->parseNodeToStr( aValue, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
traverseOnePredicate(pSearchCondition->getChild(0),aValue,pSearchCondition->getChild(2));
impl_fillJoinConditions(pSearchCondition);
// if (! aIteratorStatus.IsSuccessful())
// return;
}
else if (SQL_ISRULE(pSearchCondition,like_predicate) /*&& SQL_ISRULE(pSearchCondition->getChild(0),column_ref)*/)
{
OSL_ENSURE(pSearchCondition->count() >= 4,"OSQLParseTreeIterator: error in parse tree!");
OSL_ENSURE(pSearchCondition->count() == 2,"OSQLParseTreeIterator: error in parse tree!");
const OSQLParseNode* pPart2 = pSearchCondition->getChild(1);
sal_Int32 nCurentPos = pSearchCondition->count()-2;
sal_Int32 nCurentPos = pPart2->count()-2;
OSQLParseNode * pNum_value_exp = pSearchCondition->getChild(nCurentPos);
OSQLParseNode * pOptEscape = pSearchCondition->getChild(nCurentPos+1);
OSQLParseNode * pNum_value_exp = pPart2->getChild(nCurentPos);
OSQLParseNode * pOptEscape = pPart2->getChild(nCurentPos+1);
OSL_ENSURE(pNum_value_exp != NULL,"OSQLParseTreeIterator: error in parse tree!");
OSL_ENSURE(pOptEscape != NULL,"OSQLParseTreeIterator: error in parse tree!");
@ -1347,12 +1411,13 @@ void OSQLParseTreeIterator::traverseANDCriteria(OSQLParseNode * pSearchCondition
}
else if (SQL_ISRULE(pSearchCondition,in_predicate))
{
OSL_ENSURE(pSearchCondition->count() == 4,"OSQLParseTreeIterator: error in parse tree!");
OSL_ENSURE(pSearchCondition->count() == 2,"OSQLParseTreeIterator: error in parse tree!");
const OSQLParseNode* pPart2 = pSearchCondition->getChild(1);
traverseORCriteria(pSearchCondition->getChild(0));
// if (! aIteratorStatus.IsSuccessful()) return;
OSQLParseNode* pChild = pSearchCondition->getChild(3);
OSQLParseNode* pChild = pPart2->getChild(2);
if ( SQL_ISRULE(pChild->getChild(0),subquery) )
{
traverseTableNames( *m_pImpl->m_pSubTables );
@ -1370,8 +1435,9 @@ void OSQLParseTreeIterator::traverseANDCriteria(OSQLParseNode * pSearchCondition
}
else if (SQL_ISRULE(pSearchCondition,test_for_null) /*&& SQL_ISRULE(pSearchCondition->getChild(0),column_ref)*/)
{
OSL_ENSURE(pSearchCondition->count() >= 3,"OSQLParseTreeIterator: error in parse tree!");
OSL_ENSURE(SQL_ISTOKEN(pSearchCondition->getChild(1),IS),"OSQLParseTreeIterator: error in parse tree!");
OSL_ENSURE(pSearchCondition->count() == 2,"OSQLParseTreeIterator: error in parse tree!");
const OSQLParseNode* pPart2 = pSearchCondition->getChild(1);
OSL_ENSURE(SQL_ISTOKEN(pPart2->getChild(0),IS),"OSQLParseTreeIterator: error in parse tree!");
::rtl::OUString aString;
traverseOnePredicate(pSearchCondition->getChild(0),aString,NULL);
@ -1430,7 +1496,14 @@ void OSQLParseTreeIterator::traverseParameter(const OSQLParseNode* _pParseNode
{// found a function as column_ref
::rtl::OUString sFunctionName;
_pColumnRef->getChild(0)->parseNodeToStr( sFunctionName, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
sal_Int32 nType = ::connectivity::OSQLParser::getFunctionReturnType( sFunctionName, &m_rParser.getContext() );
const sal_uInt32 nCount = _pColumnRef->count();
sal_uInt32 i = 0;
for(; i < nCount;++i)
{
if ( _pColumnRef->getChild(i) == _pParseNode )
break;
}
sal_Int32 nType = ::connectivity::OSQLParser::getFunctionParameterType( _pColumnRef->getParent()->getChild(0)->getTokenID(), i+1);
OParseColumn* pColumn = new OParseColumn( sParameterName,
::rtl::OUString(),

View file

@ -680,7 +680,7 @@ void OSQLParseNode::impl_parseTableRangeNodeToString_throw(::rtl::OUStringBuffer
void OSQLParseNode::impl_parseLikeNodeToString_throw( ::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam ) const
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::impl_parseLikeNodeToString_throw" );
OSL_ENSURE(count() >= 4,"count != 5: Prepare for GPF");
OSL_ENSURE(count() == 2,"count != 2: Prepare for GPF");
const OSQLParseNode* pEscNode = NULL;
const OSQLParseNode* pParaNode = NULL;
@ -717,13 +717,14 @@ void OSQLParseNode::impl_parseLikeNodeToString_throw( ::rtl::OUStringBuffer& rSt
if (bAddName)
m_aChildren[0]->impl_parseNodeToString_throw( rString, aNewParam );
m_aChildren[1]->impl_parseNodeToString_throw( rString, aNewParam );
if(count() == 5)
m_aChildren[2]->impl_parseNodeToString_throw( rString, aNewParam );
const OSQLParseNode* pPart2 = m_aChildren[1];
pPart2->getChild(1)->impl_parseNodeToString_throw( rString, aNewParam );
if (SQL_ISTOKEN(pPart2->getChild(0), NOT))
pPart2->getChild(2)->impl_parseNodeToString_throw( rString, aNewParam );
sal_Int32 nCurentPos = m_aChildren.size()-2;
pParaNode = m_aChildren[nCurentPos];
pEscNode = m_aChildren[nCurentPos+1];
sal_Int32 nCurentPos = pPart2->count() - 2;
pParaNode = pPart2->getChild(nCurentPos);
pEscNode = pPart2->getChild(nCurentPos+1);
if (pParaNode->isToken())
{
@ -1428,7 +1429,9 @@ OSQLParser::OSQLParser(const ::com::sun::star::uno::Reference< ::com::sun::star:
{ OSQLParseNode::bit_value_fct, "bit_value_fct" },
{ OSQLParseNode::comparison_predicate_part_2, "comparison_predicate_part_2" },
{ OSQLParseNode::parenthesized_boolean_value_expression, "parenthesized_boolean_value_expression" },
{ OSQLParseNode::character_string_type, "character_string_type" }
{ OSQLParseNode::character_string_type, "character_string_type" },
{ OSQLParseNode::other_like_predicate_part_2, "other_like_predicate_part_2" },
{ OSQLParseNode::between_predicate_part_2, "between_predicate_part_2" }
};
size_t nRuleMapCount = sizeof( aRuleDescriptions ) / sizeof( aRuleDescriptions[0] );
OSL_ENSURE( nRuleMapCount == size_t( OSQLParseNode::rule_count ), "OSQLParser::OSQLParser: added a new rule? Adjust this map!" );
@ -1990,39 +1993,34 @@ void OSQLParseNode::negateSearchCondition(OSQLParseNode*& pSearchCondition,sal_B
else if(bNegate && (SQL_ISRULE(pSearchCondition,test_for_null) || SQL_ISRULE(pSearchCondition,in_predicate) ||
SQL_ISRULE(pSearchCondition,between_predicate) || SQL_ISRULE(pSearchCondition,boolean_test) ))
{
OSQLParseNode* pPart2 = pSearchCondition;
if ( !SQL_ISRULE(pSearchCondition,boolean_test) )
pPart2 = pSearchCondition->getChild(1);
sal_uInt32 nNotPos = 0;
// row_value_constructor not SQL_TOKEN_IN in_predicate_value
// row_value_constructor not SQL_TOKEN_BETWEEN row_value_constructor SQL_TOKEN_AND row_value_constructor
if ( SQL_ISRULE( pSearchCondition, in_predicate )
|| SQL_ISRULE( pSearchCondition, between_predicate )
)
if ( SQL_ISRULE( pSearchCondition, test_for_null ) )
nNotPos = 1;
// row_value_constructor SQL_TOKEN_IS not SQL_TOKEN_NULL
// boolean_primary SQL_TOKEN_IS not truth_value
else if ( SQL_ISRULE( pSearchCondition, test_for_null )
|| SQL_ISRULE( pSearchCondition, boolean_test )
)
else if ( SQL_ISRULE( pSearchCondition, boolean_test ) )
nNotPos = 2;
OSQLParseNode* pNot = pSearchCondition->getChild(nNotPos);
OSQLParseNode* pNot = pPart2->getChild(nNotPos);
OSQLParseNode* pNotNot = NULL;
if(pNot->isRule())
pNotNot = new OSQLParseNode(::rtl::OUString::createFromAscii("NOT"),SQL_NODE_KEYWORD,SQL_TOKEN_NOT);
else
pNotNot = new OSQLParseNode(::rtl::OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::sql_not));
pSearchCondition->replace(pNot, pNotNot);
pPart2->replace(pNot, pNotNot);
delete pNot;
}
else if(bNegate && (SQL_ISRULE(pSearchCondition,like_predicate)))
{
OSQLParseNode* pCheckForNOT = pSearchCondition->getChild( 1 );
if ( SQL_ISTOKEN(pCheckForNOT,NOT) )
delete pSearchCondition->removeAt( 1 );
OSQLParseNode* pNot = pSearchCondition->getChild( 1 )->getChild( 0 );
OSQLParseNode* pNotNot = NULL;
if(pNot->isRule())
pNotNot = new OSQLParseNode(::rtl::OUString::createFromAscii("NOT"),SQL_NODE_KEYWORD,SQL_TOKEN_NOT);
else
{
OSQLParseNode* pNot = new OSQLParseNode( ::rtl::OUString::createFromAscii( "NOT" ), SQL_NODE_KEYWORD, SQL_TOKEN_NOT );
pSearchCondition->insert( 1, pNot );
}
pNotNot = new OSQLParseNode(::rtl::OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::sql_not));
pSearchCondition->getChild( 1 )->replace(pNot, pNotNot);
delete pNot;
}
}
//-----------------------------------------------------------------------------

View file

@ -32,6 +32,8 @@
#include <tools/list.hxx>
#include <com/sun/star/sdbc/XRowSet.hpp>
#include <com/sun/star/sdbc/XRowSetListener.hpp>
#include <com/sun/star/sdb/XRowsChangeListener.hpp>
#include <com/sun/star/beans/PropertyChangeEvent.hpp>
#include <com/sun/star/util/XNumberFormatter.hpp>
#include <com/sun/star/util/Date.hpp>
@ -250,6 +252,8 @@ private:
// For that reason we have to listen to some properties of our data source.
::comphelper::OPropertyChangeMultiplexer* m_pDataSourcePropMultiplexer;
FmXGridSourcePropListener* m_pDataSourcePropListener;
::com::sun::star::uno::Reference< ::com::sun::star::sdb::XRowsChangeListener>
m_xRowSetListener; // get notification when rows were changed
void* m_pFieldListeners;
// property listeners for field values
@ -526,15 +530,20 @@ public:
void setGridListener( FmGridListener* _pListener ) { m_pGridListener = _pListener; }
// helper class to grant access to selected methods from within the DbCellControl class
struct GrantCellControlAccess
struct GrantControlAccess
{
friend class DbCellControl;
friend class RowSetEventListener;
protected:
GrantCellControlAccess() { }
GrantControlAccess() { }
};
/// called when a controller needs to be re-initialized
void refreshController(sal_uInt16 _nColId, GrantCellControlAccess _aAccess);
void refreshController(sal_uInt16 _nColId, GrantControlAccess _aAccess);
CursorWrapper* GetSeekCursor(GrantControlAccess /*_aAccess*/) const { return m_pSeekCursor; }
const DbGridRowRef& GetSeekRow(GrantControlAccess /*_aAccess*/) const { return m_xSeekRow; }
void SetSeekPos(sal_Int32 nPos,GrantControlAccess /*_aAccess*/) {m_nSeekPos = nPos;}
/**
@return
@ -589,6 +598,7 @@ protected:
const DbGridRowRef& GetPaintRow() const { return m_xPaintRow; }
CursorWrapper* GetSeekCursor() const { return m_pSeekCursor; }
void ConnectToFields();
void DisconnectFromFields();

View file

@ -1741,11 +1741,12 @@ void FmGridControl::InitColumnByField(
_pColumn->SetObject( (sal_Int16)nFieldPos );
return;
}
/*
// handle readonly columns
sal_Bool bReadOnly = sal_True;
xField->getPropertyValue( FM_PROP_ISREADONLY ) >>= bReadOnly;
_pColumn->SetReadOnly( bReadOnly );
*/
}
// the control type is determined by the ColumnServiceName

View file

@ -557,6 +557,7 @@ TYPEINIT1( DbFilterField, DbCellControl )
//------------------------------------------------------------------------------
DbCellControl::DbCellControl( DbGridColumn& _rColumn, sal_Bool /*_bText*/ )
:OPropertyChangeListener(m_aMutex)
,m_pFieldChangeBroadcaster(NULL)
,m_bTransparent( sal_False )
,m_bAlignedController( sal_True )
,m_bAccessingValueProperty( sal_False )
@ -580,6 +581,31 @@ DbCellControl::DbCellControl( DbGridColumn& _rColumn, sal_Bool /*_bText*/ )
implDoPropertyListening( FM_PROP_STATE, sal_False );
implDoPropertyListening( FM_PROP_TEXT, sal_False );
implDoPropertyListening( FM_PROP_EFFECTIVE_VALUE, sal_False );
// be listener at the bound field as well
try
{
Reference< XPropertySet > xColModelProps( m_rColumn.getModel(), UNO_QUERY );
Reference< XPropertySetInfo > xPSI;
if ( xColModelProps.is() )
xPSI = xColModelProps->getPropertySetInfo();
if ( xPSI.is() && xPSI->hasPropertyByName( FM_PROP_BOUNDFIELD ) )
{
Reference< XPropertySet > xField;
xColModelProps->getPropertyValue( FM_PROP_BOUNDFIELD ) >>= xField;
if ( xField.is() )
{
m_pFieldChangeBroadcaster = new ::comphelper::OPropertyChangeMultiplexer(this, xField);
m_pFieldChangeBroadcaster->acquire();
m_pFieldChangeBroadcaster->addProperty( FM_PROP_ISREADONLY );
}
}
}
catch( const Exception& )
{
DBG_ERROR( "DbCellControl::doPropertyListening: caught an exception!" );
}
}
}
@ -611,17 +637,22 @@ void DbCellControl::doPropertyListening( const ::rtl::OUString& _rPropertyName )
{
implDoPropertyListening( _rPropertyName );
}
//------------------------------------------------------------------------------
void lcl_clearBroadCaster(::comphelper::OPropertyChangeMultiplexer*& _pBroadcaster)
{
if ( _pBroadcaster )
{
_pBroadcaster->dispose();
_pBroadcaster->release();
_pBroadcaster = NULL;
// no delete, this is done implicitly
}
}
//------------------------------------------------------------------------------
DbCellControl::~DbCellControl()
{
if ( m_pModelChangeBroadcaster )
{
m_pModelChangeBroadcaster->dispose();
m_pModelChangeBroadcaster->release();
m_pModelChangeBroadcaster = NULL;
// no delete, this is done implicitly
}
lcl_clearBroadCaster(m_pModelChangeBroadcaster);
lcl_clearBroadCaster(m_pFieldChangeBroadcaster);
delete m_pWindow;
delete m_pPainter;
@ -666,7 +697,14 @@ void DbCellControl::_propertyChanged(const PropertyChangeEvent& _rEvent) throw(R
}
else if ( _rEvent.PropertyName.equals( FM_PROP_READONLY ) )
{
implAdjustReadOnly( xSourceProps );
implAdjustReadOnly( xSourceProps, true);
}
else if ( _rEvent.PropertyName.equals( FM_PROP_ISREADONLY ) )
{
sal_Bool bReadOnly = sal_True;
_rEvent.NewValue >>= bReadOnly;
m_rColumn.SetReadOnly(bReadOnly);
implAdjustReadOnly( xSourceProps, false);
}
else if ( _rEvent.PropertyName.equals( FM_PROP_ENABLED ) )
{
@ -804,7 +842,7 @@ void DbCellControl::ImplInitWindow( Window& rParent, const InitWindowFacet _eIni
}
//------------------------------------------------------------------------------
void DbCellControl::implAdjustReadOnly( const Reference< XPropertySet >& _rxModel )
void DbCellControl::implAdjustReadOnly( const Reference< XPropertySet >& _rxModel,bool i_bReadOnly )
{
DBG_ASSERT( m_pWindow, "DbCellControl::implAdjustReadOnly: not to be called without window!" );
DBG_ASSERT( _rxModel.is(), "DbCellControl::implAdjustReadOnly: invalid model!" );
@ -813,9 +851,12 @@ void DbCellControl::implAdjustReadOnly( const Reference< XPropertySet >& _rxMode
Edit* pEditWindow = dynamic_cast< Edit* >( m_pWindow );
if ( pEditWindow )
{
sal_Bool bReadOnly = sal_True;
_rxModel->getPropertyValue( FM_PROP_READONLY ) >>= bReadOnly;
static_cast< Edit* >( m_pWindow )->SetReadOnly( m_rColumn.IsReadOnly() || bReadOnly );
sal_Bool bReadOnly = m_rColumn.IsReadOnly();
if ( !bReadOnly )
{
_rxModel->getPropertyValue( i_bReadOnly ? FM_PROP_READONLY : FM_PROP_ISREADONLY) >>= bReadOnly;
}
static_cast< Edit* >( m_pWindow )->SetReadOnly( bReadOnly );
}
}
}
@ -852,7 +893,7 @@ void DbCellControl::Init( Window& rParent, const Reference< XRowSet >& _rxCursor
if ( xModelPSI->hasPropertyByName( FM_PROP_READONLY ) )
{
implAdjustReadOnly( xModel );
implAdjustReadOnly( xModel,true );
}
if ( xModelPSI->hasPropertyByName( FM_PROP_ENABLED ) )
@ -1009,7 +1050,7 @@ double DbCellControl::GetValue(const Reference< ::com::sun::star::sdb::XColumn >
//------------------------------------------------------------------------------
void DbCellControl::invalidatedController()
{
m_rColumn.GetParent().refreshController(m_rColumn.GetId(), DbGridControl::GrantCellControlAccess());
m_rColumn.GetParent().refreshController(m_rColumn.GetId(), DbGridControl::GrantControlAccess());
}
/*************************************************************************/

View file

@ -47,6 +47,8 @@
#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
#include <com/sun/star/accessibility/XAccessible.hpp>
#include <com/sun/star/sdb/XResultSetAccess.hpp>
#include <com/sun/star/sdb/RowChangeAction.hpp>
#include <com/sun/star/sdb/XRowsChangeBroadcaster.hpp>
#include <com/sun/star/sdbc/XResultSetUpdate.hpp>
#include <com/sun/star/sdbcx/Privilege.hpp>
#include <com/sun/star/container/XChild.hpp>
@ -105,6 +107,39 @@ using namespace com::sun::star::accessibility;
| BROWSER_VLINESFULL \
| BROWSER_HEADERBAR_NEW \
class RowSetEventListener : public ::cppu::WeakImplHelper1<XRowsChangeListener>
{
DbGridControl* m_pControl;
public:
RowSetEventListener(DbGridControl* i_pControl) : m_pControl(i_pControl)
{
}
private:
// XEventListener
virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& /*i_aEvt*/)
{
}
virtual void SAL_CALL rowsChanged(const ::com::sun::star::sdb::RowsChangeEvent& i_aEvt)
{
if ( i_aEvt.Action == RowChangeAction::UPDATE )
{
::DbGridControl::GrantControlAccess aAccess;
CursorWrapper* pSeek = m_pControl->GetSeekCursor(aAccess);
const DbGridRowRef& rSeekRow = m_pControl->GetSeekRow(aAccess);
const Any* pIter = i_aEvt.Bookmarks.getConstArray();
const Any* pEnd = pIter + i_aEvt.Bookmarks.getLength();
for(;pIter != pEnd;++pIter)
{
pSeek->moveToBookmark(*pIter);
// get the data
rSeekRow->SetState(pSeek, sal_True);
sal_Int32 nSeekPos = pSeek->getRow() - 1;
m_pControl->SetSeekPos(nSeekPos,aAccess);
m_pControl->RowModified(nSeekPos);
}
}
}
};
//==============================================================================
class GridFieldValueListener;
@ -990,6 +1025,7 @@ DbGridControl::~DbGridControl()
m_pDataSourcePropMultiplexer = NULL;
m_pDataSourcePropListener = NULL;
}
m_xRowSetListener.clear();
delete m_pDataCursor;
delete m_pSeekCursor;
@ -1380,7 +1416,7 @@ sal_Bool DbGridControl::IsPermanentCursorEnabled() const
}
//------------------------------------------------------------------------------
void DbGridControl::refreshController(sal_uInt16 _nColId, GrantCellControlAccess /*_aAccess*/)
void DbGridControl::refreshController(sal_uInt16 _nColId, GrantControlAccess /*_aAccess*/)
{
if ((GetCurColumnId() == _nColId) && IsEditing())
{ // the controller which is currently active needs to be refreshed
@ -1415,6 +1451,7 @@ void DbGridControl::setDataSource(const Reference< XRowSet >& _xCursor, sal_uInt
m_pDataSourcePropMultiplexer = NULL;
m_pDataSourcePropListener = NULL;
}
m_xRowSetListener.clear();
// is the new cursor valid ?
// the cursor is only valid if it contains some columns
@ -1506,7 +1543,7 @@ void DbGridControl::setDataSource(const Reference< XRowSet >& _xCursor, sal_uInt
Reference< XPropertySet > xSet(_xCursor, UNO_QUERY);
if (xSet.is())
{
// feststellen welche Updatem<EFBFBD>glichkeiten bestehen
// feststellen welche Updatemoeglichkeiten bestehen
sal_Int32 nConcurrency = ResultSetConcurrency::READ_ONLY;
xSet->getPropertyValue(FM_PROP_RESULTSET_CONCURRENCY) >>= nConcurrency;
@ -1568,6 +1605,12 @@ void DbGridControl::setDataSource(const Reference< XRowSet >& _xCursor, sal_uInt
xSet->getPropertyValue(FM_PROP_ROWCOUNT) >>= nRecordCount;
m_bRecordCountFinal = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ROWCOUNTFINAL));
m_xRowSetListener = new RowSetEventListener(this);
Reference< XRowsChangeBroadcaster> xChangeBroad(xSet,UNO_QUERY);
if ( xChangeBroad.is( ) )
xChangeBroad->addRowsChangeListener(m_xRowSetListener);
// insert the currently known rows
// and one row if we are able to insert rows
if (m_nOptions & OPT_INSERT)

View file

@ -222,6 +222,7 @@ class DbCellControl
{
private:
::comphelper::OPropertyChangeMultiplexer* m_pModelChangeBroadcaster;
::comphelper::OPropertyChangeMultiplexer* m_pFieldChangeBroadcaster;
private:
sal_Bool m_bTransparent : 1;
@ -351,7 +352,7 @@ private:
void implDoPropertyListening( const ::rtl::OUString& _rPropertyName, sal_Bool _bWarnIfNotExistent = sal_True );
/// updates the "readonly" setting on m_pWindow, according to the respective property value in the given model
void implAdjustReadOnly( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxModel );
void implAdjustReadOnly( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxModel,bool i_bReadOnly );
/// updates the "enabled" setting on m_pWindow, according to the respective property value in the given model
void implAdjustEnabled( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxModel );