Beispiel #1
0
ThemeParameters* ThemeParameters::Parse(const wchar_t* expressionString)
{
    // parse the expression and see if it consists of one of our theming functions
    FdoPtr<FdoExpression> expression;
    try
    {
        expression = FdoExpression::Parse(expressionString);
    }
    catch (FdoException* e)
    {
        ProcessStylizerException(e, __LINE__, __WFILE__);
    }

    FdoFunction* function = dynamic_cast<FdoFunction*>(expression.p);
    if (function != NULL)
    {
        FdoString* name = function->GetName();
        FdoPtr<FdoExpressionCollection> exprColl = function->GetArguments();

        if (_wcsicmp(name, L"lookup") == 0)
            return new LookupThemeParameters(exprColl);

        if (_wcsicmp(name, L"range") == 0)
            return new RangeThemeParameters(exprColl);
    }

    // not one of our functions
    return NULL;
}
//
// The TRIM function requires special processing.
void FdoRdbmsMySqlFilterProcessor::ProcessTrimFunction( FdoFunction& expr)
{
    // Append the function name and the opening bracket.
    ProcessFunctionName(expr);
	AppendString( "( " );

    // Process the arguments. This is were the special processing is required.
    // If the call includes an operator (BOTH, LEADING, TRAILING), it is required
    // to add a FROM clause after the operation keyword.
    FdoPtr<FdoExpressionCollection> exprCol = expr.GetArguments();
    for ( int i=0; i<exprCol->GetCount(); i++ )
    {
        FdoPtr<FdoExpression>exp = exprCol->GetItem( i );
        if ( (i == 0) && (IsDataValue( exp )) )
        {
            FdoDataValue *dataValue = (static_cast<FdoDataValue *>(exp.p) );
            if ( dataValue->GetDataType() == FdoDataType_String )
            {
                FdoStringValue *stringValue = static_cast<FdoStringValue *>(dataValue);
                AppendString( stringValue->GetString() );
                AppendString( " FROM " );	

            }
            else
                throw FdoFilterException::Create(NlsMsgGet(FDORDBMS_29, "Unsupported FDO type in expression"));
        }
        else
            HandleExpr( exp );
	}
    AppendString( " )" );
}
//
// The function checks whether or not the function has a correct set of arguments.
bool FdoRdbmsMySqlFilterProcessor::HasNativeSupportedFunctionArguments(FdoFunction& expr) const
{
    // If the function needs argument checking, execute the verification and return
    // the result back to the calling routine. Otherwise, the arguments are always 
    // deemed valid and the corresponding indication is returned.

    if (FdoCommonOSUtil::wcsicmp(L"STDDEV", expr.GetName()) == 0)
    {
        // The signatures for the function STDDEV allow an optional first
        // parameter that identifies the operation type (ALL, DISTINCT). In
        // MySQL this is not natively supported. Therefore, instead of sending
        // the request to MySQL it needs to be redirected to the Expression
        // Engine.
        // The following checks for the number of arguments. If there are two
        // arguments, the request needs to be redirected to the Expression
        // Engine. 
        return (expr.GetArguments()->GetCount() > 1) ? false : true;
    }

    if (FdoCommonOSUtil::wcsicmp(L"TRUNC", expr.GetName()) == 0)
    {
        // The signatures for the function TRUNC allow the truncation of date
        // and numeric data. If the input is data then the request cannot be
        // handled by MySQL as this is not supported. In this case the request
        // needs to be handed to the Expression Engine.
        // NOTE: The current implementation hands the request to the Expression
        //       Engine in all cases. This needs to be updated later.
        return false;
    }

    return true;;
}
void UnitTestProcessor::ProcessFunction(FdoFunction& expr)
{
    prependTabs();
    wprintf(L"Function : %s\n", expr.GetName());
    FdoExpressionCollection* pColl = expr.GetArguments();
    m_tabLevel++;
    for (FdoInt32 i = 0; i < pColl->GetCount(); i++)
    {
        FdoExpression*   pExpr;

        pExpr = pColl->GetItem(i);
        pExpr->Process(this);
        pExpr->Release();
    }
    m_tabLevel--;
    pColl->Release();
}
void FdoRdbmsMySqlFilterProcessor::ProcessToInt32Int64Function (FdoFunction& expr)
{
    // MySQL uses a different native function name for the expression functions
    // TOINT32, TOINT64. 
    AppendString(MYSQL_FUNCTION_TONUM);
    AppendString(OPEN_PARENTH);

    FdoPtr<FdoExpressionCollection> exprCol = expr.GetArguments();
    for(int i=0; i<exprCol->GetCount(); i++ )
    {
        if( i!= 0 )
            AppendString( L", " );

        FdoPtr<FdoExpression>exp = exprCol->GetItem( i );
        HandleExpr( exp );
    }

    // Add the keyword that performs the conversion and the closing bracket.
    AppendString( L", SIGNED)" );
}
void FdoRdbmsMySqlFilterProcessor::ProcessCurrentDateFunction (FdoFunction& expr)
{
    // MySQL uses a different native function name for the expression function
    // CurrentDate. 
    AppendString(MYSQL_FUNCTION_CURRENTDATE);
    AppendString(OPEN_PARENTH);

    // Note, that the function does not allow any arguments. However, if some
    // are given, they are added to the function call and it is left to MySQL
    // to deal with it.
    FdoPtr<FdoExpressionCollection> exprCol = expr.GetArguments();
    for(int i=0; i<exprCol->GetCount(); i++ )
    {
        if( i!= 0 )
            AppendString( L", " );

        FdoPtr<FdoExpression>exp = exprCol->GetItem( i );
        HandleExpr( exp );
    }
    AppendString( CLOSE_PARENTH );
}
//
// Aggregate functions require special processing because of the optional
// first parameter. The value of this parameter may be ALL or DISTINCT.
void FdoRdbmsMySqlFilterProcessor::ProcessAggregateFunction (FdoFunction& expr)
{
    // Append the function name and the opening bracket.
    ProcessFunctionName(expr);
	AppendString( "( " );

    // Process the arguments. This is were the special processing is required as
    // it is required to have the parameters listed sequencially without a comma
    // between them.
    FdoPtr<FdoExpressionCollection> exprCol = expr.GetArguments();
    for (int i=0; i<exprCol->GetCount(); i++)
    {
        FdoPtr<FdoExpression>exp = exprCol->GetItem(i);
        if ((i == 0) && (IsDataValue(exp)))
        {
            FdoDataValue *dataValue = (static_cast<FdoDataValue *>(exp.p));
            if (dataValue->GetDataType() == FdoDataType_String)
            {
                // Omit ALL if specified as this keyword is not supported in
                // MySQL.
                FdoStringValue *stringValue = static_cast<FdoStringValue *>(dataValue);
                FdoStringP strValue = stringValue->GetString();
                if (FdoCommonOSUtil::wcsicmp(strValue, L"ALL") != 0)
                {
                    AppendString(stringValue->GetString());
                    AppendString(L" ");	
                }
            }
            else
                throw FdoFilterException::Create(NlsMsgGet(FDORDBMS_29, "Unsupported FDO type in expression"));
        }
        else
            HandleExpr(exp);
	}
    AppendString(" )");
}
FdoRdbmsFeatureReader *FdoRdbmsSelectCommand::GetOptimizedFeatureReader( const FdoSmLpClassDefinition *classDefinition )
{

	// Verify if this is a special case we can optimize (no grouping filter,
	// and only aggregate functions Count() and/or SpatialExtents())
    FdoRdbmsFeatureReader *reader = NULL;
	bool        bOtherAggrSelected = false;
	aggr_list   *selAggrList = new aggr_list;

	if ( (classDefinition->GetClassType() == FdoClassType_FeatureClass ) && mIdentifiers && 
		!mGroupingCol)
	{
        for (int i = 0; i < mIdentifiers->GetCount() && !bOtherAggrSelected; i++ )
        {
			FdoPtr<FdoIdentifier> identifier = mIdentifiers->GetItem(i);
			FdoComputedIdentifier* computedIdentifier = dynamic_cast<FdoComputedIdentifier*>(identifier.p);
              
            if (computedIdentifier) 
            {
				FdoPtr<FdoExpression> expr = computedIdentifier->GetExpression();
                FdoFunction* func = dynamic_cast<FdoFunction*>(expr.p);

                if (func && 0==FdoCommonOSUtil::wcsicmp(func->GetName(), FDO_FUNCTION_SPATIALEXTENTS))
                {
					FdoPtr<FdoExpressionCollection> args = func->GetArguments();
                    FdoPtr<FdoExpression> arg = args->GetItem(0);
                    FdoIdentifier* argId = dynamic_cast<FdoIdentifier*>(arg.p);

					AggregateElement *id = new AggregateElement;
					id->propName = argId->GetName();
                    id->name = computedIdentifier->GetName();
                    id->type = FdoPropertyType_GeometricProperty;

                    selAggrList->push_back( id );
				}
                else if (func && 0 == FdoCommonOSUtil::wcsicmp(func->GetName(), FDO_FUNCTION_COUNT))
                {
                    // Only if the argument count for the function is 1 do some
                    // special handling.

                    FdoPtr<FdoExpressionCollection> exprArgColl = func->GetArguments();
                    if (exprArgColl->GetCount() == 1)
					{
                        AggregateElement *id = new AggregateElement;
					    id->name = computedIdentifier->GetName();
					    id->type = FdoPropertyType_DataProperty;

					    selAggrList->push_back( id );
                    }
                    else
                    {
                        bOtherAggrSelected = true;
                    }
                }
                else
                {
                    bOtherAggrSelected = true;
                }			
			}
		}
	}

	// Now perform the actual select aggregates and return the data reader:
	if ( !bOtherAggrSelected && ( selAggrList->size() > 0 ))
    {
		reader = mFdoConnection->GetOptimizedAggregateReader( classDefinition, selAggrList, GetFilterRef() ); // The reader takes ownership of the selAggrList
    }
    else
    {
		// Sorry, no optimization. Clean up.
        for ( size_t j = 0; j < selAggrList->size(); j++ )
			delete selAggrList->at(j);

        delete selAggrList;
    }

    return reader;
}