You may need at some point to implement your own data model because the implementations in Libgda don't suit your needs. This section is dedicated to explaining to you how this can be done.
Implementing a new GdaDataModel is simply a matter of creating a new GObject which implements the GdaDataModel interface, which is described below. Thos new class needs to inherit GObject, but needs not be direct descendant of it. The way to subclass an object using GLib is not covered in this documentation, for this matter reref to GObject's documentation, or online.
The interface's methods which can and/or need to be implemented are defined below.
This method, if implemented, returns the total number of rows in the data model, or -1 if unknown. If it's not implemented, then it is assumed that -1 is returned in all cases.
This method, returns the total number of columns in the data model, or -1 if unknown.
This method describes a column; it returns (without any ownership to the caller) a GdaColumn for each existing column, or NULL otherwise.
This method defines how the data model may be accessed (randomly, only using a cursor, ...)
This method is used to access the contents of a data model, specifically a GValue is returned for each (column,row) position. It must return NULL if the data model experienced an error for the specific (column,row) position. See gda_data_model_get_value_at() for more information about the lifetime of the returned GValue.
This method returns, for a (column,row) position in the data model, the attributes of the adressed "cell".
This method can be implemented to create specific GdaDataModelIter or to customize them.
This method can be implemented if a specific implementation allows an iterator to be moved quickly to a specific row (faster than iterating from row to row to the requested row).
This method is called to move an iterator to the next row; it's not necessary to implement it if the data models supports random access.
This method is called to move an iterator to the previous row. It is only necessary to implement it if the data model does not support random access and supports moving the cursor backward.
This method needs to be defined if the data model allows each value in a (column,row) position to be modified individually.
This method can be defined if a specific treatment is required when a modification made to a GdaDataModelIter is propagated to the data model. It should seldom, if ever, be necessary to implement it.
This method needs to be defined if the data model allows modifications to be made for one complete row at a time. See the gda_data_model_set_values() method for more information about the arguments
This method can be implemented if the data model needs to support adding a row and defining the values to be added in the same operation. See gda_data_model_append_values() for more information.
This method needs to be defined if the data model needs to support adding an empty row (i.e. without any value specified in the new row).
This method should be implemented if the data model needs to support row removal.
This method can be implemented if the data model implements an indexing scheme which allows it to find rows from values quickly than by analysing each row after another to find the requested values.
This method should be implemented if the data model needs to honor the gda_data_model_freeze() and gda_data_model_thaw() methods. If this method is not implemented, then these two methods will have no effect.
This method should be implemented if the data model needs to honor the gda_data_model_freeze() and gda_data_model_thaw() methods. If this method is not implemented, then these two methods will have no effect.
This method should be implemented if the data model needs to be able to treat hints, see gda_data_model_send_hint() for more information
This method needs to be implemented if the data model keeps exceptions about the errors it has encountered and may "export" these exceptions using the gda_data_model_get_exceptions() method.
When the data model changes, it needs to signal its changes. However, only the changes from the initial state need to be notified, in situations such as:
a row which has already been accessed is modified or removed
the total number of rows changes, and that number has already been obtained and was known (i.e. different than -1)
To signal changes, one of the following methods has to be used:
gda_data_model_row_inserted(): to be called after a row has been inserted
gda_data_model_row_updated(): to be called after a row has been updated
gda_data_model_row_removed(): to be called after a row has been removed
gda_data_model_reset(): to be called when the data model has changed in a way it's not possible or desirable to signal all the changes using any combination of the above methods (for example when the whole contents has changed, or when the number and/or types of columns has changed)
Moreover, when the data model's access flags have changed, the implementation should signal it by emitting the "access-changed" signal.