Search in sources :

Example 1 with ControlFlowSignal

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;
    }
}
Also used : Configuration(org.jooq.Configuration) SQLException(java.sql.SQLException) DetachedException(org.jooq.exception.DetachedException) ExecuteListener(org.jooq.ExecuteListener) ControlFlowSignal(org.jooq.exception.ControlFlowSignal)

Example 2 with ControlFlowSignal

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);
    }
}
Also used : SQLException(java.sql.SQLException) PostgresUtils.toPGArrayString(org.jooq.util.postgres.PostgresUtils.toPGArrayString) DataTypeException(org.jooq.exception.DataTypeException) SQLDialectNotSupportedException(org.jooq.exception.SQLDialectNotSupportedException) MappingException(org.jooq.exception.MappingException) SQLException(java.sql.SQLException) Array(java.sql.Array) MockArray(org.jooq.tools.jdbc.MockArray) ResultSet(java.sql.ResultSet) MockResultSet(org.jooq.tools.jdbc.MockResultSet) Arrays.asList(java.util.Arrays.asList) List(java.util.List) ArrayList(java.util.ArrayList) ControlFlowSignal(org.jooq.exception.ControlFlowSignal)

Example 3 with ControlFlowSignal

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);
    }
}
Also used : SQLException(java.sql.SQLException) Connection(java.sql.Connection) ExecuteContext(org.jooq.ExecuteContext) ExecuteListener(org.jooq.ExecuteListener) ControlFlowSignal(org.jooq.exception.ControlFlowSignal)

Example 4 with ControlFlowSignal

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);
    }
}
Also used : SQLException(java.sql.SQLException) Connection(java.sql.Connection) ArrayList(java.util.ArrayList) ExecuteContext(org.jooq.ExecuteContext) ExecuteListener(org.jooq.ExecuteListener) Param(org.jooq.Param) DataType(org.jooq.DataType) ControlFlowSignal(org.jooq.exception.ControlFlowSignal)

Example 5 with ControlFlowSignal

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);
    }
}
Also used : SQLException(java.sql.SQLException) Connection(java.sql.Connection) ExecuteContext(org.jooq.ExecuteContext) ExecuteListener(org.jooq.ExecuteListener) ControlFlowSignal(org.jooq.exception.ControlFlowSignal)

Aggregations

ControlFlowSignal (org.jooq.exception.ControlFlowSignal)6 SQLException (java.sql.SQLException)5 ExecuteListener (org.jooq.ExecuteListener)4 Connection (java.sql.Connection)3 ExecuteContext (org.jooq.ExecuteContext)3 ArrayList (java.util.ArrayList)2 Array (java.sql.Array)1 ResultSet (java.sql.ResultSet)1 Arrays.asList (java.util.Arrays.asList)1 List (java.util.List)1 Configuration (org.jooq.Configuration)1 DataType (org.jooq.DataType)1 WRITE (org.jooq.ExecuteType.WRITE)1 Param (org.jooq.Param)1 RecordListener (org.jooq.RecordListener)1 RecordListenerProvider (org.jooq.RecordListenerProvider)1 DataTypeException (org.jooq.exception.DataTypeException)1 DetachedException (org.jooq.exception.DetachedException)1 MappingException (org.jooq.exception.MappingException)1 SQLDialectNotSupportedException (org.jooq.exception.SQLDialectNotSupportedException)1