The new datalist based navigation has following advantages:
Data source is not only jdbc. It should be possible to write data source handlers for all other data, e.g. xml.
Navigation should be independent from filtering. Navigation should be possible with free form select, too --i.e. use of a
whereClause should be ok.
To perform this goals the following points are done:
On the contrary to the classic navigation, where each request will result in an new query to the database with special selections to get the next/previous/first and last data, the new navigation system makes an query to the database only if an GotoEvent happens. This query context represented by an DataSource object is stored in the session context an will be reused if one of the other navigation events happens.
All navigation and database events use the DataSourceFactory class to retrieve an concrete implementation of the abstract DataSource class. The DataSourceFactory class gets takes the DataAccessClass attribute of the table class uses reflection to instanciate a new concrete implementation. If no DataAccessClass is given in table the DataSourceJDBC class is used. DataSourceJDBC is an implementation wich uses jdbc database access to get the data.
You can override this behaviour if you set the DataAccessClass in dbforms to another class.
<table name="line_flightbars" dataAccessClass="de.aucos.linedata.LineData" > <field name="flightbar_id" fieldType="integer" isKey="true" /> <field name="flightbartype" fieldType="char" /> <field name="flightbarstatus" fieldType="char" /> <field name="stationid" fieldType="integer" /> <field name="shuttleid" fieldType="integer" /> </table>
The abstract class DataSource is the base class for all data access. Retrieving data is done by four abstract methods which must be overloaded by implementing class:
protected abstract void open(): This method is called to open the resultset.
protected abstract int size(): This method must return the size of the whole resultset with all data fetch
protected abstract Object getRow(int i) This method must return the row at special index as an Object
protected abstract int findStartRow(String startRow) This method gets the index of an row given by the special DbForms startrow string, This string has the format FieldID ":" Length ":" Value example: if key id = 121 and field id=2 then keyValueStr contains "2:3:121" if the key consists of more than one fields, the key values are seperated through "-" example: value of field 1=12, value of field 3=1992, then we'll get "1:2:12-3:4:1992"
This methods are called by the DataSource methods getCurrent, getFirst, getPrev, getNext and getLast. This datasource methods are called indirect by the DataSourceFactory during service of the navigation events.
To insert/update/delete data exists empty methods doInsert/doUpdate/doDelete which could be overloaded by the implementing classes. This method are called indirect by the DataSourceFactory which is called through the insert/update/delete events of the datalist events.
The class DataSourceJDBC is an implementation of the DataSource class which retrieves data from JDBC data sources. doInsert/doUpdate/doDelete are implemented and do there work via SQL statements for insert/update/delete. The interesting part is retrieving of the data. This is done by a simplified data list handler pattern:
protected abstract void open():
This method just creates an java.SQL.Resultset and stores it in the class.
protected abstract int size():
This method first retrieves all data sets of the current java.SQL.Resultset, storing them in the internal data vector and returns then the size of the internal data vector.
protected abstract Object getRow(int i)
This method first tries to lookup the requested row in the data vector. This could be done, if the requested row is less then the current size of the data vector. If the requested row is outside the data vector the method will retrieve the next records from the java.SQL.Resultset up to the time, the size of the data vector is equal to the retrieved row or no more records are found.
protected abstract int findStartRow(String startRow)
To do the mapping of the DbForms key string a second vector is used. This vector stores all key value strings of each row from the java.SQL.Resultset. So searching for the mapping is done in two tasks: First the startRow is searched by an linear search in the keys vector. If found, the index of the key vector is return as result. If the startRow is not found in the keys vector, data from the java.SQL.Resultset is retrieved and stored up to the moment the key string of the just retrieved row is equal to the search row or nomore data is found.