Method: RPM::Transaction#commit

Defined in:
lib/rpm/transaction.rb

#commit {|CallbackData| ... } ⇒ Object

Performs the transaction. You can supply your own callback end

Examples:

transaction.commit
transaction.commit do |data|
end

Parameters:

  • flag (Number)

    Transaction flags, default RPM::TRANS_FLAG_NONE

  • filter (Number)

    Transaction filter, default RPM::PROB_FILTER_NONE

Yields:



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/rpm/transaction.rb', line 173

def commit(&user_callback)
  flags = RPM::C::TransFlags[:none]

  callback = Proc.new do |hdr, type, amount, total, key_ptr, data_ignored|
    key_id = key_ptr.address
    key = @keys.include?(key_id) ? @keys[key_id] : nil

    case
      when block_given?
        package = hdr.null? ? nil : Package.new(hdr)
        data = CallbackData.new(type, key, package, amount, total)
        user_callback.call(data)
      else
        RPM::C.rpmShowProgress(hdr, type, amount, total, key, data_ignored)
    end
  end
  # We create a callback to pass to the C method and we
  # call the user supplied callback from there
  #
  # The C callback expects you to return a file handle,
  # We expect from the user to get a File, which we
  # then convert to a file handle to return.
  callback = Proc.new do |hdr, type, amount, total, key_ptr, data_ignored|
    key_id = key_ptr.address
    key = @keys.include?(key_id) ? @keys[key_id] : nil

    case
      when block_given?
        package = hdr.null? ? nil : Package.new(hdr)
        data = CallbackData.new(type, key, package, amount, total)
        ret = user_callback.call(data)

        # For OPEN_FILE we need to do some type conversion
        # for certain callback types we need to do some
        case type
          when :inst_open_file
            # For :inst_open_file the user callback has to
            # return the open file
            if !ret.is_a?(::File)
              raise TypeError, "illegal return value type #{ret.class}. Expected File."
            end
            fdt = RPM::C.fdDup(ret.to_i)
            if (fdt.null? || RPM::C.Ferror(fdt) != 0)
              raise RuntimeError, "Can't use opened file #{data.key}: #{RPM::C.Fstrerror(fdt)}"
              RPM::C.Fclose(fdt) if not fdt.nil?
            else
              fdt = RPM::C.fdLink(fdt)
              @fdt = fdt
            end
            # return the (RPM type) file handle
            fdt
          when :inst_close_file
            fdt = @fdt
            RPM::C.Fclose(fdt)
            @fdt = nil
          else
            ret
        end
      else
        # No custom callback given, use the default to show progress
        RPM::C.rpmShowProgress(hdr, type, amount, total, key, data_ignored)
    end
  end

  rc = RPM::C.rpmtsSetNotifyCallback(@ptr, callback, nil)
  raise "Can't set commit callback" if rc != 0

  rc = RPM::C.rpmtsRun(@ptr, nil, :none)

  raise "#{self}: #{RPM::C.rpmlogMessage}" if rc < 0

  if rc > 0
    ps = RPM::C.rpmtsProblems(@ptr)
    psi = RPM::C.rpmpsInitIterator(ps)
    while (RPM::C.rpmpsNextIterator(psi) >= 0)
      problem = Problem.from_ptr(RPM::C.rpmpsGetProblem(psi))
      STDERR.puts problem
    end
    RPM::C.rpmpsFree(ps)
  end
end