Example #1
0
  private final int[] executeStatic() {
    List<Query> queries = new ArrayList<Query>();
    QueryCollector collector = new QueryCollector();

    Configuration local =
        configuration.derive(
            Utils.combine(
                configuration.executeListenerProviders(),
                new DefaultExecuteListenerProvider(collector)));

    for (int i = 0; i < records.length; i++) {
      Configuration previous = ((AttachableInternal) records[i]).configuration();

      try {
        records[i].attach(local);
        executeAction(i);
      } catch (QueryCollectorSignal e) {
        Query query = e.getQuery();

        if (query.isExecutable()) {
          queries.add(query);
        }
      } finally {
        records[i].attach(previous);
      }
    }

    // Resulting statements can be batch executed in their requested order
    int[] result = create.batch(queries).execute();
    updateChangedFlag();
    return result;
  }
Example #2
0
  private final int[] executeStatic() {
    List<Query> queries = new ArrayList<Query>();

    for (Object[] bindValues : allBindValues) {
      for (int i = 0; i < bindValues.length; i++) {
        query.bind(i + 1, bindValues[i]);
      }

      queries.add(create.query(query.getSQL(INLINED)));
    }

    return create.batch(queries).execute();
  }
Example #3
0
  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
    DataType<?>[] paramTypes = dataTypes(query.getParams().values().toArray(new Field[0]));

    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
        List<Field<?>> params =
            (paramTypes.length > 0) ? fields(bindValues, paramTypes) : fields(bindValues);

        visitAll(new DefaultBindContext(configuration, ctx.statement()), params);

        listener.bindEnd(ctx);
        ctx.statement().addBatch();
      }

      try {
        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;
      } finally {
        consumeWarnings(ctx, listener);
      }
    } 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 {
      Utils.safeClose(listener, ctx);
    }
  }
Example #4
0
  private final int[] executePrepared() {
    Map<String, List<Query>> queries = new LinkedHashMap<String, List<Query>>();
    QueryCollector collector = new QueryCollector();

    // Add the QueryCollector to intercept query execution after rendering
    Configuration local =
        configuration.derive(
            Utils.combine(
                configuration.executeListenerProviders(),
                new DefaultExecuteListenerProvider(collector)));

    // [#1537] Communicate with UpdatableRecordImpl
    local.data(Utils.DATA_OMIT_RETURNING_CLAUSE, true);

    // [#1529] Avoid DEBUG logging of single INSERT / UPDATE statements
    local.settings().setExecuteLogging(false);

    for (int i = 0; i < records.length; i++) {
      Configuration previous = ((AttachableInternal) records[i]).configuration();

      try {
        records[i].attach(local);
        executeAction(i);
      } catch (QueryCollectorSignal e) {
        Query query = e.getQuery();
        String sql = e.getSQL();

        // Aggregate executable queries by identical SQL
        if (query.isExecutable()) {
          List<Query> list = queries.get(sql);

          if (list == null) {
            list = new ArrayList<Query>();
            queries.put(sql, list);
          }

          list.add(query);
        }
      } finally {
        records[i].attach(previous);
      }
    }

    // Execute one batch statement for each identical SQL statement. Every
    // SQL statement may have several queries with different bind values.
    // The order is preserved as much as possible
    List<Integer> result = new ArrayList<Integer>();
    for (Entry<String, List<Query>> entry : queries.entrySet()) {
      BatchBindStep batch = create.batch(entry.getValue().get(0));

      for (Query query : entry.getValue()) {
        batch.bind(query.getBindValues().toArray());
      }

      int[] array = batch.execute();
      for (int i : array) {
        result.add(i);
      }
    }

    int[] array = new int[result.size()];
    for (int i = 0; i < result.size(); i++) {
      array[i] = result.get(i);
    }

    updateChangedFlag();
    return array;
  }