wiki:FDORfc34

Version 30 (modified by gregboone, 15 years ago) ( diff )

--

FDO RFC 34 - FDO Reader Access By Index

This page contains an change request (RFC) for the FDO Open Source project. More FDO RFCs can be found on the RFCs page.

Status

RFC Template Version(1.0)
Submission Date April 9, 2009
Last Modified Greg Boone Timestamp
AuthorGreg Boone
RFC StatusNot Ready
Implementation StatusPending
Proposed Milestone3.5.0.0
Assigned PSC guide(s)Greg Boone
Voting History(vote date)
+1
+0
-0
-1

Motivation

To provide faster access to data returned from feature, data and SQL readers though the FDO API.
To provide enhance compatibility with the ADO.Net Reader/record Interfaces.

Overview

Currently, data returned in Feature readers, data or SQL readers can only be accessed using input function parameters that reflect the name of the property or column being read. In the following example, the feature reader returned from the select command has to be accessed using the GetDouble method, with an input parameter that is the feature property name. In such an implementation, there is an associated cost to determining which property is being requested. Such a cost is typically encountered in performing a lookup based on the parameter name, which inevitably results in some form of a string comparison.

FdoPtr<FdoISelect> spSelectCmd = static_cast<FdoISelect>(mConnection->CreateCommand(FdoCommandType_Select));
spSelectCmd->SetFeatureClassName (L"Foo");

FdoPtr<FdoIdentifierCollection> spIds = spSelectCmd->GetPropertyNames ();
FdoPtr<FdoIdentifier> spId = FdoComputedIdentifier::Create(L"AVG_ID", FdoPtr<FdoExpression>(FdoExpression::Parse(L"Avg(ID)")));
spIds->Add(spId);

FdoPtr<FdoIFeatureReader> spReader = spSelectCmd->Execute ();
while (spReader->ReadNext())
{
    double avg = spReader->GetDouble(L"AVG_ID");
}

The goal of this RFC is to add overloaded methods to the various FDO reader interfaces that will accept an integer argument representing the indexed location of the property in the reader's in-memory representation of the feature or table. Readers will return the total count of properties being returned and be able to indicate which property or column is indexed a specified location. It is expected that this will speed up processing and provide a better end-user experience. Users will be able to access their data using an index into the feature reader collection as follows:

FdoPtr<FdoISelect> spSelectCmd = static_cast<FdoISelect>(mConnection->CreateCommand(FdoCommandType_Select));
spSelectCmd->SetFeatureClassName (L"Foo");

FdoPtr<FdoIdentifierCollection> spIds = spSelectCmd->GetPropertyNames ();
FdoPtr<FdoIdentifier> spId = FdoComputedIdentifier::Create(L"AVG_ID", FdoPtr<FdoExpression>(FdoExpression::Parse(L"Avg(ID)")));
spIds->Add(spId);

FdoPtr<FdoIFeatureReader> spReader = spSelectCmd->Execute ();
while (spReader->ReadNext())
{
    double avg = spReader->GetDouble(0); // 0 is the index of the AVG_ID property
}

Requirements

The following FDO reader interfaces will be updated to allow for indexed access. Providers will be required to implement these method.

Interface IReader

/// \brief
/// The FdoIReader interface provides a forward-only, read-only iterator
/// for reading feature data.  FdoIReader is the base interface for 
/// feature and data readers that are returned from the Select, 
/// and SelectAggregates commands. FdoIReader provides the funtion
/// definitions for the GetXxxx properties and the definition of IsNull() 
/// and ReadNext(). Because the initial position of the reader is prior 
/// to the first item, you must call ReadNext to begin accessing any data.
class FdoIReader: public FdoIDisposable
{
public:
...
...
...
    /// \brief
    /// Returns true if the value of the property at the specified 
    /// index is null.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns true if the value is null.
    /// 
    FDO_API virtual FdoBoolean IsNull(FdoInt32 index) = 0;

    /// \brief
    /// Gets the Boolean value of the property specified at the index position. 
    /// No conversion is performed, thus the property must be FdoDataType_Boolean 
    /// or an exception is thrown.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the Boolean value.
    /// 
    FDO_API virtual FdoBoolean GetBoolean(FdoInt32 index) = 0;

    /// \brief
    /// Gets the Byte value of the property specified at the index position. 
    /// No conversion is performed, thus the property must be FdoDataType_Byte 
    /// or an exception is thrown.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the byte value.
    /// 
    FDO_API virtual FdoByte GetByte(FdoInt32 index) = 0;

