{{{ }}} = FDO RFC 17 - Add a Managed API for the FDO Expression Engine = This page contains a request for comments document (RFC) for the FDO Open Source project. More FDO RFCs can be found on the [wiki:FDORfcs RFCs] page. == Status == ||RFC Template Version||(1.0)|| ||Submission Date||March 20, 2008|| ||Last Modified|| Greg Boone [[Timestamp]]|| ||Author||Greg Boone|| ||RFC Status||Deferred|| ||Implementation Status||Under Consideration|| ||Proposed Milestone||3.4.0.0 || ||Assigned PSC guide(s)|| Greg Boone|| ||'''Voting History'''||TBD|| ||+1|| || ||+0|| || ||-0|| || ||-1|| || == Overview == The purpose of this RFC is to determine if there is a need to design and add a Managed API for the FDO Expression Engine. == Motivation == The Unmanaged FDO Expression Engine has a set of unmanaged interfaces but does not have a corresponding managed set of interfaces. The general rule has been that if an unmanaged component of the API is released in the SDK for external use, it should have a corresponding managed API as well. == Proposed Solution == The following shows the proposed additions for the Managed API === Expression Engine === {{{ public __gc class OSGeo::FDO::Utilities::ExpressionEngine::ExpressionEngine : public OSGeo::Runtime::Disposable { public: /// \brief /// Constructs an instance of an ExpressionEngine /// /// \param reader /// Input FDO feature reader /// /// \param classDef /// Input FDO class definition /// /// \param userDefinedFunctions /// Input User defined functions /// ExpressionEngine(OSGeo::FDO::Commands::Feature::IReader* reader, OSGeo::FDO::Schema::ClassDefinition* classDef, OSGeo::FDO::Utilities::ExpressionEngine::FunctionCollection* userDefinedFunctions); /// \brief /// Constructs an instance of an ExpressionException. /// /// \param reader /// Input reader /// /// \param classDef /// Input class definition /// /// \param classDef /// Input identifiers /// /// \param userDefinedFunctions /// Input user defined functions /// /// \return /// Returns ExpressionEngine /// ExpressionEngine(OSGeo::FDO::Commands::Feature::IReader* reader, OSGeo::FDO::Schema::ClassDefinition* classDef, OSGeo::FDO::Commands::IdentifierCollection* identifiers, OSGeo::FDO::Utilities::ExpressionEngine::FunctionCollection* userDefinedFunctions); /// \brief /// Evaluates an expression /// /// \param expression /// Input expression /// /// \return /// Returns a literal value. This value is valid until the next Evaluate call /// OSGeo::FDO::Expression::LiteralValue* Evaluate(OSGeo::FDO::Expression::Expression* expression); /// \brief /// Evaluates a name /// /// \param name /// Input identifier /// /// \return /// Returns a literal value. This value is valid until the next Evaluate call /// OSGeo::FDO::Expression::LiteralValue* Evaluate(System::String* name); /// \brief /// Evaluates an identifier /// /// \param identifier /// Input identifier /// /// \return /// Returns a literal value. This value is valid until the next Evaluate call /// OSGeo::FDO::Expression::LiteralValue* Evaluate(OSGeo::FDO::Expression::Identifier* expr); /// \brief /// Evaluates an aggregate functions /// /// \return /// Returns the aggragate results /// OSGeo::FDO::Commands::PropertyValueCollection* RunQuery(); /// \brief /// Checks if passes the filter /// /// \param filter /// Input filter /// /// \return /// Returns true id passes the filter, otherwise false /// System::Boolean ProcessFilter(OSGeo::FDO::Filter::Filter* filter); /// \brief /// Returns the default functions plus the user defined functions /// /// \return /// Returns the functions /// OSGeo::FDO::Connections::Capabilities::FunctionDefinitionCollection* GetAllFunctions(); /// \brief /// Returns the default functions the expression engine supports /// /// \return /// Returns the functions /// static OSGeo::FDO::Connections::Capabilities::FunctionDefinitionCollection* GetStandardFunctions(); /// \brief /// Checks if the filter is valid /// /// \param cls /// Input class definition /// /// \param filter /// Input filter /// /// \param selIds /// Input identifier collection /// /// \param filterCapabilities /// Input filter capabilities /// /// \return /// Throws an exception is filter is not valid /// static System::Void ValidateFilter(OSGeo::FDO::Schema::ClassDefinition *cls, OSGeo::FDO::Filter::Filter *filter, OSGeo::FDO::Commands::IdentifierCollection *selIds, OSGeo::FDO::Connections::Capabilities::IFilterCapabilities *filterCapabilities); /// \brief /// Optimizes the filter /// /// \param filter /// Input the filter /// /// \return /// The optimized filter /// static OSGeo::FDO::Filter::Filter* OptimizeFilter( OSGeo::FDO::Filter::Filter *filter ); /// \brief /// Checks if the function name is a aggregate function /// /// \param funcDefs /// Input the list of functions /// /// \param name /// Input the function name /// /// \return /// True if the function is an aggregate function otherwise false /// static System::Boolean IsAggregateFunction(OSGeo::FDO::Connections::Capabilities::FunctionDefinitionCollection *funcDefs, System::String *name); /// \brief /// Returns the type of expression /// /// \param functions /// Input the list of functions /// /// \param originalClassDef /// Input the class definition /// /// \param propType /// Output the property type /// /// \param dataType /// Output the data type /// /// \return /// Returns nothing /// static System::Void GetExpressionType(OSGeo::FDO::Connections::Capabilities::FunctionDefinitionCollection *functionDefinitions, OSGeo::FDO::Schema::ClassDefinition *originalClassDef, OSGeo::FDO::Expression::Expression *expr, OSGeo::FDO::Schema::PropertyType *retPropType, OSGeo::FDO::Schema::DataType *retDataType); /// \brief /// Returns the type of expression /// /// \param originalClassDef /// Input the class definition /// /// \param propType /// Output the property type /// /// \param dataType /// Output the data type /// /// \return /// Returns nothing /// static System::Void GetExpressionType(OSGeo::FDO::Schema::ClassDefinition* originalClassDef, OSGeo::FDO::Expression::Expression *expr, OSGeo::FDO::Schema::PropertyType *retPropType, OSGeo::FDO::Schema::DataType *retDataType); /// \brief /// Registers the user-defined functions /// /// \param userDefinedFunctions /// Input the user-defined functions /// /// \return /// Returns nothing /// static System::Void RegisterFunctions(OSGeo::FDO::Utilities::ExpressionEngine::FunctionCollection *userDefinedFunctions); }; }}} === Copy Filter === {{{ /// \brief /// This helper class traverse the filter object and creates a deep copy. /// public __gc class OSGeo::FDO::Utilities::ExpressionEngine::CopyFilter : public virtual OSGeo::FDO::Expression::IExpressionProcessor, public virtual OSGeo::FDO::Filter::IFilterProcessor { public: /// \brief /// Constructs a new instance of ExpressionEngineCopyFilter /// CopyFilter(); /// \brief /// Static methods needed for copy/constructing filter objects /// static OSGeo::FDO::Filter::Filter* Copy( OSGeo::FDO::Filter::Filter *filter ); static OSGeo::FDO::Filter::Filter* Copy( OSGeo::FDO::Filter::Filter *filter, OSGeo::FDO::Commands::IdentifierCollection* idList ); /// \brief /// Static methods needed for copy/constructing expression objects /// static OSGeo::FDO::Expression::Expression* Copy( OSGeo::FDO::Expression::Expression *expression ); static OSGeo::FDO::Expression::Expression* Copy( OSGeo::FDO::Expression::Expression *expression, OSGeo::FDO::Commands::IdentifierCollection* idList ); /// \brief /// Gets the FDO Expression associated to the CopyFilter /// OSGeo::FDO::Expression::Expression* GetExpression(); /// \brief /// Gets the FDO Filter associated to the CopyFilter /// OSGeo::FDO::Filter::Filter* GetFilter(); }; }}} === Function Collection === {{{ /// \brief /// The FunctionCollection class represents a collection of Expression Engine IFunction objects. /// [System::Reflection::DefaultMemberAttribute("RealTypeItem")] public __sealed __gc class OSGeo::FDO::Utilities::ExpressionEngine::FunctionCollection : public OSGeo::Runtime::Disposable, public System::Collections::IList { public: /// \brief /// Constructs a FunctionCollection object /// /// \param parent /// Input A Pointer to the parent schema object of the collection /// FunctionCollection(OSGeo::FDO::Schema::SchemaElement* parent); /// \brief /// Constructs a FunctionCollection object based on an unmanaged instance of the object /// /// \param unmanaged /// Input A Pointer to the unmanaged object. /// /// \param autoDelete /// Input Indicates if the constructed object should be automatically deleted /// once it no longer referenced. /// FunctionCollection(System::IntPtr unmanaged, System::Boolean autoDelete); /// \brief /// Gets the count of items in collection. /// /// \return /// Returns the number of items in the collection. /// __property System::Int32 get_Count(System::Void); /// \brief /// Gets an enumerator that can iterate through a collection. /// /// \return /// Returns an enumerator on the dictionary. /// __sealed System::Collections::IEnumerator* GetEnumerator(System::Void); /// \brief /// Removes the index-th IFunction from this collection. /// /// \param index /// Input index of the element to remove. /// System::Void RemoveAt(System::Int32 index); /// \brief /// Removes all elements from the collection. /// System::Void Clear(); /// \brief /// Adds a IFunction object into the collection. /// /// \param value /// Input the IFunction object to add. /// /// \return /// Returns the position into which the new element was inserted. /// System::Int32 Add(OSGeo::FDO::Utilities::ExpressionEngine::IFunction* value); /// \brief /// Determines the index of a specific IFunction object. /// /// \param value /// Input the IFunction object to locate in the collection. /// /// \return /// The index of value if found in the collection; otherwise, -1. /// System::Int32 IndexOf(OSGeo::FDO::Utilities::ExpressionEngine::IFunction* value); /// \brief /// Determines the index of a specific IFunction object. /// /// \param name /// Input the name of the object to locate in the collection. /// /// \return /// The index of value if found in the collection; otherwise, -1. /// System::Int32 IndexOf(String* name); /// \brief /// Inserts a IFunction object into the collection at the specified position. /// /// \param index /// Input the zero-based index at which value should be inserted. /// \param value /// Input the IFunction object to insert. /// System::Void Insert(System::Int32 index, OSGeo::FDO::Utilities::ExpressionEngine::IFunction* value); /// \brief /// Removes the first occurrence of a specific IFunction object. /// /// \param value /// Input the IFunction object to remove from the collection. /// System::Void Remove(OSGeo::FDO::Utilities::ExpressionEngine::IFunction* value); /// \brief /// Determines whether the collection contains a specific IFunction object. /// /// \param value /// Input The IFunction object to search in the collection. /// /// \return /// Returns true if the value is found in the collection; otherwise, false. /// System::Boolean Contains(OSGeo::FDO::Utilities::ExpressionEngine::IFunction* value); /// \brief /// Determines whether the collection contains a specific IFunction object. /// /// \param name /// Input The name of the IFunction object to search in the collection. /// /// \return /// Returns true if the value is found in the collection; otherwise, false. /// System::Boolean Contains(String* name); /// \brief /// Copies the elements of the collection to an array. /// /// \param array /// Output the one-dimensional Array that is the destination of the elements copied from this collection. /// /// \param startAt /// Input an integer that represents the index in array at which copying begins. /// System::Void CopyTo(OSGeo::FDO::Utilities::ExpressionEngine::IFunction* array[],System::Int32 startAt); /// \brief /// Gets the item in the collection at the specified index. /// /// \param index /// The index of the item in the collection. The index is 0 based. /// /// \return /// Returns an instance of a the collected item. /// Throws an instance of Exception if the index is out of range or an error occurs. /// __property OSGeo::FDO::Utilities::ExpressionEngine::IFunction* get_RealTypeItem(System::Int32 index); /// \brief /// Gets the item in the collection by name. /// /// \param index /// The name of the item in the collection. /// /// \return /// Returns an instance of a the collected item. /// __property OSGeo::FDO::Utilities::ExpressionEngine::IFunction* get_RealTypeItem(System::String* index); /// \brief /// Sets the value of the item at the specified index /// /// \param index /// Input index of the item to set. /// /// \param value /// Input the value of the item /// __property System::Void set_RealTypeItem(System::Int32 index, OSGeo::FDO::Utilities::ExpressionEngine::IFunction* value); /// \brief /// Gets an item in the collection. /// /// \param index /// Input index of the item to retrieve. /// /// \return /// Returns the item at the specified index /// __property OSGeo::FDO::Utilities::ExpressionEngine::IFunction* get_Item(System::Int32 index); /// \brief /// Sets the value of the item at the specified index /// /// \param index /// Input index of the item to set. /// /// \param value /// Input the value of the item /// __property System::Void set_Item(System::Int32 index, OSGeo::FDO::Utilities::ExpressionEngine::IFunction* value); }; }}} === IFunction Interface === {{{ /// \brief /// This class defines the base interface from which all Function classes derive. /// public __gc class OSGeo::FDO::Utilities::ExpressionEngine::IFunction : public OSGeo::Runtime::Disposable { public: /// \brief /// Returns the function definition for the function. /// The definition includes the list of supported signatures for the /// function. __property OSGeo::FDO::Connections::Capabilities::FunctionDefinition *get_FunctionDefinition (); }; }}} === IAggregateFunction Interface === {{{ /// \brief /// This class defines the base interface from which all Aggregate Function classes derive. /// public __gc class OSGeo::FDO::Utilities::ExpressionEngine::IAggregateFunction : public OSGeo::FDO::Utilities::ExpressionEngine::IFunction { public: /// \brief /// Executes the call of the function on an expression value. System::Void Process(OSGeo::FDO::Expression::LiteralValueCollection *literal_values); /// \brief // Returns the result of the function. __property OSGeo::FDO::Expression::LiteralValue *get_Result(); }; }}} === INonAggregateFunction Interface === {{{ /// \brief /// This class defines the base interface from which all Non-Aggregate Function classes derive. /// public __gc class OSGeo::FDO::Utilities::ExpressionEngine::INonAggregateFunction : public OSGeo::FDO::Utilities::ExpressionEngine::IFunction { public: /// \brief /// The function determines the function result and returns it back to /// the calling routine. OSGeo::FDO::Expression::LiteralValue * Evaluate(OSGeo::FDO::Expression::LiteralValueCollection *literalValues); }; }}} === Aggregate Functions === {{{ /// \brief /// The class FunctionAvg implements the Expression Engine function AVG. /// public __gc class OSGeo::FDO::Utilities::ExpressionEngine::Functions::Aggregate::FunctionAvg : public OSGeo::FDO::Utilities::ExpressionEngine::IAggregateFunction { public: /// \brief /// Constructs a new object definition. /// FunctionAvg (); } /// \brief /// The class FunctionCount implements the Expression Engine function COUNT. /// public __gc class OSGeo::FDO::Utilities::ExpressionEngine::Functions::Aggregate::FunctionCount : public OSGeo::FDO::Utilities::ExpressionEngine::IAggregateFunction { public: /// \brief /// Constructs a new object definition. /// FunctionCount (); } Etc... }}} === Non-Aggregate Functions === {{{ /// \brief /// The class FunctionNullValue implements the Expression Engine function NULLVALUE. /// public __gc class OSGeo::FDO::Utilities::ExpressionEngine::Functions::Conversion::FunctionNullValue : public OSGeo::FDO::Utilities::ExpressionEngine::INonAggregateFunction { public: /// \brief /// Constructs a new object definition. /// FunctionNullValue (); } /// \brief /// The class FunctionToDate implements the Expression Engine function TODATE. /// public __gc class OSGeo::FDO::Utilities::ExpressionEngine::Functions::Conversion::FunctionToDate : public OSGeo::FDO::Utilities::ExpressionEngine::INonAggregateFunction { public: /// \brief /// Constructs a new object definition. /// FunctionToDate (); } Etc... }}} == Test Plan == A managed unit tests suite will be added to test the API defined above. == Funding/Resources == Autodesk to provide resources / funding