Ejemplo n.º 1
0
  private static <T> void writeToSQLOutput(
      SQLOutput stream, Class<? extends T> type, DataType<T> dataType, T value)
      throws SQLException {
    if (value == null) {
      stream.writeObject(null);
    } else if (type == Blob.class) {
      stream.writeBlob((Blob) value);
    } else if (type == Boolean.class) {
      stream.writeBoolean((Boolean) value);
    } else if (type == BigInteger.class) {
      stream.writeBigDecimal(new BigDecimal((BigInteger) value));
    } else if (type == BigDecimal.class) {
      stream.writeBigDecimal((BigDecimal) value);
    } else if (type == Byte.class) {
      stream.writeByte((Byte) value);
    } else if (type == byte[].class) {

      // [#1327] Oracle cannot serialise BLOBs as byte[] to SQLOutput
      // Use reflection to avoid dependency on OJDBC
      if (dataType.isLob()) {
        Blob blob = null;

        try {
          blob =
              on("oracle.sql.BLOB")
                  .call(
                      "createTemporary",
                      on(stream).call("getSTRUCT").call("getJavaSqlConnection").get(),
                      false,
                      on("oracle.sql.BLOB").get("DURATION_SESSION"))
                  .get();

          blob.setBytes(1, (byte[]) value);
          stream.writeBlob(blob);
        } finally {
          DefaultExecuteContext.register(blob);
        }
      } else {
        stream.writeBytes((byte[]) value);
      }
    } else if (type == Clob.class) {
      stream.writeClob((Clob) value);
    } else if (type == Date.class) {
      stream.writeDate((Date) value);
    } else if (type == Double.class) {
      stream.writeDouble((Double) value);
    } else if (type == Float.class) {
      stream.writeFloat((Float) value);
    } else if (type == Integer.class) {
      stream.writeInt((Integer) value);
    } else if (type == Long.class) {
      stream.writeLong((Long) value);
    } else if (type == Short.class) {
      stream.writeShort((Short) value);
    } else if (type == String.class) {

      // [#1327] Oracle cannot serialise CLOBs as String to SQLOutput
      // Use reflection to avoid dependency on OJDBC
      if (dataType.isLob()) {
        Clob clob = null;

        try {
          clob =
              on("oracle.sql.CLOB")
                  .call(
                      "createTemporary",
                      on(stream).call("getSTRUCT").call("getJavaSqlConnection").get(),
                      false,
                      on("oracle.sql.CLOB").get("DURATION_SESSION"))
                  .get();

          clob.setString(1, (String) value);
          stream.writeClob(clob);
        } finally {
          DefaultExecuteContext.register(clob);
        }
      } else {
        stream.writeString((String) value);
      }
    } else if (type == Time.class) {
      stream.writeTime((Time) value);
    } else if (type == Timestamp.class) {
      stream.writeTimestamp((Timestamp) value);
    } else if (type == YearToMonth.class) {
      stream.writeString(value.toString());
    } else if (type == DayToSecond.class) {
      stream.writeString(value.toString());
    }
    //        else if (type.isArray()) {
    //            stream.writeArray(value);
    //        }
    else if (UNumber.class.isAssignableFrom(type)) {
      stream.writeString(value.toString());
    } else if (ArrayRecord.class.isAssignableFrom(type)) {

      // [#1544] We can safely assume that localConfiguration has been
      // set on DefaultBindContext, prior to serialising arrays to SQLOut
      Connection connection = getDriverConnection(DefaultBindContext.LOCAL_CONFIGURATION.get());
      ArrayRecord<?> arrayRecord = (ArrayRecord<?>) value;
      stream.writeArray(
          on(connection)
              .call("createARRAY", arrayRecord.getName(), arrayRecord.get())
              .<Array>get());
    } else if (EnumType.class.isAssignableFrom(type)) {
      stream.writeString(((EnumType) value).getLiteral());
    } else if (MasterDataType.class.isAssignableFrom(type)) {
      Object key = ((MasterDataType<?>) value).getPrimaryKey();
      writeToSQLOutput(stream, key.getClass(), key);
    } else if (UDTRecord.class.isAssignableFrom(type)) {
      stream.writeObject((UDTRecord<?>) value);
    } else {
      throw new UnsupportedOperationException("Type " + type + " is not supported");
    }
  }
Ejemplo n.º 2
0
  @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());
        }

        // [#385] First time statement preparing
        else {
          listener.renderStart(ctx);
          rendered = getSQL0(ctx);
          ctx.sql(rendered.sql);
          listener.renderEnd(ctx);
          rendered.sql = ctx.sql();

          // [#3234] Defer initialising of a connection until the prepare step
          // This optimises unnecessary ConnectionProvider.acquire() calls when
          // 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 (

        // [#1145] Bind variables only for true prepared statements
        // [#2414] Even if parameters are inlined here, child
        //         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;
    }
  }