= FDO RFC 26 - New !ExtendedSelect command and Scrollable Reader = This page contains a request for change 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||October 7, 2008|| ||Last Modified||Orest Halustchak [[Timestamp]]|| ||Author||Orest Halustchak, Greg Boone|| ||RFC Status||Draft|| ||Implementation Status||Draft|| ||Proposed Milestone||3.4.0.0|| ||Assigned PSC guide(s)||Greg Boone|| ||'''Voting History'''|||| ||+1||Orest Halustchak, Greg Boone, Jason Birch, Haris Kurtagic|| ||+0|||| ||-0|||| ||-1|||| == Overview == This RFC adds a new extended select command and scrollable reader to the FDO API. It migrates the current custom command implementations of these in the SDF, SHP, and SQLite providers to make them generic FDO capabilities. == Motivation == Currently the SDF, SHP, and SQLite provides implement custom commands for extended select, which includes support for a scrollable reader and advanced sorting options. The custom command approach is fine for provider specific capabilities that are not generic, but when a capability is something that many providers could support, they should be defined at the FDO generic level. This will allow them to be used generically by any client application. == Proposed Solution == This RFC defines a generic FDO command for extended select to replace the custom commands and modifies the SDF, SHP, and SQLite providers to implement the new generic command. The custom commands will remain for backwards compatibility but should be deprecated and removed at some point. This enhancement provides the following main capabilities: 1. Scrollable reader; move forward, backward and jump to a particular record. 2. Support sorting on more than one property. The solution is made of 2 main interfaces, FdoIExtendedSelect and FdoIScrollableReader. The FdoIExtendedSelect is a specialization of the existing FdoISelect command and, likewise, the FdoIScrollableReader is a specialization of the FdoIFeatureReader interface. That implies that both extension exposes the same functionality of their base interfaces and extend it with the new features. === !ExtendedSelect === The FdoIExtendedSelect command can be used to create a scrollable reader and provide multi-properties sorting with different sorting option on each property. Sorting is only performed if the ordering collection is not empty. The ordering collection can be set by calling the FdoISelect::GetOrdering(). Above and beyond the methods provided by the FdoISelect command, the FdoIExtendedSelect provides the methods shown in the definition below. {{{ class FdoIExtendedSelect : public FdoISelect { public: /// \brief /// Set the ordering option of the selection. /// /// \remarks /// This is only used if the ordering collection is not empty. /// /// \param propertyName /// Is the property name for which the ordering should be applied. This property should be in the ordering collection. /// /// \param option /// Is the ordering option and should be set to one of FdoOrderingOption_Ascending or FdoOrderingOption_Descending. /// FdoOrderingOption_Ascending is the default value. virtual void SetOrderingOption( FdoString* propertyName, FdoOrderingOption option ) = 0; /// \brief /// Gets the ordering option for a given property. /// /// \param propertyName //Is the property name for which the ordering should be applied. This property should be in the ordering collection. /// /// \return /// Returns the ordering option. virtual FdoOrderingOption GetOrderingOption( FdoString* propertyName ) = 0; /// \brief /// Clears the internal list of property/ordering option list and re-sets the ordering option for all /// the ordering properties to the default FdoOrderingOption_Ascending or to the ordering option specified by the /// FdoIBaseSelect interface. virtual void ClearOrderingOptions( ) = 0; /// \brief /// Executes the select command and returns an FdoIScrollableFeatureReader. /// /// \remarks /// If ordering is enabled, then the returned reader is sorted according to /// the ordering collection. This method perform sorting in memory and allocates an integer value for each row. /// \return /// Returns a FdoIScrollableFeatureReader object virtual FdoIScrollableFeatureReader* ExecuteScrollable() = 0; }; }}} The new command type !FdoCommandType_ExtendedSelect will be added to the !FdoCommandType enum. === !ScrollableFeatureReader === The FdoIScrollableFeatureReader is an extension to the FdoIFeature reader that can be traversed in the forward and backward direction (scrollable). It also provides an ad-hoc access to the returned data. Once the reader is positioned at a given record, the FdoIFeatureReader accesors can be used to access the various properties values. On top of the interface supported by the FdoIFeatureReader, the FdoIScrollableFeatureReader supports the methods shown in the definition below. {{{ class FdoIScrollableFeatureReader : public FdoIFeatureReader { public: /// \brief /// Returns the number of records of the query result. /// /// \return /// Returns number of records. virtual int Count() = 0; /// \brief /// Positions the reader at the first record of the query result. /// /// \return /// Returns true if a record is found or false if the result is empty. virtual bool ReadFirst() = 0; /// \brief /// Position the reader at the last record of the query result. /// /// \return /// Returns true if a record is found or false if the result is empty. virtual bool ReadLast() = 0; /// \brief /// Advances the reader to the previous item. /// /// \remarks /// The default position of the reader is prior to the first item. /// Therefore you must call ReadFirst or ReadLast to /// begin accessing any data. /// /// \return /// Returns true if a record is found or false if reading is complete. virtual bool ReadPrevious() = 0; /// \brief /// Provides the ad-hoc access to the query result. /// /// \remarks /// It positions the position of the reader at a given record /// defined by the key. If the record is not found, /// then the reader position is unset and false value is returned. /// Once the reader’s position becames unset, /// the caller needs to call ReadFirst, ReadLast or ReadAt to re-position /// the reader at a valid location. /// /// \param key /// The key that identifies a record. /// /// \return /// Returns true if a record is found or false otherwise. virtual bool ReadAt(FdoPropertyValueCollection* key) = 0; /// \brief /// Provides an ad-hoc access to the query result. /// /// \remarks /// The recordindex is the one-based nth item in the query result. /// If successful, this method will position the reader at the feature identified by the recordindex. /// /// \param recordindex /// The index of the row. /// /// \return /// Returns true if a record is found or false otherwise. virtual bool ReadAtIndex( unsigned int recordindex ) = 0; /// \brief /// Given a key of a feature, IndexOf will return the one based index or the record number of the feature within /// the returned query result. /// \remarks /// If the record is not found, then zero is retuned. /// This is the mirror function of the GetAtIndex function. /// This method does not affect the reader position. /// GetAtIndex need to be called to move the reader to the returned index. /// /// \param key /// The key that identifies a record. /// /// \return /// Returns true if a record is found or false otherwise. virtual unsigned int IndexOf(FdoPropertyValueCollection* key) = 0; }; }}} === Example === {{{ FdoPtr select = (FdoIExtendedSelect*)connection>CreateCommand(FdoCommandType_ExtendedSelect); select->SetFeatureClassName(L"World_Countries"); FdoPtrselecProperties = select>GetPropertyNames(); selecProperties->Add(FdoPtr(FdoIdentifier::Create(L"MAPKEY")) ); selecProperties->Add(FdoPtr(FdoIdentifier::Create(L"NAME")) ); selecProperties->Add(FdoPtr(FdoIdentifier::Create(L"KEY")) ); selecProperties->Add(FdoPtr(FdoIdentifier::Create(L"Autogenerated_ID")) ); FdoPtr orders = select->GetOrdering(); orders->Add( FdoPtr(FdoIdentifier::Create(L"NAME"))); orders->Add( FdoPtr(FdoIdentifier::Create(L"Autogenerated_ID"))); select->SetOrderingOption(L"Autogenerated_ID",FdoOrderingOption_Descending); FdoPtrreader = select->Execute(); if( reader->ReadLast() ) do { // get data using the FdoIFeatureReader accessors } while( reader->ReadPrevious() ); }}} == Test Plan == Test new APIs to validate correct functionality with SDF, SHP, and SQLite providers. == Funding/Resources == Autodesk