def execute_batch *types
    types = [:delete, :insert, :update] if types.empty?

    Hash.new { 0 }.tap { |cnts|
      types.each do |type|
        raise ArgumentError.new("Invalid type: #{type}") unless @pstmts.has_key?(type)
        cnts[type] += @pstmts[type].values.map(&:execute_batch).select { |e| e > 0 }.inject(:+) || 0
      end
    }
  end
def execute_batch *types
    types = [:delete, :insert, :update] if types.empty?

    Hash.new { 0 }.tap { |cnts|
      types.each do |type|
        raise ArgumentError.new("Invalid type: #{type}") unless @pstmts.has_key?(type)
        cnts[type] += @pstmts[type].values.map(&:execute_batch).select { |e| e > 0 }.inject(:+) || 0
      end
    }
  end
Execute batched operations.
 TableWrapper uses multiple PreparedStatements and each of them may have its own homogeneous batched commands.
 It is thus not possible for TableWrapper to precisely serialize all the commands when interleaved.
 What you can do here is to specify the types of commands (:insert, :update, and :delete) in the order of execution.
 The default is to execute deletes first, then updates, and finally inserts.
 You can also execute a subset of the three types.
 @param [*Symbol] types Types of batched operations to execute in order.
   If not given, :delete, :insert and :update.
 @return [Hash] Sum of all update counts indexed by operation type