use of org.jooq.exception.ControlFlowSignal in project jOOQ by jOOQ.
the class AbstractQuery method execute.
@Override
public final int execute() {
if (isExecutable()) {
// Get the attached configuration of this query
Configuration c = configuration();
// [#1191] The following triggers a start event on all listeners.
// This may be used to provide jOOQ with a JDBC connection,
// in case this Query / Configuration was previously
// deserialised
DefaultExecuteContext ctx = new DefaultExecuteContext(c, this);
ExecuteListener listener = new ExecuteListeners(ctx);
int result = 0;
try {
// [#385] If a statement was previously kept open
if (keepStatement() && statement != null) {
ctx.sql(rendered.sql);
ctx.statement(statement);
// [#3191] Pre-initialise the ExecuteContext with a previous connection, if available.
ctx.connection(c.connectionProvider(), statement.getConnection());
} else // [#385] First time statement preparing
{
listener.renderStart(ctx);
rendered = getSQL0(ctx);
ctx.sql(rendered.sql);
listener.renderEnd(ctx);
rendered.sql = ctx.sql();
// ControlFlowSignals are thrown
if (ctx.connection() == null) {
throw new DetachedException("Cannot execute query. No Connection configured");
}
listener.prepareStart(ctx);
prepare(ctx);
listener.prepareEnd(ctx);
statement = ctx.statement();
}
// [#1856] [#4753] Set the query timeout onto the Statement
int t = SettingsTools.getQueryTimeout(timeout, ctx.settings());
if (t != 0) {
ctx.statement().setQueryTimeout(t);
}
if (// QueryParts may override this behaviour!
executePreparedStatements(c.settings()) && // [#1520] Renderers may enforce static statements, too
!Boolean.TRUE.equals(ctx.data(DATA_FORCE_STATIC_STATEMENT))) {
listener.bindStart(ctx);
if (rendered.bindValues != null)
using(c).bindContext(ctx.statement()).visit(rendered.bindValues);
listener.bindEnd(ctx);
}
result = execute(ctx, listener);
return result;
}// [#3427] ControlFlowSignals must not be passed on to ExecuteListners
catch (ControlFlowSignal e) {
throw e;
} catch (RuntimeException e) {
ctx.exception(e);
listener.exception(ctx);
throw ctx.exception();
} catch (SQLException e) {
ctx.sqlException(e);
listener.exception(ctx);
throw ctx.exception();
} finally {
// [#2385] Successful fetchLazy() needs to keep open resources
if (!keepResultSet() || ctx.exception() != null) {
Tools.safeClose(listener, ctx, keepStatement());
}
if (!keepStatement()) {
statement = null;
rendered = null;
}
}
} else {
if (log.isDebugEnabled())
log.debug("Query is not executable", this);
return 0;
}
}
use of org.jooq.exception.ControlFlowSignal in project jOOQ by jOOQ.
the class DefaultBinding method pgGetArray.
/**
* Workarounds for the unimplemented Postgres JDBC driver features
*/
@SuppressWarnings("unchecked")
private static final <T> T pgGetArray(Scope ctx, ResultSet rs, Class<T> type, int index) throws SQLException {
// Get the JDBC Array and check for null. If null, that's OK
Array array = null;
try {
array = rs.getArray(index);
if (array == null) {
return null;
}
// Try fetching a Java Object[]. That's gonna work for non-UDT types
try {
// [#5586] [#5613] TODO: Improve PostgreSQL array deserialisation.
if (byte[][].class == type)
throw new ControlFlowSignal("GOTO the next array deserialisation strategy");
else
return (T) convertArray(array, (Class<? extends Object[]>) type);
}// This might be a UDT (not implemented exception...)
catch (Exception e) {
List<Object> result = new ArrayList<Object>();
ResultSet arrayRs = null;
// Try fetching the array as a JDBC ResultSet
try {
arrayRs = array.getResultSet();
while (arrayRs.next()) {
DefaultBindingGetResultSetContext<T> out = new DefaultBindingGetResultSetContext<T>(ctx.configuration(), ctx.data(), arrayRs, 2);
new DefaultBinding<T, T>(Converters.identity((Class<T>) type.getComponentType()), false).get(out);
result.add(out.value());
}
}// That might fail too, then we don't know any further...
catch (Exception fatal) {
String string = null;
try {
string = rs.getString(index);
} catch (SQLException ignore) {
}
log.error("Cannot parse array", string, fatal);
return null;
} finally {
safeClose(arrayRs);
}
return (T) convertArray(result.toArray(), (Class<? extends Object[]>) type);
}
} finally {
safeFree(array);
}
}
use of org.jooq.exception.ControlFlowSignal in project jOOQ by jOOQ.
the class BatchMultiple method execute.
static int[] execute(final Configuration configuration, final Query[] queries) {
ExecuteContext ctx = new DefaultExecuteContext(configuration, queries);
ExecuteListener listener = new ExecuteListeners(ctx);
Connection connection = ctx.connection();
try {
ctx.statement(new SettingsEnabledPreparedStatement(connection));
String[] batchSQL = ctx.batchSQL();
for (int i = 0; i < queries.length; i++) {
listener.renderStart(ctx);
batchSQL[i] = DSL.using(configuration).renderInlined(queries[i]);
listener.renderEnd(ctx);
}
for (String sql : batchSQL) {
ctx.sql(sql);
listener.prepareStart(ctx);
ctx.statement().addBatch(sql);
listener.prepareEnd(ctx);
ctx.sql(null);
}
listener.executeStart(ctx);
int[] result = ctx.statement().executeBatch();
int[] batchRows = ctx.batchRows();
for (int i = 0; i < batchRows.length && i < result.length; i++) batchRows[i] = result[i];
listener.executeEnd(ctx);
return result;
}// [#3427] ControlFlowSignals must not be passed on to ExecuteListners
catch (ControlFlowSignal e) {
throw e;
} catch (RuntimeException e) {
ctx.exception(e);
listener.exception(ctx);
throw ctx.exception();
} catch (SQLException e) {
ctx.sqlException(e);
listener.exception(ctx);
throw ctx.exception();
} finally {
Tools.safeClose(listener, ctx);
}
}
use of org.jooq.exception.ControlFlowSignal in project jOOQ by jOOQ.
the class BatchSingle method executePrepared.
private final int[] executePrepared() {
ExecuteContext ctx = new DefaultExecuteContext(configuration, new Query[] { query });
ExecuteListener listener = new ExecuteListeners(ctx);
Connection connection = ctx.connection();
// [#1371] fetch bind variables to restore them again, later
// [#3940] Don't include inlined bind variables
// [#4062] Make sure we collect also repeated named parameters
ParamCollector collector = new ParamCollector(configuration, false);
collector.visit(query);
List<Param<?>> params = new ArrayList<Param<?>>();
for (Entry<String, Param<?>> entry : collector.resultList) params.add(entry.getValue());
DataType<?>[] paramTypes = dataTypes(params.toArray(EMPTY_FIELD));
try {
listener.renderStart(ctx);
// [#1520] TODO: Should the number of bind values be checked, here?
ctx.sql(create.render(query));
listener.renderEnd(ctx);
listener.prepareStart(ctx);
ctx.statement(connection.prepareStatement(ctx.sql()));
listener.prepareEnd(ctx);
for (Object[] bindValues : allBindValues) {
listener.bindStart(ctx);
// [#1371] [#2139] Don't bind variables directly onto statement, bind them through the collected params
// list to preserve type information
// [#3547] The original query may have no Params specified - e.g. when it was constructed with
// plain SQL. In that case, infer the bind value type directly from the bind value
visitAll(new DefaultBindContext(configuration, ctx.statement()), (paramTypes.length > 0) ? fields(bindValues, paramTypes) : fields(bindValues));
listener.bindEnd(ctx);
ctx.statement().addBatch();
}
listener.executeStart(ctx);
int[] result = ctx.statement().executeBatch();
int[] batchRows = ctx.batchRows();
for (int i = 0; i < batchRows.length && i < result.length; i++) batchRows[i] = result[i];
listener.executeEnd(ctx);
return result;
}// [#3427] ControlFlowSignals must not be passed on to ExecuteListners
catch (ControlFlowSignal e) {
throw e;
} catch (RuntimeException e) {
ctx.exception(e);
listener.exception(ctx);
throw ctx.exception();
} catch (SQLException e) {
ctx.sqlException(e);
listener.exception(ctx);
throw ctx.exception();
} finally {
Tools.safeClose(listener, ctx);
}
}
use of org.jooq.exception.ControlFlowSignal in project jOOQ by jOOQ.
the class AbstractRoutine method executeCallableStatement.
private final int executeCallableStatement() {
ExecuteContext ctx = new DefaultExecuteContext(configuration, this);
ExecuteListener listener = new ExecuteListeners(ctx);
try {
Connection connection = ctx.connection();
listener.renderStart(ctx);
// [#1520] TODO: Should the number of bind values be checked, here?
ctx.sql(create(configuration).render(this));
listener.renderEnd(ctx);
listener.prepareStart(ctx);
ctx.statement(connection.prepareCall(ctx.sql()));
// [#1856] TODO: Add Statement flags like timeout here
listener.prepareEnd(ctx);
listener.bindStart(ctx);
using(configuration).bindContext(ctx.statement()).visit(this);
registerOutParameters(ctx);
listener.bindEnd(ctx);
execute0(ctx, listener);
// http://tracker.firebirdsql.org/browse/JDBC-350
if (ctx.family() != FIREBIRD)
Tools.consumeResultSets(ctx, listener, results, null);
listener.outStart(ctx);
fetchOutParameters(ctx);
listener.outEnd(ctx);
return 0;
}// [#3427] ControlFlowSignals must not be passed on to ExecuteListners
catch (ControlFlowSignal e) {
throw e;
} catch (RuntimeException e) {
ctx.exception(e);
listener.exception(ctx);
throw ctx.exception();
} catch (SQLException e) {
ctx.sqlException(e);
listener.exception(ctx);
throw ctx.exception();
} finally {
Tools.safeClose(listener, ctx);
}
}
Aggregations