    /// \brief
    /// Gets the date and time value of the of the property specified at 
    /// the index position. No conversion is performed, thus the property 
    /// must be FdoDataType_DateTime or an exception is thrown.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the date and time value.
    /// 
    FDO_API virtual FdoDateTime GetDateTime(FdoInt32 index);

    /// \brief
    /// Gets the double-precision floating point value of the property specified at 
    /// the index position. No conversion is performed, thus the property must be 
    /// FdoDataType_Double or an exception is thrown.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the double floating point value
    /// 
    FDO_API virtual FdoDouble GetDouble(FdoInt32 index) = 0;

    /// \brief
    /// Gets the 16-bit integer value of the property specified at 
    /// the index position. No conversion is performed, thus the 
    /// property must be FdoDataType_Int16 or an exception is thrown.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the FdoInt16 value.
    /// 
    FDO_API virtual FdoInt16 GetInt16(FdoInt32 index) = 0;

    /// \brief
    /// Gets the 32-bit integer value of the property specified at 
    /// the index position. No conversion is performed, thus the 
    /// property must be FdoDataType_Int32 or an exception is thrown.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the FdoInt32 value
    /// 
    FDO_API virtual FdoInt32 GetInt32(FdoInt32 index) = 0;

    /// \brief
    /// Gets the 64-bit integer value of the property specified at 
    /// the index position. No conversion is performed, thus the 
    /// property must be FdoDataType_Int64 or an exception is thrown.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the FdoInt64 value.
    /// 
    FDO_API virtual FdoInt64 GetInt64(FdoInt32 index) = 0;

    /// \brief
    /// Gets the Single floating point value of the property specified at 
    /// the index position. No conversion is performed, thus the property 
    /// must be FdoDataType_Single or an exception is thrown.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the single value
    /// 
    FDO_API virtual FdoFloat GetSingle(FdoInt32 index) = 0;

    /// \brief
    /// Gets the string value of the property specified at the index
    /// position. No conversion is performed, thus the property must
    /// be FdoDataType_String or an exception is thrown.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the string value
    /// 
    FDO_API virtual FdoString* GetString(FdoInt32 index) = 0;

    /// \brief
    /// Gets a LOBValue reference to the property specified at the index
    /// position. The LOB is fully read in and data available.
    /// Because no conversion is performed, the property must be 
    /// FdoDataType_BLOB or FdoDataType_CLOB etc. (a LOB type)
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the reference to LOBValue
    /// 
    FDO_API virtual FdoLOBValue* GetLOB(FdoInt32 index) = 0;

    /// \brief
    /// Gets a reference to the specified LOB property, specified at the index
    /// position. The reference is returned as an FdoBLOBStreamReader or an 
    /// FdoCLOBStreamReader, to allow reading in blocks of data. Because 
    /// no conversion is performed, the property must be FdoDataType_BLOB 
    /// or FdoDataType_CLOB etc. (a LOB type) Cast the FdoIStreamReader 
    /// to the appropiate LOB Stream Reader.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns a reference to a LOB stream reader
    /// 
    FDO_API virtual FdoIStreamReader* GetLOBStreamReader(FdoInt32 index) = 0;

    /// \brief
    /// Gets the geometry value of the property, at the specified index, as  
    /// a byte array in FGF format. Because no conversion is performed, the 
    /// property must be of Geometric type; otherwise, an exception is thrown.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the byte array in FGF format.
    /// 
    FDO_API virtual FdoByteArray* GetGeometry(FdoInt32 index) = 0;

    /// \brief
    /// Gets the raster object of the property at the specified index.
    /// Because no conversion is performed, the property must be
    /// of Raster type; otherwise, an exception is thrown.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the raster object.
    /// 
    FDO_API virtual FdoIRaster* GetRaster(FdoInt32 index) = 0;
};

Interface IFeatureReader

/// \brief
/// The FdoIFeatureReader interface provides a forward-only, read-only iterator
/// for reading feature data.  A reference to an FdoIFeatureReader is returned
/// from the Select command. Because the initial position of the FdoIFeatureReader 
/// is prior to the first item, you must call ReadNext to begin accessing any data.
class FdoIFeatureReader: public FdoIReader
{
public:
    /// \brief
    /// Gets the number of properties in the result set.
    /// 
    /// \return
    /// Returns the number of columns.
    /// 
    FDO_API virtual FdoInt32 GetPropertyCount() = 0;

