Edit: It’s come to my attention through @danielroy on twitter that the walkthrough I mention below is no longer available. Sorry about that! I’ve included what was the text of it at the bottom of this entry. Thank goodness for Google Docs
The last few days have been spent learning about and understanding the workings of the ODA plug-in. It’s fairly complicated, and the actual documentation on how it interacts with BIRT is sparse. So, among other things recently, I’ve put together a small document that basically does a walkthrough of the user’s interaction with BIRT and the ODA plug-in. It includes some of the main functions called, to give an idea of what kind of data is being created and requested at each step, using the FlatFile ODA plug-in as a basis. I’ve uploaded a copy of that at this link, though the original is part of a larger, growing document in Google Docs.
I believe that eventually, the (larger, currently growing) document will become quite helpful to those who are trying to build an ODA plug-in of their own. The document actually includes a lot of OpenMRS specifics, but I’d like to create a sort of partially genericized version eventually.
Other news of late includes me finally understanding how the OpenMRS database is accessed through the code. I’ll talk about that more some other time, as currently there’s still more I have to learn, such as how I can work through the Logic Service, and I feel it’d be an incomplete entry as of now. I don’t usually do this much planning before jumping into a coding project, but this is such a complex system that any coding I had written a week ago I’d likely want to throw away today. The project is progressing nevertheless.
————————————————–
Walkthrough of important functions and user actions
Document the request lifecycle (sort of a stacktrace) of how the csv runtime plug-in works.
- from when a user enters the information about a dataset
- to creating the query used to access data in the dataset
- to actually querying for data in the dataset
Break it up into discrete pieces to make it easier, but show me which classes and important methods are called.
:::::::::::::::
User starts Eclipse BIRT, creates new report, starts the new Data Source wizard.
User selects the data source they would like, clicks Next.
User fills in information (properties) of the data source.
User clicks “Test Connection” button, and the plug-in starts up:
FlatfilePlugin(Activator).start()
FlatFileDriver.getConnection()
Connection.isOpen()
Connection.open()
Connection.getMetaData() [DataSetMetaData]
DataSetMetaData.constructor()
DataSetMetaData.getDataSourceProductVersion()
DataSetMetaData.getDataSourceProductName()
DataSetMetaData.getDataSourceProductName()
DataSetMetaData.getDataSourceProductVersion() // not sure why these are called twice
Connection.isOpen()
Connection.close()
If the button is not clicked, nothing happens in the runtime driver.
User clicks Finish.
User starts new Data Set wizard. They select the correct Data Source and Data Set type and click Next.
To generate the custom UI present in the FlatFile plug-in, the plug-in is started up and data is grabbed.
FlatfilePlugin(Activator).start()
FlatFileDriver.getConnection()
Connection.open()
Connection.newQuery()
Connection.isOpen()
FlatFileQuery.constructor() // we are query for the column names and types and such.
FlatFileQuery.prepare() // in the FlatFile plug-in, this is passed “select * from feedstats.csv” at this point, where feedstats.csv was the default csv file in the directory
Connection.isOpen()
ResultSetMetaData.constructor()
FlatFileQuery.executeQuery()
ResultSet.constructor()
FlatFileQuery.getMetaData() [ResultSetMetaData]
ResultSetMetaData.getColumnSOMETHING()
ResultSetMetaData.getColumnSOMETHING()
…
ResultSetMetaData.getColumnSOMETHING() // a total of 43 calls to ResultSetMetaData
ResultSetMetaData.getColumnSOMETHING() // these are functions like getColumnCount, getColumnName…etc.
Connection.close()
User goes through the GUI and forms the query. In the FlatFile plug-in, this involves selecting columns.
User clicks next to finalize the query.
FlatFileDriver.getConnection()
Connection.open()
Connection.newQuery()
Connection.isOpen()
FlatFileQuery.constructor()
FlatFileQuery.prepare() // this is the actual query sent to the runtime driver, though not necessarily what will be sent to the server (or in this case the..file. here, it was: select “Date”, “Subscribers”, “Hits” from feedstats.csv : {“Date”,”Date”,STRING;”Subscribers”,”Subscribers”,STRING;”Hits”,”Hits”,STRING}
Connection.isOpen()
ResultSetMetaData.constructor()
FlatFileQuery.executeQuery()
ResultSet.constructor()
FlatFileQuery.getMetaData() [ResultSetMetaData]
ResultSetMetaData.getColumnSOMETHING()
ResultSetMetaData.getColumnSOMETHING()
…
ResultSetMetaData.getColumnSOMETHING() // 23 of these calls this time.
ResultSetMetaData.getColumnSOMETHING()
Connection.close()
User designs the report. I’ll just drag the data set directly to the blank report.
User builds the report. I’ll just “View Report as HTML.”
FlatFileDriver.getConnection()
Connection.isOpen()
Connection.open()
Connection.newQuery()
Connection.isOpen()
FlatFileQuery.constructor()
FlatFileQuery.prepare( select “Date”, “Subscribers”, “Hits” from feedstats.csv : {“Date”,”Date”,STRING;”Subscribers”,”Subscribers”,STRING;”Hits”,”Hits”,STRING} )
Connection.isOpen()
ResultSetMetaData.constructor()
FlatFileQuery.getMetaData() [ResultSetMetaData]
ResultSetMetaData.getColumnSOMETHING()
ResultSetMetaData.getColumnSOMETHING()
…
ResultSetMetaData.getColumnSOMETHING()
ResultSetMetaData.getColumnSOMETHING() // 25 of these
FlatFileQuery.executeQuery()
ResultSet.constructor()
Connection.isOpen()
ResultSet.next()
ResultSetMetaData.getColumnSOMETHING()
ResultSetMetaData.getColumnSOMETHING()
…
ResultSetMetaData.getColumnSOMETHING()
ResultSetMetaData.getColumnSOMETHING() // 120 of these!
Connection.isOpen()
ResultSet.next()
Connection.isOpen()
ResultSet.next()
…
Connection.isOpen()
ResultSet.next()
Connection.isOpen() // 17 of these sets
ResultSet.next() // of 2 commands
ResultSetMetaData.getColumnSOMETHING()
FlatFileQuery.close()
Connection.isOpen()
Connection.close()
The report is generated.