Automated merge with http://hg.services.openoffice.org/cws/dba33f
This commit is contained in:
commit
fd68260cab
19 changed files with 342 additions and 152 deletions
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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) )
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() )
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in a new issue