<p>I have generated Java code that can set up a dynamically created data set from a MySQL stored procedure source.</p>
<p>The data from the data set is plotted with a chart, again scripted in Java.</p>
<p> </p>
<p>The problem is that to do the binding I need to know how many columns there are.</p>
<p>That info is dynamic, it changes from one plot to the next. If I cheat and tell my code the number of columns to expect I can get it all to work.</p>
<p> </p>
<p>I've searched both the "Field Guide" & "Integrating and Extending BIRT" books, but I find they don't explain things very well.</p>
<p>I've also searched the web and found a bunch of code to play with but no luck so far.</p>
<p>Here's my latest bit of experimental code to try to do it, but my logging (using Eclipsec) shows odaResultSetColumns as always null.</p>
<p> </p>
<p><strong>How and when does odaResultSetColumns get populated?</strong></p>
<p> </p>
<p>For data sets created in the normal GUI way I can get the column names by iterating through reportDesignHandle.getDataSets().get(set_count).getPropertyIterator() and testing the structures, but that info again is not available in the dynamic case.</p>
<p> </p>
<p><strong>Can the binding be deferred to a later event where the data set info appears?</strong></p>
<pre class="_prettyXprint">
/**
* This method is called from the onPrepare method for a label in my BIRT rptdesign.
* Used on the MySQL stored procedure that gets the plot data.
* The data set is dynamically created and everything works fine (data set being read and a chart plotted) so long as I know "y_count" a priori.
* TODO Set y_count by dynamically counting the number of columns in the JDBC result set from the MySQL stored procedure call (where resultSetNumber = 2 i.e. the second result set).
* Once I have y_count I can set up the binding between the data set and the chart.
* Returns the number of y sequence columns.
*/
public int extractColumnInfo() throws Exception {
int y_count = 3;
// Fetching list of all data sets in the report.
@SuppressWarnings("unchecked")
ArrayList<OdaDataSetHandle> odaDataSetHandles = (ArrayList<OdaDataSetHandle>) reportDesignHandle.getAllDataSets();
System.out.println("odaDataSetHandles " + odaDataSetHandles);
for (OdaDataSetHandle odaDataSetHandle : odaDataSetHandles) {
OdaDataSet odaDataSet = (OdaDataSet) odaDataSetHandle.getElement();
System.out.println("odaDataSet.getName() " + odaDataSet.getName());
if (odaDataSet.getName().contentEquals(dataSetName_s)) { // private String dataSetName_s = "Sequence info";
dataSetImpl = SimpleElementFactory.getInstance().createDataSet( odaDataSetHandle );
List colList = dataSetImpl.getCachedResultSetColumns();
System.out.println("colList " + colList);
// CURRENTLY colList IS ALWAYS null.
@SuppressWarnings("unchecked")
ArrayList<OdaResultSetColumn> odaResultSetColumns = (ArrayList<OdaResultSetColumn>) odaDataSet.getLocalProperty(reportDesignHandle.getModuleHandle().getModule(), DataSetHandle.RESULT_SET_PROP);
System.out.println("odaResultSetColumns " + odaResultSetColumns);
// CURRENTLY odaResultSetColumns IS ALWAYS null.
PropertyHandle resultSet;
resultSet = odaDataSetHandle.getPropertyHandle(DataSetHandle.RESULT_SET_PROP);
System.out.println("resultSet " + resultSet);
System.out.println("resultSet.getContents() " + resultSet.getContents());
if (odaResultSetColumns != null) {
for (OdaResultSetColumn odaResultSetColumn : odaResultSetColumns) {
System.out.println("odaResultSetColumn.getColumnName() " + odaResultSetColumn.getColumnName());
System.out.println("odaResultSetColumn.getDataType() " + odaResultSetColumn.getDataType());
// Code examples from the web typically proceed like this.
// N.B. I don't want to set these. I want to acquire the column names used in my dynamically created ODA data set so I can count them.
// odaResultSetColumn.setColumnName("SOME_COLUMN_NAME");
// odaResultSetColumn.setNativeName("SOME_COLUMN_NAME");
// odaResultSetColumn.setDataType("integer");
// odaResultSetColumn.setPosition(1);
// odaResultSetColumn.setNativeDataType(4);
// resultSet.addItem(odaResultSetColumn);
//
// // The same thing with columnHints.
// ColumnHint resultHint = new ColumnHint();
// resultHint.setProperty(ColumnHint.COLUMN_NAME_MEMBER, "EMPLOYEENUMBER");
// resultHint.setProperty(ColumnHint.COLUMN_NAME_MEMBER, "integer");
// odaDataSetHandle.getPropertyHandle(DataSetHandle.COLUMN_HINTS_PROP).addItem(resultHint);
//
// //reportDesignHandle.getDataSets().add(dataSet);
}
}
}
}
return (y_count);
}
//
// Various chunks of code from the web that I've tried
//
// Connection conn = DriverManager.getConnection("jdbc:mysql://myURL:myPORT/sim", "sim", "");
// System.out.println("Got Connection.");
// Statement st = conn.createStatement();
// st.executeUpdate("");
//
// ResultSet rsColumns = null;
// DatabaseMetaData meta = conn.getMetaData();
// rsColumns = meta.getColumns(null, null, null, null);
// while (rsColumns.next()) {
// System.out.println(rsColumns.getString("TYPE_NAME"));
// System.out.println(rsColumns.getString("COLUMN_NAME"));
// }
// st.close();
// conn.close();
//
// private static void extractColumnInfo(OdaDataSetHandle odaDataSetHandle) throws Exception {
// // Cannot figure out how to make this following code work.
// // I want to see if we have a working handle to the stored procedure call data set.
//
// int rowcount = 0;
// // Configure the Engine and start the Platform.
// DesignConfig config = new DesignConfig();
//
// config.setBIRTHome("C:/birt/birt-runtime-2_6_1/birt-runtime-2_6_1/ReportEngine");
// IDesignEngine engine = null;
//
// OdaDataSourceDesign odaDataSource;
// DataEngineContext some_c = null;
// DataEngine de = DataEngine.newDataEngine(runnable.getReportEngine().getConfig(), some_c);
//
// de = DataEngine.newDataEngine(config, null);
// de.defineDataSource(odaDataSource);
// //de.defineDataSource(dsHandle_2.getDesign());
// de.defineDataSet(odaDataSetHandle.getElement());
// //de.defineDataSet(reportDesignHandle.getDataSets().get(set_count));
//
// QueryDefinition queryDefinition = new QueryDefinition();
// queryDefinition.setDataSetName(odaDataSetHandle.getElement().getName());
// //queryDefinition.setDataSetName(reportDesignHandle.getDataSets().get(set_count).getName());
// queryDefinition.setAutoBinding(true);
//
// IPreparedQuery pq = de.prepare(queryDefinition);
// IQueryResults qr = pq.execute(null);
//
// org.eclipse.birt.data.engine.api.IResultIterator ri = qr.getResultIterator();
// int cc = ri.getResultMetaData().getColumnCount();
// IResultMetaData rsmd = ri.getResultMetaData();
//
// while (ri.next()) {
// for (int i = 0; i < cc; i++)
// System.out.print(ri.getValue(rsmd.getColumnName(i + 1)) + " ");
// System.out.println("");
// rowcount++;
// }
// System.out.println("rowcount: " + String.valueOf(rowcount));
//
// ri.close();
// qr.close();
// de.shutdown();
// }
//
// int colNum = colList.size();
// var mytable = rC.getDesignHandle().findElement(dataSetName_s);
// try{itr= colList.iterator();
// colNr = 0;
// while(itr.hasNext()){
// col = itr.next();
// colname = col.getName(); // skip column from sourceTable
// if(colname.equals("Row ID")){continue;}
// // the first column should be just overwritten
// // this way we can define the format in the layout
// // unfortunately I still don't know how to do that one...
// if(colNr == 0){
// } else { // insert column to the right (1) mytable.insertColumn(colNr,1);
// datacell = mytable.getDetail().get(0).getCells().get(colNr );
// var newdata = reportDesignHandle.getDesignHandle().getElementFactory().newDataItem( colname );
// newdata.setResultSetColumn( colname );
// datacell.getContent().add(newdata);
// var myHeader = mytable.getHeader().get(0).getCells().get(colNr);
// var newlabel = reportDesignHandle.getDesignHandle().getElementFactory().newLabel( null );
// newlabel.setText( colname );
// myHeader.getContent().add(newlabel);
// }
// colNr ++;
// }
// }catch(err){}
//
//Bind data set to table
//rptTable.setProperty(IReportItemModel.DATA_SET_PROP, "Data Set"); //Bind data set to table
// String columnNamesArray[]; //Set name array
// Iterator iterator = odaDataSetHandle.getListProperty(DataSetHandle.RESULT_SET_PROP).iterator(); //Get data set iterator
// while (iterator.hasNext()) { //Loop through data set
// rsHandle = iterator.next(); //Set next handle
// columnNamesArray.push(rsHandle.getColumnName()); //Add column name to array
// col = StructureFactory.createComputedColumn(); //Create an empty computed column structure
// col.setName(rsHandle.getColumnName()); //Set the column name
// col.setExpression("dataSetRow[\"" + rsHandle.getColumnName() + "\"]"); //Set the expression
// rptTable.getColumnBindings().addItem(col); //Add column binding to table
// }
//
</pre>