Skip to content

Commit a4949a7

Browse files
author
Daniel Junglas
committed
Add code to read scalar values.
This also adds a helper class to perform exception safe queries. This partly addresses issue #5.
1 parent 668f9b6 commit a4949a7

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

lib/jdbc-custom-data-source.jar

1.36 KB
Binary file not shown.

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

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,98 @@ public void customRead(String name, String query) throws SQLException {
150150
readSet(leaf, name, query);
151151
}
152152
}
153+
else if ( type == Type.INTEGER || type == Type.FLOAT || type == Type.STRING ) {
154+
readValue(name, query);
155+
}
156+
else
157+
throw new IllegalArgumentException("Cannot read element " + name + " of type " + type);
158+
}
159+
160+
/** Helper class to execute queries in an exception safe way.
161+
* Use the class via the following template:
162+
* <pre>
163+
final RunQuery q = new RunQuery("SELECT * FROM table;");
164+
try {
165+
ResultSet rs = q.getResult();
166+
...
167+
}
168+
finally {
169+
q.close();
170+
}
171+
</pre>
172+
* This will correctly clean up and release all resources no matter whether
173+
* an exception is throw or not.
174+
*/
175+
private final class RunQuery {
176+
private Connection conn = null;
177+
private Statement stmt = null;
178+
private ResultSet rs = null;
179+
public RunQuery(String query) throws SQLException {
180+
Connection conn = DriverManager.getConnection(_configuration.getUrl(),
181+
_configuration.getUser(),
182+
_configuration.getPassword());
183+
Statement stmt = null;
184+
ResultSet rs = null;
185+
try {
186+
stmt = conn.createStatement();
187+
rs = stmt.executeQuery(query);
188+
// Everything worked without problem. Transfer ownership of
189+
// the objects to the newly constructed instance.
190+
this.conn = conn; conn = null;
191+
this.stmt = stmt; stmt = null;
192+
this.rs = rs; rs = null;
193+
}
194+
finally {
195+
if ( rs != null ) rs.close();
196+
if ( stmt != null ) stmt.close();
197+
if ( conn != null ) conn.close();
198+
}
199+
}
200+
public void close() throws SQLException {
201+
rs.close();
202+
stmt.close();
203+
conn.close();
204+
}
205+
ResultSet getResult() { return rs; }
206+
}
207+
208+
/** Read the scalar value for <code>name</code> from <code>query</code>.
209+
* <b>Note:</b> the function will just use the first value produced by
210+
* <code>query</code> and assign that to the element identified
211+
* by <code>name</code>. If the query produces more than one
212+
* value the surplus values are ignored.
213+
* @param name The name of the element to fill.
214+
* @param query The SQL query that produces the data for <code>name</code>.
215+
* @throws SQLException if querying the database fails or the query does
216+
* not produce at least one value.
217+
*/
218+
public void readValue(String name, String query) throws SQLException {
219+
IloOplElementDefinition def = _def.getElementDefinition(name);
220+
IloOplDataHandler handler = getDataHandler();
221+
final RunQuery q = new RunQuery(query);
222+
try {
223+
ResultSet rs = q.getResult();
224+
rs.next();
225+
handler.startElement(name);
226+
Type type = def.getElementDefinitionType();
227+
if (type == Type.INTEGER) {
228+
handler.addIntItem(rs.getInt(1));
229+
}
230+
else if (type == Type.FLOAT) {
231+
handler.addNumItem(rs.getDouble(1));
232+
}
233+
else if (type == Type.STRING) {
234+
handler.addStringItem(rs.getString(1));
235+
}
236+
else
237+
throw new IllegalArgumentException("Cannot load element " + name + " of type " + type);
238+
handler.endElement();
239+
}
240+
finally {
241+
// We don't use try-with-resources so that we can compile
242+
// with pre-1.8 compilers as well.
243+
q.close();
244+
}
153245
}
154246

155247
public void readSet(Type leaf, String name, String query) {

0 commit comments

Comments
 (0)