    /// \brief
    /// Gets the name of the property at the given ordinal position.
    /// 
    /// \param index 
    /// Input the position of the property.
    /// 
    /// \return
    /// Returns the property name
    /// 
    FDO_API virtual FdoString* GetPropertyName(FdoInt32 index) = 0;

    /// \brief
    /// Gets the index of the property with the given name.
    /// 
    /// \param index 
    /// Input the name of the property.
    /// 
    /// \return
    /// Returns the property index
    /// 
    FDO_API virtual FdoInt32 GetPropertyIndex(FdoString* propertyName) = 0;

    /// \brief
    /// Gets the type of the property at the given ordinal position.
    /// 
    /// \param index 
    /// Input the position of the property.
    /// 
    /// \return
    /// Returns the type of the property.
    /// 
    FDO_API virtual FdoPropertyType GetPropertyType(FdoInt32 index) = 0;

    /// \brief
    /// Gets the type of the property with the given name.
    /// 
    /// \param index 
    /// Input the name of the property.
    /// 
    /// \return
    /// Returns the type of the property.
    /// 
    FDO_API virtual FdoPropertyType GetPropertyType(FdoString* propertyName) = 0;

    /// \brief
    /// Gets the data type of the property at the specified ordinal position.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the data type of the property.
    /// 
    FDO_API virtual FdoDataType GetDataType(FdoInt32 index) = 0;

    /// \brief
    /// Gets the data type of the property with the specified name.
    /// 
    /// \param index 
    /// Input the name of the property.
    /// 
    /// \return
    /// Returns the data type of the property.
    /// 
    FDO_API virtual FdoDataType GetDataType(FdoInt32 index) = 0;

    /// \brief
    /// Gets the definition of the object currently being read. If the user
    /// has requested only a subset of the class properties, the class 
    /// definition reflects what the user has asked, rather than the full class 
    /// definition.
    /// 
    /// \return
    /// Returns the class definition object.
    /// 
    FDO_API virtual FdoClassDefinition* GetClassDefinition() = 0;

    /// \brief
    /// Gets a value indicating the depth of nesting for the current reader.
    /// The depth value increases each time GetFeatureObject is called and a new 
    /// reader is returned. The outermost reader has a depth of 0.
    /// 
    /// \return
    /// Returns the depth
    /// 
    FDO_API virtual FdoInt32 GetDepth() = 0;

    /// \brief
    /// Gets the geometry value of the specified property as a byte array in 
    /// FGF format. Because no conversion is performed, the property must be
    /// of Geometric type; otherwise, an exception is thrown. 
    /// This method is a language-specific performance optimization that returns a
    /// pointer to the array data, rather than to an object that encapsulates
    /// the array.  The array's memory area is only guaranteed to be valid
    /// until a call to ReadNext() or Close(), or the disposal of this reader
    /// object.
    /// 
    /// \param propertyName 
    /// Input the property name.
    /// \param count 
    /// Output the number of bytes in the array.
    /// 
    /// \return
    /// Returns a pointer to the byte array in FGF format.
    /// 
    FDO_API virtual const FdoByte * GetGeometry(FdoString* propertyName, FdoInt32* count) = 0;

    /// \brief
    /// Gets the geometry value of the property, at the specified index, 
    /// as a byte array in FGF format. Because no conversion is performed, 
    /// the property must be of Geometric type; otherwise, an exception is thrown. 
    /// This method is a language-specific performance optimization that returns a
    /// pointer to the array data, rather than to an object that encapsulates
    /// the array.  The array's memory area is only guaranteed to be valid
    /// until a call to ReadNext() or Close(), or the disposal of this reader
    /// object.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// \param count 
    /// Output the number of bytes in the array.
    /// 
    /// \return
    /// Returns a pointer to the byte array in FGF format.
    /// 
    FDO_API virtual const FdoByte * GetGeometry(FdoInt32 index, FdoInt32* count) = 0;

    /// \brief
    /// Gets a reference to an FdoIFeatureReader to read the data contained in
    /// the object or object collection property. If the property is not an
    /// object property, an exception is thrown.
    /// 
    /// \param propertyName 
    /// Input the property name.
    /// 
    /// \return
    /// Returns the nested feature reader
    /// 
    FDO_API virtual FdoIFeatureReader* GetFeatureObject(FdoString* propertyName) = 0;

