## Virtual methods for recordsets

This section explains how to write virtual methods for the GdaDataSelect subclasses implementations, which should be done when implementing a database provider.

That data model implementation simplifies the implementation of provider's recordsets by having them implement only a few virtual methods, and offering some services.

The data model represents each row in a separate GdaRow object, and virtual methods to retrieve rows have to return new (and correctly initialized) objects of that class. The referencing of these new objects is left up to the implementation which:

- can rely on the GdaRow implementation to keep them, using the gda_data_select_take_row () method for each row object created which is the easiest, the fastest as once created, the rows are available for further usage, but will consume more memory with each row read from the model.

- can keep the references to these objects to the subclass implementation which will consume less memory but will make it necessary to create a new row object each time a row is read which is slower

- can do a mix of the two solutions above: monitor the memory usage for the data model to enable to "cache" some rows and discard some when memory is needed

Note that the methods mentioned in the 1st and 3rd items should be reserved for random data access mode, and that cursor based access mode should implement the method mentioned in th 2nd item.

### fetch_nb_rows()

This method is called when the user calls gda_data_model_get_n_rows ().

Note that the number of rows of the data model may not be known until the cursor has reached the last row of the recordset. Once known, the number of rows can be stored in the `advertized_nrows`'s member of the GdaDataSelect object.

### fetch_random()

This method is called when the user calls gda_data_model_get_value_at (), and is used only when the data access mode for the data model is random (that is not cursor based) (i.e. when data access is cursor based, this method will not be called).

Also it is safe to assume that when called, the `prow` parameter will not be NULL, and that `*prow` is actually NULL.

### store_all()

This method is called when the user sets the "store-all-rows" to TRUE. It has the effect of forcing the creation of a GdaRow object for each row of the data model (thus increasing the memory consumption but reducing further access times). It is available only when the data access mode for the data model is random (that is not cursor based). When data access is cursor based, this method will not be called.

### fetch_next()

This method is called when data access is cursor based and a data model iterator is moved one position forward. The `rownum` is an indication of what the row number will be once the next row has been fetched (it can safely be discarded if that information is not necessary).

This method is not used when data is accessed in a random way. Also it is safe to assume that when called, the `prow` parameter will not be NULL, and that `*prow` is actually NULL.

### fetch_prev()

This method is called when data access is cursor based and a data model iterator is moved one position backward. The `rownum` is an indication of what the row number will be once the previous row has been fetched (it can safely be discarded if that information is not necessary). Implementing this method is not necessary if the data model does not support moving iterators backward.

This method is not used when data is accessed in a random way. Also it is safe to assume that when called, the `prow` parameter will not be NULL, and that `*prow` is actually NULL.

### fetch_at()

This method can be implemented (but it is not required) when data access is cursor based and there is a shorter way of getting to a specific row than having to call the fetch_next() or fetch_prev() methods several times.