Skip to content

Commit 7a6424f

Browse files
committed
Added some utility methods on jdbc datasource
1 parent 6c537f3 commit 7a6424f

File tree

2 files changed

+81
-8
lines changed

2 files changed

+81
-8
lines changed

lib/jdbc-custom-data-source.jar

32 Bytes
Binary file not shown.

src/main/java/com/ibm/opl/customdatasource/JdbcCustomDataSource.java

Lines changed: 81 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)