    /// \brief
    /// Gets a reference to an FdoIFeatureReader to read the data contained in
    /// the object or object collection property defined at the specified index 
    /// position. If the property is not an object property, an exception is thrown.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the nested feature reader
    /// 
    FDO_API virtual FdoIFeatureReader* GetFeatureObject(FdoInt32 index) = 0;
};

Interface IDataReader

/// \brief
/// The FdoIDataReader interface provides a forward-only, read-only
/// iterator for reading relational table data. A reference to an
/// FdoIDataReader is returned from the SQLCommands ExecuteReader method.
/// The initial position of the FdoIDataReader interface is prior to the first item.
/// Thus, you must call ReadNext to begin accessing any data.
class FdoIDataReader: public FdoIReader
{
public:
...
...
...
    /// \brief
    /// Gets the data type of the property at the specified index position.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the type of the property.
    /// 
    FDO_API virtual FdoDataType GetDataType(FdoInt32 index) = 0;

    /// \brief
    /// Gets the FDO property type of the property at the given index. This is used
    /// to indicate if a given property is a geometric property or a data property. 
    /// If the property is a FdoPropertyType_DataProperty, then GetDataType 
    /// can be used to to find the data type of the property.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the FDO property type.
    /// 
    FDO_API virtual FdoPropertyType GetPropertyType(FdoInt32 index) = 0;
};

Interface ISQLDataReader

/// \brief
/// The FdoISQLDataReader interface provides a forward-only, read-only
/// iterator for reading relational table data. A reference to an
/// FdoISQLDataReader is returned from the SQLCommands ExecuteReader method.
/// The initial position of the FdoISQLDataReader interface is prior to the first item.
/// Thus, you must call ReadNext to begin accessing any data.
class FdoISQLDataReader: public FdoIDisposable
{
public:
...
...
...
    /// \brief
    /// Returns true if the value of the specified column is null.
    /// 
    /// \param index 
    /// Input the position of the column.   
    /// 
    /// \return
    /// Returns true if the value is null.
    /// 
    FDO_API virtual FdoBoolean IsNull(FdoInt32 index) = 0;

    /// \brief
    /// Gets the index of the column with the given name.
    /// 
    /// \param index 
    /// Input the name of the property.
    /// 
    /// \return
    /// Returns the property index
    /// 
    FDO_API virtual FdoInt32 GetColumnIndex(FdoString* propertyName)

    /// \brief
    /// Gets the data type of the column at the specified index.
    /// 
    /// \param index 
    /// Input the position of the column.   
    /// 
    /// \return
    /// Returns the type of the column.
    /// 
    FDO_API virtual FdoDataType GetColumnType(FdoInt32 index) = 0;

    /// \brief
    /// Gets the FDO property type of the column at the specified index. This is used
    /// to indicate if a given column is a geometric property or a data property. If the column is
    /// a FdoPropertyType_DataProperty, then GetColumnType can be used to find the data type of the column.
    /// 
    /// \param index 
    /// Input the position of the column.   
    /// 
    /// \return
    /// Returns the FDO property type of the column.
    /// 
    FDO_API virtual FdoPropertyType GetPropertyType(FdoInt32 index) = 0;

    /// \brief
    /// Gets the Boolean value of the specified column. No conversion is
    /// performed, thus the column must be FdoDataType_Boolean or an
    /// exception is thrown.
    /// 
    /// \param index 
    /// Input the position of the column.   
    /// 
    /// \return
    /// Returns the Boolean value
    /// 
    FDO_API virtual FdoBoolean GetBoolean(FdoInt32 index) = 0;

    /// \brief
    /// Gets the byte value of the specified column. No conversion is
    /// performed, thus the column must be FdoDataType_Byte or an
    /// exception is thrown.
    /// 
    /// \param index 
    /// Input the position of the column.   
    /// 
    /// \return
    /// Returns the byte value.
    /// 
    FDO_API virtual FdoByte GetByte(FdoInt32 index) = 0;

    /// \brief
    /// Gets the date time value of the specified column. No conversion
    /// is performed, thus the column must be FdoDataType_DateTime or
    /// an exception is thrown.
    /// 
    /// \param index 
    /// Input the position of the column.   
    /// 
    /// \return
    /// Returns the date and time value.
    /// 
    FDO_API virtual FdoDateTime GetDateTime(FdoInt32 index) = 0;

