class RPM::Transaction
Public Class Methods
Source
# File lib/rpm/transaction.rb, line 19 def initialize(opts={}) # http://markmail.org/message/ypsiqxop442p7rzz # The key pointer needs to stay valid during commit # so we keep a reference to them mapping from # object_id to ruby object. @keys = {} opts[:root] ||= '/' @ptr = ::FFI::AutoPointer.new(RPM::C.rpmtsCreate, Transaction.method(:release)) RPM::C.rpmtsSetRootDir(@ptr, opts[:root]) end
Source
# File lib/rpm/transaction.rb, line 15 def self.release(ptr) RPM::C.rpmtsFree(ptr) end
Public Instance Methods
Source
# File lib/rpm/transaction.rb, line 146 def check rc = RPM::C.rpmtsCheck(@ptr) probs = RPM::C.rpmtsProblems(@ptr) return if rc < 0 begin psi = RPM::C.rpmpsInitIterator(probs) while (RPM::C.rpmpsNextIterator(psi) >= 0) problem = Problem.from_ptr(RPM::C.rpmpsGetProblem(psi)) yield problem end ensure RPM::C.rpmpsFree(probs) end end
Source
# File lib/rpm/transaction.rb, line 142 def clean RPM::C.rpmtsClean(@ptr) end
Free memory needed only for dependency checks and ordering.
Source
# 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
Performs the transaction. @param [Number] flag Transaction
flags, default RPM::TRANS_FLAG_NONE
@param [Number] filter Transaction
filter, default RPM::PROB_FILTER_NONE
@example
transaction.commit
You can supply your own callback @example
transaction.commit do |data| end
end @yield [CallbackData] sig Transaction
progress
Source
# File lib/rpm/transaction.rb, line 256 def db RPM::DB.new(self) end
@return [DB] the database associated with this transaction
Source
# File lib/rpm/transaction.rb, line 92 def delete(pkg) iterator = case pkg when Package pkg[:sigmd5] ? each_match(:sigmd5, pkg[:sigmd5]) : each_match(:label, pkg[:label]) when String each_match(:label, pkg) when Dependency each_match(:label, pkg.name).set_iterator_version(pkg.version) else raise TypeError, "illegal argument type" end iterator.each do |header| ret = RPM::C.rpmtsAddEraseElement(@ptr, header.ptr, iterator.offset) raise RuntimeError, "Error while adding erase/#{pkg} to transaction" if ret != 0 end end
Add a delete operation to the transaction @param [String, Package
, Dependency] pkg Package
to delete
Source
# File lib/rpm/transaction.rb, line 72 def each(&block) each_match(0, nil, &block) end
@yield [Package] Called for each package in the database @example
db.each do |pkg| puts pkg.name end
Source
# File lib/rpm/transaction.rb, line 57 def each_match(key, val, &block) it = init_iterator(key, val) return it unless block_given? it.each(&block) end
@yield [Package] Called for each match @param [Number] key RPM
tag key @param [String] val Value to match @example
RPM.transaction do |t| t.each_match(RPM::TAG_ARCH, "x86_64") do |pkg| puts pkg.name end end
Source
# File lib/rpm/transaction.rb, line 122 def flags=(fl) RPM::C.rpmtsSetFlags(@ptr, fl) end
Source
# File lib/rpm/transaction.rb, line 32 def init_iterator(tag, val) raise TypeError if (val && !val.is_a?(String)) it_ptr = RPM::C.rpmtsInitIterator(@ptr, tag.nil? ? 0 : tag, val, 0) raise "Can't init iterator for [#{tag}] -> '#{val}'" if it_ptr.null? return MatchIterator.from_ptr(it_ptr) end
@return [RPM::MatchIterator] Creates an iterator for tag
and val
Source
# File lib/rpm/transaction.rb, line 79 def install(pkg, key) install_element(pkg, key, :upgrade => false) end
Add a install operation to the transaction @param [Package] pkg Package
to install @param [String] key e.g. filename where to install from
Source
# File lib/rpm/transaction.rb, line 137 def order RPM::C.rpmtsOrder(@ptr) end
Determine package order in the transaction according to dependencies
The final order ends up as installed packages followed by removed packages, with packages removed for upgrades immediately following the new package to be installed.
@returns [Fixnum] no. of (added) packages that could not be ordered
Source
# File lib/rpm/transaction.rb, line 118 def root_dir RPM::C.rpmtsRootDir(@ptr) end
@return [String ] the root directory for this transaction
Source
# File lib/rpm/transaction.rb, line 112 def root_dir=(dir) rc = RPM::C.rpmtsSetRootDir(@ptr, dir) raise "Can't set #{dir} as root directory" if rc < 0 end
Sets the root directory for this transaction @param [String] root directory
Source
# File lib/rpm/transaction.rb, line 86 def upgrade(pkg, key) install_element(pkg, key, :upgrade => true) end
Add an upgrade operation to the transaction @param [Package] pkg Package
to upgrade @param [String] key e.g. filename where to install from
Private Instance Methods
Source
# File lib/rpm/transaction.rb, line 266 def install_element(pkg, key, opts={}) raise TypeError, "illegal argument type" if not pkg.is_a?(RPM::Package) raise ArgumentError, "#{self}: key '#{key}' must be unique" if @keys.include?(key.object_id) # keep a reference to the key as rpmtsAddInstallElement will keep a copy # of the passed pointer (we pass the object_id) @keys[key.object_id] = key ret = RPM::C.rpmtsAddInstallElement(@ptr, pkg.ptr, FFI::Pointer.new(key.object_id), opts[:upgrade] ? 1 : 0, nil) raise RuntimeError if ret != 0 nil end
@param [Package] pkg package to install @param [String] key e.g. filename where to install from @param opts options
@option :upgrade Upgrade packages if true