@@ -39,8 +39,8 @@ private static class JdbcCustomDataSourcePublisher extends IloCustomOplPostProce
3939 JdbcConfiguration _config ;
4040
4141
42- JdbcCustomDataSourcePublisher (IloOplFactory factory , IloOplModel model , JdbcConfiguration config ) {
43- super (factory );
42+ JdbcCustomDataSourcePublisher (IloOplModel model , JdbcConfiguration config ) {
43+ super (IloOplFactory . getOplFactoryFrom ( model ) );
4444 _model = model ;
4545 _config = config ;
4646 }
@@ -60,25 +60,28 @@ public void customEndPostProcess() {
6060 *
6161 * @param xmlFile The xml configuration for the data source
6262 * @param model The OPL Model
63+ * @return the custom datasource
6364 */
64- public static void addDataSourceXMLConfig (String xmlFile , IloOplModel model ) throws IOException {
65+ public static JdbcCustomDataSource addDataSourceXMLConfig (String xmlFile , IloOplModel model ) throws IOException {
6566 JdbcConfiguration config = new JdbcConfiguration ();
6667 config .read (xmlFile );
67- addDataSource (config , model );
68+ return addDataSource (config , model );
6869 }
6970
7071 /**
7172 * Adds a custom data source to a model.
7273 *
7374 * @param config The JDBC configuration object
7475 * @param model The OPL Model
76+ * @return the custom datasource
7577 */
76- public static void addDataSource (JdbcConfiguration config , IloOplModel model ) {
78+ public static JdbcCustomDataSource addDataSource (JdbcConfiguration config , IloOplModel model ) {
7779 IloOplFactory factory = IloOplFactory .getOplFactoryFrom (model );
7880 IloOplModelDefinition definition = model .getModelDefinition ();
7981 JdbcCustomDataSource source = new JdbcCustomDataSource (config , factory , definition );
8082 model .addDataSource (source );
81- model .registerPostProcessListener (new JdbcCustomDataSourcePublisher (factory , model , config ));
83+ model .registerPostProcessListener (new JdbcCustomDataSourcePublisher (model , config ));
84+ return source ;
8285 }
8386
8487 /**
@@ -103,7 +106,7 @@ void fillNamesAndTypes(IloTupleSchema schema, String[] names, Type[] types) {
103106 names [i ] = columnName ;
104107 }
105108 }
106-
109+
107110 /**
108111 * Overrides the IloCustomOplDataSource method to read data when the model
109112 * is generated.
@@ -200,7 +203,62 @@ public void close() throws SQLException {
200203 }
201204 ResultSet getResult () { return rs ; }
202205 }
203-
206+
207+ /** Helper class to execute statements in an exception safe way.
208+ * Use the class via the following template:
209+ * <pre>
210+ final ExecuteStatement q = new ExecuteStatement("CREATE TABLE t (x INT, y STRING);");
211+ try {
212+ boolean result = q.getResult();
213+ ...
214+ }
215+ finally {
216+ q.close();
217+ }
218+ </pre>
219+ * If getResult() is true, the ResultSet can be retrieved using getResultSet().
220+ *
221+ * This will correctly clean up and release all resources no matter whether
222+ * an exception is throw or not.
223+ */
224+ private final class ExecuteStatement {
225+ private Connection conn = null ;
226+ private Statement stmt = null ;
227+ private boolean result = false ;
228+ private ResultSet rs = null ;
229+ public ExecuteStatement (String query ) throws SQLException {
230+ Connection conn = DriverManager .getConnection (_configuration .getUrl (),
231+ _configuration .getUser (),
232+ _configuration .getPassword ());
233+ Statement stmt = null ;
234+ ResultSet rs = null ;
235+ try {
236+ stmt = conn .createStatement ();
237+ result = stmt .execute (query );
238+ if (result )
239+ rs = stmt .getResultSet ();
240+ // Everything worked without problem. Transfer ownership of
241+ // the objects to the newly constructed instance.
242+ this .conn = conn ; conn = null ;
243+ this .stmt = stmt ; stmt = null ;
244+ this .rs = rs ; rs = null ;
245+ }
246+ finally {
247+ if ( rs != null ) rs .close ();
248+ if ( stmt != null ) stmt .close ();
249+ if ( conn != null ) conn .close ();
250+ }
251+ }
252+ public void close () throws SQLException {
253+ rs .close ();
254+ stmt .close ();
255+ conn .close ();
256+ }
257+ boolean getResult () { return result ; }
258+ ResultSet getResultSet () { return rs ; }
259+ }
260+
261+
204262 /** Read the scalar value for <code>name</code> from <code>query</code>.
205263 * <b>Note:</b> the function will just use the first value produced by
206264 * <code>query</code> and assign that to the element identified
@@ -319,4 +377,19 @@ public void readTupleSet(String name, String query) throws SQLException {
319377 q .close ();
320378 }
321379 }
380+
381+ /**
382+ * Utility method to execute a statement using the jdbc connection configured for this source
383+ * @param sql The SQL query or statement
384+ * @return true if the query or statement returned a ResultSet, false if it is an update count
385+ * or there are no results.
386+ */
387+ public boolean execute (String sql ) throws SQLException {
388+ ExecuteStatement s = new ExecuteStatement (sql );
389+ try {
390+ return s .getResult ();
391+ } finally {
392+ s .close ();
393+ }
394+ }
322395};
0 commit comments