    /// \brief
    /// Gets the double-precision floating point value of the specified column.
    /// No conversion is performed, thus the column must be of type
    /// Double or an exception is thrown.
    /// 
    /// \param index 
    /// Input the position of the column.   
    /// 
    /// \return
    /// Returns the double value.
    /// 
    FDO_API virtual FdoDouble GetDouble(FdoInt32 index) = 0;

    /// \brief
    /// Gets the signed 16-bit integer value of the specified column. No conversion is
    /// performed, thus the column must be FdoDataType_Int16 or an
    /// exception is thrown.
    /// 
    /// \param index 
    /// Input the position of the column.   
    /// 
    /// \return
    /// Returns the FdoInt16 value.
    /// 
    FDO_API virtual FdoInt16 GetInt16(FdoInt32 index) = 0;

    /// \brief
    /// Gets the signed 32-bit integer value of the specified column. No conversion is
    /// performed, thus the column must be FdoDataType_Int32 or an
    /// exception is thrown.
    /// 
    /// \param index 
    /// Input the position of the column.   
    /// 
    /// \return
    /// Returns the FdoInt32 value.
    /// 
    FDO_API virtual FdoInt32 GetInt32(FdoInt32 index) = 0;

    /// \brief
    /// Gets the signed 64-bit integer value of the specified column. No conversion
    /// is performed, thus the column must be FdoDataType_Int64 or an
    /// exception is thrown.
    /// 
    /// \param index 
    /// Input the position of the column.   
    /// 
    /// \return
    /// Returns the FdoInt64 value.
    /// 
    FDO_API virtual FdoInt64 GetInt64(FdoInt32 index) = 0;

    /// \brief
    /// Gets the single-precision floating point value of the specified column.
    /// No conversion is performed, thus the column must be FdoDataType_Single
    /// or an exception is thrown.
    /// 
    /// \param index 
    /// Input the position of the column.   
    /// 
    /// \return
    /// Returns the single value
    /// 
    FDO_API virtual FdoFloat GetSingle(FdoInt32 index) = 0;

    /// \brief
    /// Gets the string value of the specified column. No conversion is
    /// performed, thus the column must be FdoDataType_String or an
    /// exception is thrown.
    /// 
    /// \param index 
    /// Input the position of the column.   
    /// 
    /// \return
    /// Returns the string value.
    /// 
    FDO_API virtual FdoString* GetString(FdoInt32 index) = 0;

    /// \brief
    /// Gets a LOBValue reference. The LOB is fully read in and data available.
    /// Because no conversion is performed, the property must be FdoDataType_BLOB or
    /// FdoDataType_CLOB etc. (a LOB type)
    /// 
    /// \param index 
    /// Input the position of the column.   
    /// 
    /// \return
    /// Returns the reference to LOBValue
    /// 
    FDO_API virtual FdoLOBValue* GetLOB(FdoInt32 index) = 0;

    /// \brief
    /// Gets a reference of the specified LOB property as a FdoBLOBStreamReader or
    /// FdoCLOBStreamReader etc. to allow reading in blocks of data. Because 
    /// no conversion is performed, the property must be FdoDataType_BLOB 
    /// or FdoDataType_CLOB etc. (a LOB type) Cast the FdoIStreamReader 
    /// to the appropiate LOB Stream Reader.
    /// 
    /// \param index 
    /// Input the position of the column.   
    /// 
    /// \return
    /// Returns a reference to a LOB stream reader
    /// 
    FDO_API virtual FdoIStreamReader* GetLOBStreamReader(FdoInt32 index) = 0;

    /// \brief
    /// Gets the geometry value of the specified column as a byte array
    /// in FGF format. No conversion is performed, thus the column
    /// must be of Geometric type or an exception is thrown.
    /// 
    /// \param index 
    /// Input the position of the column.   
    /// 
    /// \return
    /// Returns the FGF byte array value.
    /// 
    FDO_API virtual FdoByteArray* GetGeometry(FdoInt32 index) = 0;
};

Managed FDO API

The FDO Managed Interfaces will be updated in a similar manner to reflect the proposed changes.

Provider Implementation

Providers will be required to implement the above functionality.

It is expected that resourcing will be supplied to modify all the existing FDO Open Source providers.

Test Plan

Existing FDO Core and Provider level unit tests will be expanded to test the proposed enhancements defined above.

Funding/Resources

Autodesk to provide resources / funding

Note: See TracWiki for help on using the wiki.