table of contents
- NAME
- DESCRIPTION
- PERL SPECIFICS
- PYTHON SPECIFICS
- RUBY SPECIFICS
- THE SOLV CLASS
- THE POOL CLASS
- THE DEPENDENCY CLASS
- METHODS
- THE REPOSITORY CLASS
- THE SOLVABLE CLASS
- THE DATAITERATOR CLASS
- THE DATAMATCH CLASS
- THE SELECTION CLASS
- THE JOB CLASS
- THE SOLVER CLASS
- THE PROBLEM CLASS
- THE RULE CLASS
- THE RULEINFO CLASS
- THE SOLUTION CLASS
- THE SOLUTIONELEMENT CLASS
- THE TRANSACTION CLASS
- THE TRANSACTIONCLASS CLASS
- CHECKSUMS
- FILE MANAGEMENT
- THE REPODATA CLASS
- THE DATAPOS CLASS
- AUTHOR
LIBSOLV-BINDINGS(3) | LIBSOLV | LIBSOLV-BINDINGS(3) |
NAME¶
libsolv-bindings - access libsolv from perl/python/rubyDESCRIPTION¶
Libsolv’s language bindings offer an abstract, object orientated interface to the library. The supported languages are currently perl, python, and ruby. All example code (except in the specifics sections, of course) lists first the “C-ish” interface, then the syntax for perl, python, and ruby (in that order).PERL SPECIFICS¶
Libsolv’s perl bindings can be loaded with the following statement:use solv;
my $pool = solv::Pool->new(); my $repo = $pool->add_repo("my_first_repo");
$pool->{appdata} = 42; printf "appdata is %d\n", $pool->{appdata};
my $iter = $pool->solvables_iter(); for my $solvable (@$iter) { ... };
my @problems = $solver->solve(\@jobs);
print $dep->str() . "\n";
$pool->set_flag($solv::Pool::POOL_FLAG_OBSOLETEUSESCOLORS, 1);
PYTHON SPECIFICS¶
The python bindings can be loaded with:import solv
pool = solv.Pool() repo = pool.add_repo("my_first_repo")
pool.appdata = 42 print "appdata is %d" % (pool.appdata)
for solvable in pool.solvables_iter():
jobs = [] problems = solver.solve(jobs)
print dep print repr(repo)
pool.set_flag(solv.Pool.POOL_FLAG_OBSOLETEUSESCOLORS, 1);
RUBY SPECIFICS¶
The ruby bindings can be loaded with:require 'solv'
pool = Solv::Pool.new repo = pool.add_repo("my_first_repo")
pool.appdata = 42 puts "appdata is #{pool.appdata}"
for solvable in pool.solvables_iter() do ...
jobs = [] problems = solver.solve(jobs)
puts dep puts repo.inspect
pool.set_flag(Solv::Pool::POOL_FLAG_OBSOLETEUSESCOLORS, 1);
puts "empty repo" if repo.isempty?
THE SOLV CLASS¶
This is the main namespace of the library, you cannot create objects of this type but it contains some useful constants.CONSTANTS¶
Relational flag constants, the first three can be or-ed together REL_LTthe “less than” bit
REL_EQ
the “equals to” bit
REL_GT
the “greater then” bit
REL_ARCH
used for relations that describe an extra architecture
filter, the version part of the relation is interpreted as architecture.
Special Solvable Ids
SOLVID_META
Access the meta section of a repository or repodata area.
This is like an extra Solvable that has the Id SOLVID_META.
SOLVID_POS
Use the data position stored inside of the pool instead
of accessing some solvable by Id. The bindings have the Datapos objects as an
abstraction mechanism, so you do not need this constant.
Constant string Ids
ID_NULL
Always zero
ID_EMPTY
Always one, describes the empty string
SOLVABLE_NAME
The keyname Id of the name of the solvable.
...
see the libsolv-constantids manpage for a list of fixed
Ids.
THE POOL CLASS¶
The pool is libsolv’s central resource manager. A pool consists of Solvables, Repositories, Dependencies, each indexed by Ids.CLASS METHODS¶
Pool *Pool() my $pool = solv::Pool->new(); pool = solv.Pool() pool = Solv::Pool.new()
ATTRIBUTES¶
void *appdata; /* read/write */ $pool->{appdata} pool.appdata pool.appdata
Solvable solvables[]; /* read only */ my $solvable = $pool->{solvables}->[$solvid]; solvable = pool.solvables[solvid] solvable = pool.solvables[solvid]
Repo repos[]; /* read only */ my $repo = $pool->{repos}->[$repoid]; repo = pool.repos[repoid] repo = pool.repos[repoid]
Repo *installed; /* read/write */ $pool->{installed} = $repo; pool.installed = repo pool.installed = repo
const char *errstr; /* read only */ my $err = $pool->{errstr}; err = pool.errstr err = pool.errstr
CONSTANTS¶
POOL_FLAG_PROMOTEEPOCHPromote the epoch of the providing dependency to the
requesting dependency if it does not contain an epoch. Used at some time in
old rpm versions, modern systems should never need this.
POOL_FLAG_FORBIDSELFCONFLICTS
Disallow the installation of packages that conflict with
themselves. Debian always allows self-conflicting packages, rpm used to forbid
them but switched to also allowing them recently.
POOL_FLAG_OBSOLETEUSESPROVIDES
Make obsolete type dependency match against provides
instead of just the name and version of packages. Very old versions of rpm
used the name/version, then it got switched to provides and later switched
back again to just name/version.
POOL_FLAG_IMPLICITOBSOLETEUSESPROVIDES
An implicit obsoletes is the internal mechanism to remove
the old package on an update. The default is to remove all packages with the
same name, rpm-5 switched to also removing packages providing the same
name.
POOL_FLAG_OBSOLETEUSESCOLORS
Rpm’s multilib implementation (used in RedHat and
Fedora) distinguishes between 32bit and 64bit packages (the terminology is
that they have a different color). If obsoleteusescolors is set, packages with
different colors will not obsolete each other.
POOL_FLAG_IMPLICITOBSOLETEUSESCOLORS
Same as POOL_FLAG_OBSOLETEUSESCOLORS, but used to find
out if packages of the same name can be installed in parallel. For current
Fedora systems, POOL_FLAG_OBSOLETEUSESCOLORS should be false and
POOL_FLAG_IMPLICITOBSOLETEUSESCOLORS should be true (this is the default if
FEDORA is defined when libsolv is compiled).
POOL_FLAG_NOINSTALLEDOBSOLETES
New versions of rpm consider the obsoletes of installed
packages when checking for dependency, thus you may not install a package that
is obsoleted by some other installed package, unless you also erase the other
package.
POOL_FLAG_HAVEDISTEPOCH
Mandriva added a new field called distepoch that gets
checked in version comparison if the epoch/version/release of two packages are
the same.
POOL_FLAG_NOOBSOLETESMULTIVERSION
If a package is installed in multiversionmode, rpm used
to ignore both the implicit obsoletes and the obsolete dependency of a
package. This was changed to ignoring just the implicit obsoletes, thus you
may install multiple versions of the same name, but obsoleted packages still
get removed.
POOL_FLAG_ADDFILEPROVIDESFILTERED
Make the addfileprovides method only add files from the
standard locations (i.e. the “bin” and “etc”
directories). This is useful if you have only few packages that use
non-standard file dependencies, but you still wand the fast speed that
addfileprovides() generates.
METHODS¶
void free() $pool->free(); pool.free() pool.free()
void disown() $pool->disown(); pool.disown() pool.disown()
void setdebuglevel(int level) $pool->setdebuglevel($level); pool.setdebuglevel(level) pool.setdebuglevel(level)
int set_flag(int flag, int value) my $oldvalue = $pool->set_flag($flag, $value); oldvalue = pool.set_flag(flag, value) oldvalue = pool.set_flag(flag, value)
int get_flag(int flag) my $value = $pool->get_flag($flag); value = pool.get_flag(flag) value = pool.get_flag(flag)
void set_rootdir(const char *rootdir) $pool->set_rootdir(rootdir); pool.set_rootdir(rootdir) pool.set_rootdir(rootdir)
const char *get_rootdir() my $rootdir = $pool->get_rootdir(); rootdir = pool.get_rootdir() rootdir = pool.get_rootdir()
void setarch(const char *arch = 0) $pool->setarch(); pool.setarch() pool.setarch()
Repo add_repo(const char *name) $repo = $pool->add_repo($name); repo = pool.add_repo(name) repo = pool.add_repo(name)
Repoiterator repos_iter() for my $repo (@{$pool->repos_iter()}) for repo in pool.repos_iter(): for repo in pool.repos_iter()
Solvableiterator solvables_iter() for my $solvable (@{$pool->solvables_iter()}) for solvable in pool.solvables_iter(): for solvable in pool.solvables_iter()
Dep Dep(const char *str, bool create = 1) my $dep = $pool->Dep($string); dep = pool.Dep(string) dep = pool.Dep(string)
void addfileprovides() $pool->addfileprovides(); pool.addfileprovides() pool.addfileprovides()
Id *addfileprovides_queue() my @ids = $pool->addfileprovides_queue(); ids = pool.addfileprovides_queue() ids = pool.addfileprovides_queue()
void createwhatprovides() $pool->createwhatprovides(); pool.createwhatprovides() pool.createwhatprovides()
Solvable *whatprovides(DepId dep) my @solvables = $pool->whatprovides($dep); solvables = pool.whatprovides(dep) solvables = pool.whatprovides(dep)
Id *matchprovidingids(const char *match, int flags) my @ids = $pool->matchprovidingids($match, $flags); ids = pool.matchprovidingids(match, flags) ids = pool.matchprovidingids(match, flags)
Id towhatprovides(Id *ids) my $offset = $pool->towhatprovides(\@ids); offset = pool.towhatprovides(ids) offset = pool.towhatprovides(ids)
bool isknownarch(DepId id) my $bool = $pool->isknownarch($id); bool = pool.isknownarch(id) bool = pool.isknownarch?(id)
Solver Solver() my $solver = $pool->Solver(); solver = pool.Solver() solver = pool.Solver()
Job Job(int how, Id what) my $job = $pool->Job($how, $what); job = pool.Job(how, what) job = pool.Job(how, what)
Selection Selection() my $sel = $pool->Selection(); sel = pool.Selection() sel = pool.Selection()
Selection Selection_all() my $sel = $pool->Selection_all(); sel = pool.Selection_all() sel = pool.Selection_all()
Selection select(const char *name, int flags) my $sel = $pool->select($name, $flags); sel = pool.select(name, flags) sel = pool.select(name, flags)
void setpooljobs(Jobs *jobs) $pool->setpooljobs(\@jobs); pool.setpooljobs(jobs) pool.setpooljobs(jobs)
Job *getpooljobs() @jobs = $pool->getpooljobs(); jobs = pool.getpooljobs() jobs = pool.getpooljobs()
void set_loadcallback(Callable *callback) $pool->setloadcallback(\&callbackfunction); pool.setloadcallback(callbackfunction) pool.setloadcallback { |repodata| ... }
DATA RETRIEVAL METHODS¶
In the following functions, the keyname argument describes what to retrieve. For the standard cases you can use the available Id constants. For example,$solv::SOLVABLE_SUMMARY solv.SOLVABLE_SUMMARY Solv::SOLVABLE_SUMMARY
const char *lookup_str(Id solvid, Id keyname) my $string = $pool->lookup_str($solvid, $keyname); string = pool.lookup_str(solvid, keyname) string = pool.lookup_str(solvid, keyname)
Id lookup_id(Id solvid, Id keyname) my $id = $pool->lookup_id($solvid, $keyname); id = pool.lookup_id(solvid, keyname) id = pool.lookup_id(solvid, keyname)
unsigned long long lookup_num(Id solvid, Id keyname, unsigned long long notfound = 0) my $num = $pool->lookup_num($solvid, $keyname); num = pool.lookup_num(solvid, keyname) num = pool.lookup_num(solvid, keyname)
bool lookup_void(Id solvid, Id keyname) my $bool = $pool->lookup_void($solvid, $keyname); bool = pool.lookup_void(solvid, keyname) bool = pool.lookup_void(solvid, keyname)
Id *lookup_idarray(Id solvid, Id keyname) my @ids = $pool->lookup_idarray($solvid, $keyname); ids = pool.lookup_idarray(solvid, keyname) ids = pool.lookup_idarray(solvid, keyname)
Chksum lookup_checksum(Id solvid, Id keyname) my $chksum = $pool->lookup_checksum($solvid, $keyname); chksum = pool.lookup_checksum(solvid, keyname) chksum = pool.lookup_checksum(solvid, keyname)
Dataiterator Dataiterator(Id keyname, const char *match = 0, int flags = 0) my $di = $pool->Dataiterator($keyname, $match, $flags); di = pool.Dataiterator(keyname, match, flags) di = pool.Dataiterator(keyname, match, flags)
Dataiterator Dataiterator_solvid(Id solvid, Id keyname, const char *match = 0, int flags = 0) my $di = $pool->Dataiterator($solvid, $keyname, $match, $flags); di = pool.Dataiterator(solvid, keyname, match, flags) di = pool.Dataiterator(solvid, keyname, match, flags)
for my $d (@$di) for d in di: for d in di
ID METHODS¶
The following methods deal with Ids, i.e. integers representing objects in the pool. They are considered “low level”, in most cases you would not use them but instead the object orientated methods.Repo id2repo(Id id) $repo = $pool->id2repo($id); repo = pool.id2repo(id) repo = pool.id2repo(id)
Solvable id2solvable(Id id) $solvable = $pool->id2solvable($id); solvable = pool.id2solvable(id) solvable = pool.id2solvable(id)
const char *solvid2str(Id id) my $str = $pool->solvid2str($id); str = pool.solvid2str(id) str = pool.solvid2str(id)
Id str2id(const char *str, bool create = 1) my $id = pool->str2id($string); id = pool.str2id(string) id = pool.str2id(string)
const char *id2str(Id id) $string = pool->id2str($id); string = pool.id2str(id) string = pool.id2str(id)
Id rel2id(Id name, Id evr, int flags, bool create = 1) my $id = pool->rel2id($nameid, $evrid, $flags); id = pool.rel2id(nameid, evrid, flags) id = pool.rel2id(nameid, evrid, flags)
$solv::REL_EQ | $solv::REL_GT | $solv::REL_LT solv.REL_EQ | solv.REL_GT | solv.REL_LT Solv::REL_EQ | Solv::REL_GT | Solv::REL_LT
Id id2langid(Id id, const char *lang, bool create = 1) my $id = $pool->id2langid($id, $language); id = pool.id2langid(id, language) id = pool.id2langid(id, language)
const char *dep2str(Id id) $string = pool->dep2str($id); string = pool.dep2str(id) string = pool.dep2str(id)
THE DEPENDENCY CLASS¶
The dependency class is an object orientated way to work with strings and dependencies. Internally, dependencies are represented as Ids, i.e. simple numbers. Dependency objects can be constructed by using the Pool’s Dep() method.ATTRIBUTES¶
Pool *pool; /* read only */ $dep->{pool} dep.pool dep.pool
Id id; /* read only */ $dep->{id} dep.id dep.id
METHODS¶
Dep Rel(int flags, DepId evrid, bool create = 1) my $reldep = $dep->Rel($flags, $evrdep); reldep = dep.Rel(flags, evrdep) reldep = dep.Rel(flags, evrdep)
Selection Selection_name(int setflags = 0) my $sel = $dep->Selection_name(); sel = dep.Selection_name() sel = dep.Selection_name()
Selection Selection_provides(int setflags = 0) my $sel = $dep->Selection_provides(); sel = dep.Selection_provides() sel = dep.Selection_provides()
const char *str() my $str = $dep->str(); str = $dep.str() str = $dep.str()
<stringification> my $str = $dep->str; str = str(dep) str = dep.to_s
<equality> if ($dep1 == $dep2) if dep1 == dep2: if dep1 == dep2
THE REPOSITORY CLASS¶
A Repository describes a group of packages, normally coming from the same source. Repositories are created by the Pool’s add_repo() method.ATTRIBUTES¶
Pool *pool; /* read only */ $repo->{pool} repo.pool repo.pool
Id id; /* read only */ $repo->{id} repo.id repo.id
const char *name; /* read/write */ $repo->{name} repo.name repo.name
int priority; /* read/write */ $repo->{priority} repo.priority repo.priority
int subpriority; /* read/write */ $repo->{subpriority} repo.subpriority repo.subpriority
int nsolvables; /* read only */ $repo->{nsolvables} repo.nsolvables repo.nsolvables
void *appdata; /* read/write */ $repo->{appdata} repo.appdata repo.appdata
Datapos *meta; /* read only */ $repo->{meta} repo.meta repo.meta
CONSTANTS¶
REPO_REUSE_REPODATAReuse the last repository data area
(“repodata”) instead of creating a new one.
REPO_NO_INTERNALIZE
Do not internalize the added repository data. This is
useful if you plan to add more data because internalization is a costly
operation.
REPO_LOCALPOOL
Use the repodata’s pool for Id storage instead of
the global pool. Useful if you don’t want to pollute the global pool
with many unneeded ids, like when storing the filelist.
REPO_USE_LOADING
Use the repodata that is currently being loaded instead
of creating a new one. This only makes sense if used in a load callback.
REPO_EXTEND_SOLVABLES
Do not create new solvables for the new data, but match
existing solvables and add the data to them. Repository metadata is often
split into multiple parts, with one primary file describing all packages and
other parts holding information that is normally not needed, like the
changelog.
REPO_USE_ROOTDIR
Prepend the pool’s rootdir to the path when doing
file operations.
REPO_NO_LOCATION
Do not add a location element to the solvables. Useful if
the solvables are not in the final position, so you can add the correct
location later in your code.
SOLV_ADD_NO_STUBS
Do not create stubs for repository parts that can be
downloaded on demand.
SUSETAGS_RECORD_SHARES
This is specific to the add_susetags() method. Susetags
allows one to refer to already read packages to save disk space. If this data
sharing needs to work over multiple calls to add_susetags, you need to specify
this flag so that the share information is made available to subsequent
calls.
METHODS¶
void free(bool reuseids = 0) $repo->free(); repo.free() repo.free()
void empty(bool reuseids = 0) $repo->empty(); repo.empty() repo.empty()
bool isempty() $repo->isempty() repo.empty() repo.empty?
void internalize() $repo->internalize(); repo.internalize() repo.internalize()
bool write(FILE *fp) $repo->write($fp) repo.write(fp) repo.write(fp)
Solvableiterator solvables_iter() for my $solvable (@{$repo->solvables_iter()}) for solvable in repo.solvables_iter(): for solvable in repo.solvables_iter()
Repodata add_repodata(int flags = 0) my $repodata = $repo->add_repodata(); repodata = repo.add_repodata() repodata = repo.add_repodata()
void create_stubs() $repo->create_stubs(); repo.create_stubs() repo.create_stubs()
bool iscontiguous() $repo->iscontiguous() repo.iscontiguous() repo.iscontiguous?
Repodata first_repodata() my $repodata = $repo->first_repodata(); repodata = repo.first_repodata() repodata = repo.first_repodata()
Selection Selection(int setflags = 0) my $sel = $repo->Selection(); sel = repo.Selection() sel = repo.Selection()
Dataiterator Dataiterator(Id key, const char *match = 0, int flags = 0) my $di = $repo->Dataiterator($keyname, $match, $flags); di = repo.Dataiterator(keyname, match, flags) di = repo.Dataiterator(keyname, match, flags)
Dataiterator Dataiterator_meta(Id key, const char *match = 0, int flags = 0) my $di = $repo->Dataiterator_meta($keyname, $match, $flags); di = repo.Dataiterator_meta(keyname, match, flags) di = repo.Dataiterator_meta(keyname, match, flags)
for my $d (@$di) for d in di: for d in di
<stringification> my $str = $repo->str; str = str(repo) str = repo.to_s
<equality> if ($repo1 == $repo2) if repo1 == repo2: if repo1 == repo2
DATA ADD METHODS¶
Solvable add_solvable() $repo->add_solvable(); repo.add_solvable() repo.add_solvable()
bool add_solv(const char *name, int flags = 0) $repo->add_solv($name); repo.add_solv(name) repo.add_solv(name)
bool add_solv(FILE *fp, int flags = 0) $repo->add_solv($fp); repo.add_solv(fp) repo.add_solv(fp)
bool add_rpmdb(int flags = 0) $repo->add_rpmdb(); repo.add_rpmdb() repo.add_rpmdb()
bool add_rpmdb_reffp(FILE *reffp, int flags = 0) $repo->add_rpmdb_reffp($reffp); repo.add_rpmdb_reffp(reffp) repo.add_rpmdb_reffp(reffp)
Solvable add_rpm(const char *filename, int flags = 0) my $solvable = $repo->add_rpm($filename); solvable = repo.add_rpm(filename) solvable = repo.add_rpm(filename)
bool add_rpmdb_pubkeys(int flags = 0) $repo->add_rpmdb_pubkeys(); repo.add_rpmdb_pubkeys() repo.add_rpmdb_pubkeys()
Solvable add_pubkey(const char *keyfile, int flags = 0) my $solvable = $repo->add_pubkey($keyfile); solvable = repo.add_pubkey(keyfile) solvable = repo.add_pubkey(keyfile)
bool add_rpmmd(FILE *fp, const char *language, int flags = 0) $repo->add_rpmmd($fp, undef); repo.add_rpmmd(fp, None) repo.add_rpmmd(fp, nil)
bool add_repomdxml(FILE *fp, int flags = 0) $repo->add_repomdxml($fp); repo.add_repomdxml(fp) repo.add_repomdxml(fp)
bool add_updateinfoxml(FILE *fp, int flags = 0) $repo->add_updateinfoxml($fp); repo.add_updateinfoxml(fp) repo.add_updateinfoxml(fp)
bool add_deltainfoxml(FILE *fp, int flags = 0) $repo->add_deltainfoxml($fp); repo.add_deltainfoxml(fp) repo.add_deltainfoxml(fp)
bool add_debdb(int flags = 0) $repo->add_debdb(); repo.add_debdb() repo.add_debdb()
bool add_debpackages(FILE *fp, int flags = 0) $repo->add_debpackages($fp); repo.add_debpackages($fp) repo.add_debpackages($fp)
Solvable add_deb(const char *filename, int flags = 0) my $solvable = $repo->add_deb($filename); solvable = repo.add_deb(filename) solvable = repo.add_deb(filename)
bool add_mdk(FILE *fp, int flags = 0) $repo->add_mdk($fp); repo.add_mdk(fp) repo.add_mdk(fp)
bool add_mdk_info(FILE *fp, int flags = 0) $repo->add_mdk($fp); repo.add_mdk(fp) repo.add_mdk(fp)
bool add_arch_repo(FILE *fp, int flags = 0) $repo->add_arch_repo($fp); repo.add_arch_repo(fp) repo.add_arch_repo(fp)
bool add_arch_local(const char *dir, int flags = 0) $repo->add_arch_local($dir); repo.add_arch_local(dir) repo.add_arch_local(dir)
bool add_content(FILE *fp, int flags = 0) $repo->add_content($fp); repo.add_content(fp) repo.add_content(fp)
bool add_susetags(FILE *fp, Id defvendor, const char *language, int flags = 0) $repo->add_susetags($fp, $defvendor, $language); repo.add_susetags(fp, defvendor, language) repo.add_susetags(fp, defvendor, language)
bool add_products(const char *dir, int flags = 0) $repo->add_products($dir); repo.add_products(dir) repo.add_products(dir)
THE SOLVABLE CLASS¶
A solvable describes all the information of one package. Each solvable belongs to one repository, it can be added and filled manually but in most cases solvables will get created by the repo_add methods.ATTRIBUTES¶
Repo *repo; /* read only */ $solvable->{repo} solvable.repo solvable.repo
Pool *pool; /* read only */ $solvable->{pool} solvable.pool solvable.pool
Id id; /* read only */ $solvable->{id} solvable.id solvable.id
char *name; /* read/write */ $solvable->{name} solvable.name solvable.name
char *evr; /* read/write */ $solvable->{evr} solvable.evr solvable.evr
char *arch; /* read/write */ $solvable->{arch} solvable.arch solvable.arch
char *vendor; /* read/write */ $solvable->{vendor} solvable.vendor solvable.vendor
Id nameid; /* read/write */ $solvable->{nameid} solvable.nameid solvable.nameid
Id evrid; /* read/write */ $solvable->{evrid} solvable.evrid solvable.evrid
Id archid; /* read/write */ $solvable->{archid} solvable.archid solvable.archid
Id vendorid; /* read/write */ $solvable->{vendorid} solvable.vendorid solvable.vendorid
METHODS¶
const char *lookup_str(Id keyname) my $string = $solvable->lookup_str($keyname); string = solvable.lookup_str(keyname) string = solvable.lookup_str(keyname)
Id lookup_id(Id keyname) my $id = $solvable->lookup_id($keyname); id = solvable.lookup_id(solvid) id = solvable.lookup_id(solvid)
unsigned long long lookup_num(Id solvid, Id keyname, unsigned long long notfound = 0) my $num = $solvable->lookup_num($keyname); num = solvable.lookup_num(keyname) num = solvable.lookup_num(keyname)
bool lookup_void(Id keyname) my $bool = $solvable->lookup_void($keyname); bool = solvable.lookup_void(keyname) bool = solvable.lookup_void(keyname)
Chksum lookup_checksum(Id keyname) my $chksum = $solvable->lookup_checksum($keyname); chksum = solvable.lookup_checksum(keyname) chksum = solvable.lookup_checksum(keyname)
Id *lookup_idarray(Id keyname, Id marker = -1) my @ids = $solvable->lookup_idarray($keyname); ids = solvable.lookup_idarray(keyname) ids = solvable.lookup_idarray(keyname)
Dep *lookup_deparray(Id keyname, Id marker = -1) my @deps = $solvable->lookup_deparray($keyname); deps = solvable.lookup_deparray(keyname) deps = solvable.lookup_deparray(keyname)
const char *lookup_location(unsigned int *OUTPUT); my ($location, $medianr) = $solvable->lookup_location(); location, medianr = solvable.lookup_location() location, medianr = solvable.lookup_location()
Dataiterator Dataiterator(Id keyname, const char *match = 0, int flags = 0) my $di = $solvable->Dataiterator($keyname, $match, $flags); di = solvable.Dataiterator(keyname, match, flags) di = solvable.Dataiterator(keyname, match, flags)
for my $d (@$di) for d in di: for d in di
void add_deparray(Id keyname, DepId dep, Id marker = -1); $solvable->add_deparray($keyname, $dep); solvable.add_deparray(keyname, dep) solvable.add_deparray(keyname, dep)
void unset(Id keyname); $solvable->unset($keyname); solvable.unset(keyname) solvable.unset(keyname)
bool installable(); $solvable->installable() solvable.installable() solvable.installable?
bool isinstalled(); $solvable->isinstalled() solvable.isinstalled() solvable.isinstalled?
bool identical(Solvable *other) $solvable->identical($other) $solvable.identical(other) $solvable.identical?(other)
int evrcmp(Solvable *other) $solvable->evrcmp(other) $solvable.evrcmp(other) $solvable.evrcmp(other)
Selection Selection(int setflags = 0) my $sel = $solvable->Selection(); sel = solvable.Selection() sel = solvable.Selection()
const char *str() my $str = $solvable->str(); str = $solvable.str() str = $solvable.str()
<stringification> my $str = $solvable->str; str = str(solvable) str = solvable.to_s
<equality> if ($solvable1 == $solvable2) if solvable1 == solvable2: if solvable1 == solvable2
THE DATAITERATOR CLASS¶
Dataiterators can be used to do complex string searches or to iterate over arrays. They can be created via the constructors in the Pool, Repo, and Solvable classes. The Repo and Solvable constructors will limit the search to the repository or the specific package.CONSTANTS¶
SEARCH_STRINGReturn a match if the search string matches the
value.
SEARCH_STRINGSTART
Return a match if the value starts with the search
string.
SEARCH_STRINGEND
Return a match if the value ends with the search
string.
SEARCH_SUBSTRING
Return a match if the search string can be matched
somewhere in the value.
SEARCH_GLOB
Do a glob match of the search string against the
value.
SEARCH_REGEX
Do a regular expression match of the search string
against the value.
SEARCH_NOCASE
Ignore case when matching strings. Works for all the
above match types.
SEARCH_FILES
Match the complete filenames of the file list, not just
the base name.
SEARCH_COMPLETE_FILELIST
When matching the file list, check every file of the
package not just the subset from the primary metadata.
SEARCH_CHECKSUMS
Allow the matching of checksum entries.
METHODS¶
void prepend_keyname(Id keyname); $di->prepend_keyname($keyname); di.prepend_keyname(keyname) di.prepend_keyname(keyname)
void skip_solvable(); $di->kip_solvable(); di.skip_solvable() di.skip_solvable()
<iteration> for my $d (@$di) for d in di: for d in di
THE DATAMATCH CLASS¶
Objects of this type will be created for every value matched by a dataiterator.ATTRIBUTES¶
Pool *pool; /* read only */ $d->{pool} d.pool d.pool
Repo *repo; /* read only */ $d->{repo} d.repo d.repo
Solvable *solvable; /* read only */ $d->{solvable} d.solvable d.solvable
Id solvid; /* read only */ $d->{solvid} d.solvid d.solvid
Id key_id; $d->{key_id} d.key_id d.key_id
const char *key_idstr; $d->{key_idstr} d.key_idstr d.key_idstr
Id type_id; $d->{type_id} d.type_id d.type_id
const char *type_idstr; $d->{type_idstr}; d.type_idstr d.type_idstr
Id id; $d->{id} d.id d.id
Id idstr; $d->{idstr} d.idstr d.idstr
const char *str; $d->{str} d.str d.str
unsigned long long num; $d->{num} d.num d.num
unsigned int num2; $d->{num2} d.num2 d.num2
unsigned int binary; $d->{binary} d.binary d.binary
METHODS¶
Datapos pos(); my $pos = $d->pos(); pos = d.pos() pos = d.pos()
Datapos parentpos(); my $pos = $d->parentpos(); pos = d.parentpos() pos = d.parentpos()
<stringification> my $str = $d->str; str = str(d) str = d.to_s
THE SELECTION CLASS¶
Selections are a way to easily deal with sets of packages. There are multiple constructors to create them, the most useful is probably the select() method in the Pool class.CONSTANTS¶
SELECTION_NAMECreate the selection by matching package names.
SELECTION_PROVIDES
Create the selection by matching package provides.
SELECTION_FILELIST
Create the selection by matching package files.
SELECTION_CANON
Create the selection by matching the canonical
representation of the package. This is normally a combination of the name, the
version, and the architecture of a package.
SELECTION_DOTARCH
Allow an “.<architecture>” suffix
when matching names or provides.
SELECTION_REL
Allow the specification of a relation when matching names
or provides, e.g. "name >= 1.2".
SELECTION_INSTALLED_ONLY
Limit the package search to installed packages.
SELECTION_SOURCE_ONLY
Limit the package search to source packages only.
SELECTION_WITH_SOURCE
Extend the package search to also match source packages.
The default is only to match binary packages.
SELECTION_GLOB
Allow glob matching for package names, package provides,
and file names.
SELECTION_NOCASE
Ignore case when matching package names, package
provides, and file names.
SELECTION_FLAT
Return only one selection element describing the selected
packages. The default is to create multiple elements for all globbed packages.
Multiple elements are useful if you want to turn the selection into an install
job, in that case you want an install job for every globbed package.
ATTRIBUTES¶
Pool *pool; /* read only */ $d->{pool} d.pool d.pool
METHODS¶
int flags(); my $flags = $sel->flags(); flags = sel.flags() flags = sel.flags()
bool isempty(); $sel->isempty() sel.isempty() sel.isempty?
void filter(Selection *other) $sel->filter($other); sel.filter(other) sel.filter(other)
void add(Selection *other) $sel->add($other); sel.add(other) sel.add(other)
void add_raw(Id how, Id what) $sel->add_raw($how, $what); sel.add_raw(how, what) sel.add_raw(how, what)
Job *jobs(int action) my @jobs = $sel->jobs($action); jobs = sel.jobs(action) jobs = sel.jobs(action)
Solvable *solvables() my @solvables = $sel->solvables(); solvables = sel.solvables() solvables = sel.solvables()
<stringification> my $str = $sel->str; str = str(sel) str = sel.to_s
THE JOB CLASS¶
Jobs are the way to specify to the dependency solver what to do. Most of the times jobs will get created by calling the jobs() method on a Selection object, but there is also a Job() constructor in the Pool class.CONSTANTS¶
Selection constants: SOLVER_SOLVABLEThe “what” part is the id of a
solvable.
SOLVER_SOLVABLE_NAME
The “what” part is the id of a package
name.
SOLVER_SOLVABLE_PROVIDES
The “what” part is the id of a package
provides.
SOLVER_SOLVABLE_ONE_OF
The “what” part is an offset into the
“whatprovides” data, created by calling the towhatprovides()
pool method.
SOLVER_SOLVABLE_REPO
The “what” part is the id of a
repository.
SOLVER_SOLVABLE_ALL
The “what” part is ignored, all packages
are selected.
SOLVER_SOLVABLE_SELECTMASK
A mask containing all the above selection bits.
Action constants:
SOLVER_NOOP
Do nothing.
SOLVER_INSTALL
Install a package of the specified set of packages. It
tries to install the best matching package (i.e. the highest version of the
packages from the repositories with the highest priority).
SOLVER_ERASE
Erase all of the packages from the specified set. If a
package is not installed, erasing it will keep it from getting
installed.
SOLVER_UPDATE
Update the matching installed packages to their best
version. If none of the specified packages are installed, try to update the
installed packages to the specified versions. See the section about targeted
updates about more information.
SOLVER_WEAKENDEPS
Allow to break the dependencies of the matching packages.
Handle with care.
SOLVER_MULTIVERSION
Mark the matched packages for multiversion install. If
they get to be installed because of some other job, the installation will keep
the old version of the package installed (for rpm this is done by using
“-i” instead of “-U”).
SOLVER_LOCK
Do not change the state of the matched packages, i.e.
when they are installed they stay installed, if not they are not selected for
installation.
SOLVER_DISTUPGRADE
Update the matching installed packages to the best
version included in one of the repositories. After this operation, all come
from one of the available repositories except orphaned packages. Orphaned
packages are packages that have no relation to the packages in the
repositories, i.e. no package in the repositories have the same name or
obsolete the orphaned package. This action brings the installed packages in
sync with the ones in the repository. By default it also turns of
arch/vendor/version locking for the affected packages to simulate a fresh
installation. This means that distupgrade can actually downgrade packages if
only lower versions of a package are available in the repositories. You can
tweak this behavior with the SOLVER_FLAG_DUP_ solver flags.
SOLVER_DROP_ORPHANED
Erase all the matching installed packages if they are
orphaned. This only makes sense if there is a “distupgrade all
packages” job. The default is to erase orphaned packages only if they
block the installation of other packages.
SOLVER_VERIFY
Fix dependency problems of matching installed packages.
The default is to ignore dependency problems for installed packages.
SOLVER_USERINSTALLED
The matching installed packages are considered to be
installed by a user, thus not installed to fulfill some dependency. This is
needed input for the calculation of unneeded packages for jobs that have the
SOLVER_CLEANDEPS flag set.
SOLVER_JOBMASK
A mask containing all the above action bits.
Action modifier constants:
SOLVER_WEAK
Makes the job a weak job. The solver tries to fulfill
weak jobs, but does not report a problem if it is not possible to do so.
SOLVER_ESSENTIAL
Makes the job an essential job. If there is a problem
with the job, the solver will not propose to remove the job as one solution
(unless all other solutions are also to remove essential jobs).
SOLVER_CLEANDEPS
The solver will try to also erase all packages dragged in
through dependencies when erasing the package. This needs SOLVER_USERINSTALLED
jobs to maximize user satisfaction.
SOLVER_FORCEBEST
Insist on the best package for install, update, and
distupgrade jobs. If this flag is not used, the solver will use the
second-best package if the best package cannot be installed for some reason.
When this flag is used, the solver will generate a problem instead.
SOLVER_TARGETED
Forces targeted operation update and distupgrade jobs.
See the section about targeted updates about more information.
Set constants.
SOLVER_SETEV
The job specified the exact epoch and version of the
package set.
SOLVER_SETEVR
The job specified the exact epoch, version, and release
of the package set.
SOLVER_SETARCH
The job specified the exact architecture of the packages
from the set.
SOLVER_SETVENDOR
The job specified the exact vendor of the packages from
the set.
SOLVER_SETREPO
The job specified the exact repository of the packages
from the set.
SOLVER_SETNAME
The job specified the exact name of the packages from the
set.
SOLVER_NOAUTOSET
Turn of automatic set flag generation for SOLVER_SOLVABLE
jobs.
SOLVER_SETMASK
A mask containing all the above set bits.
See the section about set bits for more information.
ATTRIBUTES¶
Pool *pool; /* read only */ $job->{pool} d.pool d.pool
Id how; /* read/write */ $job->{how} d.how d.how
Id what; /* read/write */ $job->{what} d.what d.what
METHODS¶
Solvable *solvables() my @solvables = $job->solvables(); solvables = job.solvables() solvables = job.solvables()
bool isemptyupdate(); $job->isemptyupdate() job.isemptyupdate() job.isemptyupdate?
<stringification> my $str = $job->str; str = str(job) str = job.to_s
<equality> if ($job1 == $job2) if job1 == job2: if job1 == job2
TARGETED UPDATES¶
Libsolv has two modes for upgrades and distupgrade: targeted and untargeted. Untargeted mode means that the installed packages from the specified set will be updated to the best version. Targeted means that packages that can be updated to a package in the specified set will be updated to the best package of the set. Here’s an example to explain the subtle difference. Suppose that you have package A installed in version "1.1", "A-1.2" is available in one of the repositories and there is also package "B" that obsoletes package A. An untargeted update of "A" will update the installed "A-1.1" to package "B", because that is the newest version (B obsoletes A and is thus newer). A targeted update of "A" will update "A-1.1" to "A-1.2", as the set of packages contains both "A-1.1" and "A-1.2", and "A-1.2" is the newer one. An untargeted update of "B" will do nothing, as "B" is not installed. An targeted update of "B" will update "A-1.1" to "B". Note that the default is to do "auto-targeting", thus if the specified set of packages does not include an installed package, the solver will assume targeted operation even if SOLVER_TARGETED is not used. This mostly matches the intent of the user, with one exception: In the example above, an update of "A-1.2" will update "A-1.1" to "A-1.2" (targeted mode), but a second update of "A-1.2" will suddenly update to "B", as untargeted mode is chosen because "A-1.2" is now installed. If you want to have full control over when targeting mode is chosen, turn off auto-targeting with the SOLVER_FLAG_NO_AUTOTARGET solver option. In that case, all updates are considered to be untargeted unless they include the SOLVER_TARGETED flag.SET BITS¶
Set bits specify which parts of the specified packages where specified by the user. It is used by the solver when checking if an operation is allowed or not. For example, the solver will normally not allow the downgrade of an installed package. But it will not report a problem if the SOLVER_SETEVR flag is used, as it then assumes that the user specified the exact version and thus knows what he is doing. So if a package "screen-1-1" is installed for the x86_64 architecture and version "2-1" is only available for the i586 architecture, installing package "screen-2.1" will ask the user for confirmation because of the different architecture. When using the Selection class to create jobs the set bits are automatically added, e.g. selecting “screen.i586” will automatically add SOLVER_SETARCH, and thus no problem will be reported.THE SOLVER CLASS¶
Dependency solving is what this library is about. A solver object is needed for solving to store the result of the solver run. The solver object can be used multiple times for different jobs, reusing it allows the solver to re-use the dependency rules it already computed.CONSTANTS¶
Flags to modify some of the solver’s behavior: SOLVER_FLAG_ALLOW_DOWNGRADEAllow the solver to downgrade packages without asking for
confirmation (i.e. reporting a problem).
SOLVER_FLAG_ALLOW_ARCHCHANGE
Allow the solver to change the architecture of an
installed package without asking for confirmation. Note that changes to/from
noarch are always considered to be allowed.
SOLVER_FLAG_ALLOW_VENDORCHANGE
Allow the solver to change the vendor of an installed
package without asking for confirmation. Each vendor is part of one or more
vendor equivalence classes, normally installed packages may only change their
vendor if the new vendor shares at least one equivalence class.
SOLVER_FLAG_ALLOW_NAMECHANGE
Allow the solver to change the name of an installed
package, i.e. install a package with a different name that obsoletes the
installed package. This option is on by default.
SOLVER_FLAG_ALLOW_UNINSTALL
Allow the solver to erase installed packages to fulfill
the jobs. This flag also includes the above flags. You may want to set this
flag if you only have SOLVER_ERASE jobs, as in that case it’s better
for the user to check the transaction overview instead of approving every
single package that needs to be erased.
SOLVER_FLAG_DUP_ALLOW_DOWNGRADE
Like SOLVER_FLAG_ALLOW_DOWNGRADE, but used in distupgrade
mode.
SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE
Like SOLVER_FLAG_ALLOW_ARCHCHANGE, but used in
distupgrade mode.
SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE
Like SOLVER_FLAG_ALLOW_VENDORCHANGE, but used in
distupgrade mode.
SOLVER_FLAG_DUP_ALLOW_NAMECHANGE
Like SOLVER_FLAG_ALLOW_NAMECHANGE, but used in
distupgrade mode.
SOLVER_FLAG_NO_UPDATEPROVIDE
If multiple packages obsolete an installed package, the
solver checks the provides of every such package and ignores all packages that
do not provide the installed package name. Thus, you can have an official
update candidate that provides the old name, and other packages that also
obsolete the package but are not considered for updating. If you cannot use
this feature, you can turn it off by setting this flag.
SOLVER_FLAG_SPLITPROVIDES
Make the solver aware of special provides of the form
“<packagename>:<path>” used in SUSE systems to
support package splits.
SOLVER_FLAG_IGNORE_RECOMMENDED
Do not process optional (aka weak) dependencies.
SOLVER_FLAG_ADD_ALREADY_RECOMMENDED
Install recommended or supplemented packages even if they
have no connection to the current transaction. You can use this feature to
implement a simple way for the user to install new recommended packages that
were not available in the past.
SOLVER_FLAG_NO_INFARCHCHECK
Turn off the inferior architecture checking that is
normally done by the solver. Normally, the solver allows only the installation
of packages from the "best" architecture if a package is available
for multiple architectures.
SOLVER_FLAG_BEST_OBEY_POLICY
Make the SOLVER_FORCEBEST job option consider only
packages that meet the policies for installed packages, i.e. no downgrades, no
architecture change, no vendor change (see the first flags of this section).
If the flag is not specified, the solver will enforce the installation of the
best package ignoring the installed packages, which may conflict with the set
policy.
SOLVER_FLAG_NO_AUTOTARGET
Do not enable auto-targeting up update and distupgrade
jobs. See the section on targeted updates for more information.
Basic rule types:
SOLVER_RULE_UNKNOWN
A rule of an unknown class. You should never encounter
those.
SOLVER_RULE_RPM
A package dependency rule, called rpm rule for historical
reasons.
SOLVER_RULE_UPDATE
A rule to implement the update policy of installed
packages. Every installed package has an update rule that consists of the
packages that may replace the installed package.
SOLVER_RULE_FEATURE
Feature rules are fallback rules used when a update rule
is disabled. They include all packages that may replace the installed package
ignoring the update policy, i.e. they contain downgrades, arch changes and so
on. Without them, the solver would simply erase installed packages if their
update rule gets disabled.
SOLVER_RULE_JOB
Job rules implement the job given to the solver.
SOLVER_RULE_DISTUPGRADE
This are simple negative assertions that make sure that
only packages are kept that are also available in one of the
repositories.
SOLVER_RULE_INFARCH
Infarch rules are also negative assertions, they disallow
the installation of packages when there are packages of the same name but with
a better architecture.
SOLVER_RULE_CHOICE
Choice rules are used to make sure that the solver
prefers updating to installing different packages when some dependency is
provided by multiple packages with different names. The solver may always
break choice rules, so you will not see them when a problem is found.
SOLVER_RULE_LEARNT
These rules are generated by the solver to keep it from
running into the same problem multiple times when it has to backtrack. They
are the main reason why a sat solver is faster then other dependency solver
implementations.
Special dependency rule types:
SOLVER_RULE_RPM_NOT_INSTALLABLE
This rule was added to prevent the installation of a
package of an architecture that does not work on the system.
SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP
The package contains a required dependency which was not
provided by any package.
SOLVER_RULE_RPM_PACKAGE_REQUIRES
Similar to SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP, but in
this case some packages provided the dependency but none of them could be
installed due to other dependency issues.
SOLVER_RULE_RPM_SELF_CONFLICT
The package conflicts with itself. This is not allowed by
older rpm versions.
SOLVER_RULE_RPM_PACKAGE_CONFLICT
To fulfill the dependencies two packages need to be
installed, but one of the packages contains a conflict with the other
one.
SOLVER_RULE_RPM_SAME_NAME
The dependencies can only be fulfilled by multiple
versions of a package, but installing multiple versions of the same package is
not allowed.
SOLVER_RULE_RPM_PACKAGE_OBSOLETES
To fulfill the dependencies two packages need to be
installed, but one of the packages obsoletes the other one.
SOLVER_RULE_RPM_IMPLICIT_OBSOLETES
To fulfill the dependencies two packages need to be
installed, but one of the packages has provides a dependency that is obsoleted
by the other one. See the POOL_FLAG_IMPLICITOBSOLETEUSESPROVIDES flag.
SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES
To fulfill the dependencies a package needs to be
installed that is obsoleted by an installed package. See the
POOL_FLAG_NOINSTALLEDOBSOLETES flag.
SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP
The user asked for installation of a package providing a
specific dependency, but no available package provides it.
SOLVER_RULE_JOB_UNKNOWN_PACKAGE
The user asked for installation of a package with a
specific name, but no available package has that name.
SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM
The user asked for the erasure of a dependency that is
provided by the system (i.e. for special hardware or language dependencies),
this cannot be done with a job.
SOLVER_RULE_JOB_UNSUPPORTED
The user asked for something that is not yet implemented,
e.g. the installation of all packages at once.
Policy error constants
POLICY_ILLEGAL_DOWNGRADE
The solver ask for permission before downgrading
packages.
POLICY_ILLEGAL_ARCHCHANGE
The solver ask for permission before changing the
architecture of installed packages.
POLICY_ILLEGAL_VENDORCHANGE
The solver ask for permission before changing the vendor
of installed packages.
POLICY_ILLEGAL_NAMECHANGE
The solver ask for permission before replacing an
installed packages with a package that has a different name.
Solution element type constants
SOLVER_SOLUTION_JOB
The problem can be solved by removing the specified
job.
SOLVER_SOLUTION_POOLJOB
The problem can be solved by removing the specified job
that is defined in the pool.
SOLVER_SOLUTION_INFARCH
The problem can be solved by allowing the installation of
the specified package with an inferior architecture.
SOLVER_SOLUTION_DISTUPGRADE
The problem can be solved by allowing to keep the
specified package installed.
SOLVER_SOLUTION_BEST
The problem can be solved by allowing to install the
specified package that is not the best available package.
SOLVER_SOLUTION_ERASE
The problem can be solved by allowing to erase the
specified package.
SOLVER_SOLUTION_REPLACE
The problem can be solved by allowing to replace the
package with some other package.
SOLVER_SOLUTION_REPLACE_DOWNGRADE
The problem can be solved by allowing to replace the
package with some other package that has a lower version.
SOLVER_SOLUTION_REPLACE_ARCHCHANGE
The problem can be solved by allowing to replace the
package with some other package that has a different architecture.
SOLVER_SOLUTION_REPLACE_VENDORCHANGE
The problem can be solved by allowing to replace the
package with some other package that has a different vendor.
SOLVER_SOLUTION_REPLACE_NAMECHANGE
The problem can be solved by allowing to replace the
package with some other package that has a different name.
Reason constants
SOLVER_REASON_UNRELATED
The package status did not change as it was not related
to any job.
SOLVER_REASON_UNIT_RULE
The package was installed/erased/kept because of a unit
rule, i.e. a rule where all literals but one were false.
SOLVER_REASON_KEEP_INSTALLED
The package was chosen when trying to keep as many
packages installed as possible.
SOLVER_REASON_RESOLVE_JOB
The decision happened to fulfill a job rule.
SOLVER_REASON_UPDATE_INSTALLED
The decision happened to fulfill a package update
request.
SOLVER_REASON_CLEANDEPS_ERASE
The package was erased when cleaning up dependencies from
other erased packages.
SOLVER_REASON_RESOLVE
The package was installed to fulfill package
dependencies.
SOLVER_REASON_WEAKDEP
The package was installed because of a weak dependency
(Recommends or Supplements).
SOLVER_REASON_RESOLVE_ORPHAN
The decision about the package was made when deciding the
fate of orphaned packages.
SOLVER_REASON_RECOMMENDED
This is a special case of SOLVER_REASON_WEAKDEP.
SOLVER_REASON_SUPPLEMENTED
This is a special case of SOLVER_REASON_WEAKDEP.
ATTRIBUTES¶
Pool *pool; /* read only */ $job->{pool} d.pool d.pool
METHODS¶
int set_flag(int flag, int value) my $oldvalue = $solver->set_flag($flag, $value); oldvalue = solver.set_flag(flag, value) oldvalue = solver.set_flag(flag, value)
int get_flag(int flag) my $value = $solver->get_flag($flag); value = solver.get_flag(flag) value = solver.get_flag(flag)
Problem *solve(Job *jobs) my @problems = $solver->solve(\@jobs); problems = solver.solve(jobs) problems = solver.solve(jobs)
Transaction transaction() my $trans = $solver->transaction(); trans = solver.transaction() trans = solver.transaction()
int reason = describe_decision(Solvable *s, Rule *OUTPUT) my ($reason, $rule) = $solver->describe_decision($solvable); (reason, rule) = solver.describe_decision(solvable) (reason, rule) = solver.describe_decision(solvable)
THE PROBLEM CLASS¶
Problems are the way of the solver to interact with the user. You can simply list all problems and terminate your program, but a better way is to present solutions to the user and let him pick the ones he likes.ATTRIBUTES¶
Solver *solv; /* read only */ $problem->{solv} problem.solv problem.solv
Id id; /* read only */ $problem->{id} problem.id problem.id
METHODS¶
Rule findproblemrule() my $probrule = $problem->findproblemrule(); probrule = problem.findproblemrule() probrule = problem.findproblemrule()
Rule *findallproblemrules(bool unfiltered = 0) my @probrules = $problem->findallproblemrules(); probrules = problem.findallproblemrule() probrules = problem.findallproblemrule()
Solution *solutions() my @solutions = $problem->solutions(); solutions = problem.solutions() solutions = problem.solutions()
int solution_count() my $cnt = $problem->solution_count(); cnt = problem.solution_count() cnt = problem.solution_count()
<stringification> my $str = $problem->str; str = str(problem) str = problem.to_s
THE RULE CLASS¶
Rules are the basic block of sat solving. Each package dependency gets translated into one or multiple rules.ATTRIBUTES¶
Solver *solv; /* read only */ $rule->{solv} rule.solv rule.solv
Id id; /* read only */ $rule->{id} rule.id rule.id
int type; /* read only */ $rule->{type} rule.type rule.type
METHODS¶
Ruleinfo info() my $ruleinfo = $rule->info(); ruleinfo = rule.info() ruleinfo = rule.info()
Ruleinfo *allinfos() my @ruleinfos = $rule->allinfos(); ruleinfos = rule.allinfos() ruleinfos = rule.allinfos()
<equality> if ($rule1 == $rule2) if rule1 == rule2: if rule1 == rule2
THE RULEINFO CLASS¶
A Ruleinfo describes one reason why a rule was created.ATTRIBUTES¶
Solver *solv; /* read only */ $ruleinfo->{solv} ruleinfo.solv ruleinfo.solv
int type; /* read only */ $ruleinfo->{type} ruleinfo.type ruleinfo.type
Dep *dep; /* read only */ $ruleinfo->{dep} ruleinfo.dep ruleinfo.dep
Dep *dep_id; /* read only */ $ruleinfo->{'dep_id'} ruleinfo.dep_id ruleinfo.dep_id
Solvable *solvable; /* read only */ $ruleinfo->{solvable} ruleinfo.solvable ruleinfo.solvable
Solvable *othersolvable; /* read only */ $ruleinfo->{othersolvable} ruleinfo.othersolvable ruleinfo.othersolvable
const char *problemstr(); my $str = $ruleinfo->problemstr(); str = ruleinfo.problemstr() str = ruleinfo.problemstr()
THE SOLUTION CLASS¶
A solution solves one specific problem. It consists of multiple solution elements that all need to be executed.ATTRIBUTES¶
Solver *solv; /* read only */ $solution->{solv} solution.solv solution.solv
Id problemid; /* read only */ $solution->{problemid} solution.problemid solution.problemid
Id id; /* read only */ $solution->{id} solution.id solution.id
METHODS¶
Solutionelement *elements(bool expandreplaces = 0) my @solutionelements = $solution->elements(); solutionelements = solution.elements() solutionelements = solution.elements()
int element_count() my $cnt = $solution->solution_count(); cnt = solution.element_count() cnt = solution.element_count()
THE SOLUTIONELEMENT CLASS¶
A solution element describes a single action of a solution. The action is always either to remove one specific job or to add a new job that installs or erases a single specific package.ATTRIBUTES¶
Solver *solv; /* read only */ $solutionelement->{solv} solutionelement.solv solutionelement.solv
Id problemid; /* read only */ $solutionelement->{problemid} solutionelement.problemid solutionelement.problemid
Id solutionid; /* read only */ $solutionelement->{solutionid} solutionelement.solutionid solutionelement.solutionid
Id id; /* read only */ $solutionelement->{id} solutionelement.id solutionelement.id
Id type; /* read only */ $solutionelement->{type} solutionelement.type solutionelement.type
Solvable *solvable; /* read only */ $solutionelement->{solvable} solutionelement.solvable solutionelement.solvable
Solvable *replacement; /* read only */ $solutionelement->{replacement} solutionelement.replacement solutionelement.replacement
int jobidx; /* read only */ $solutionelement->{jobidx} solutionelement.jobidx solutionelement.jobidx
METHODS¶
Solutionelement *replaceelements() my @solutionelements = $solutionelement->replaceelements(); solutionelements = solutionelement.replaceelements() solutionelements = solutionelement.replaceelements()
int illegalreplace() my $illegal = $solutionelement->illegalreplace(); illegal = solutionelement.illegalreplace() illegal = solutionelement.illegalreplace()
Job Job() my $job = $solutionelement->Job(); illegal = solutionelement.Job() illegal = solutionelement.Job()
const char *str() my $str = $solutionelement->str(); str = solutionelement.str() str = solutionelement.str()
THE TRANSACTION CLASS¶
Transactions describe the output of a solver run. A transaction contains a number of transaction elements, each either the installation of a new package or the removal of an already installed package. The Transaction class supports a classify() method that puts the elements into different groups so that a transaction can be presented to the user in a meaningful way.CONSTANTS¶
Transaction element types, both active and passive SOLVER_TRANSACTION_IGNOREThis element does nothing. Used to map element types that
do not match the view mode.
SOLVER_TRANSACTION_INSTALL
This element installs a package.
SOLVER_TRANSACTION_ERASE
This element erases a package.
SOLVER_TRANSACTION_MULTIINSTALL
This element installs a package with a different version
keeping the other versions installed.
SOLVER_TRANSACTION_MULTIREINSTALL
This element reinstalls a installed package keeping the
other versions installed.
Transaction element types, active view
SOLVER_TRANSACTION_REINSTALL
This element re-installs a package, i.e. installs the
same package again.
SOLVER_TRANSACTION_CHANGE
This element installs a package with same name, version,
architecture but different content.
SOLVER_TRANSACTION_UPGRADE
This element installs a newer version of an installed
package.
SOLVER_TRANSACTION_DOWNGRADE
This element installs a older version of an installed
package.
SOLVER_TRANSACTION_OBSOLETES
This element installs a package that obsoletes an
installed package.
Transaction element types, passive view
SOLVER_TRANSACTION_REINSTALLED
This element re-installs a package, i.e. installs the
same package again.
SOLVER_TRANSACTION_CHANGED
This element replaces an installed package with one of
the same name, version, architecture but different content.
SOLVER_TRANSACTION_UPGRADED
This element replaces an installed package with a new
version.
SOLVER_TRANSACTION_DOWNGRADED
This element replaces an installed package with an old
version.
SOLVER_TRANSACTION_OBSOLETED
This element replaces an installed package with a package
that obsoletes it.
Pseudo element types for showing extra information used by classify()
SOLVER_TRANSACTION_ARCHCHANGE
This element replaces an installed package with a package
of a different architecture.
SOLVER_TRANSACTION_VENDORCHANGE
This element replaces an installed package with a package
of a different vendor.
Transaction mode flags
SOLVER_TRANSACTION_SHOW_ACTIVE
Filter for active view types. The default is to return
passive view type, i.e. to show how the installed packages get changed.
SOLVER_TRANSACTION_SHOW_OBSOLETES
Do not map the obsolete view type into INSTALL/ERASE
elements.
SOLVER_TRANSACTION_SHOW_ALL
If multiple packages replace an installed package, only
the best of them is kept as OBSOLETE element, the other ones are mapped to
INSTALL/ERASE elements. This is because most applications want to show just
one package replacing the installed one. The SOLVER_TRANSACTION_SHOW_ALL makes
the library keep all OBSOLETE elements.
SOLVER_TRANSACTION_SHOW_MULTIINSTALL
The library maps MULTIINSTALL elements to simple INSTALL
elements. This flag can be used to disable the mapping.
SOLVER_TRANSACTION_CHANGE_IS_REINSTALL
Use this flag if you want to map CHANGE elements to the
REINSTALL type.
SOLVER_TRANSACTION_OBSOLETE_IS_UPGRADE
Use this flag if you want to map OBSOLETE elements to the
UPGRADE type.
SOLVER_TRANSACTION_MERGE_ARCHCHANGES
Do not add extra categories for every architecture
change, instead cumulate them in one category.
SOLVER_TRANSACTION_MERGE_VENDORCHANGES
Do not add extra categories for every vendor change,
instead cumulate them in one category.
SOLVER_TRANSACTION_RPM_ONLY
Special view mode that just returns IGNORE, ERASE,
INSTALL, MULTIINSTALL elements. Useful if you want to find out what to feed to
the underlying package manager.
Transaction order flags
SOLVER_TRANSACTION_KEEP_ORDERDATA
Do not throw away the dependency graph used for ordering
the transaction. This flag is needed if you want to do manual ordering.
ATTRIBUTES¶
Pool *pool; /* read only */ $trans->{pool} trans.pool trans.pool
METHODS¶
bool isempty(); $trans->isempty() trans.isempty() trans.isempty?
Solvable *newsolvables(); my @newsolvables = $trans->newsolvables(); newsolvables = trans.newsolvables() newsolvables = trans.newsolvables()
Solvable *keptsolvables(); my @keptsolvables = $trans->keptsolvables(); keptsolvables = trans.keptsolvables() keptsolvables = trans.keptsolvables()
Solvable *steps(); my @steps = $trans->steps(); steps = trans.steps() steps = trans.steps()
int steptype(Solvable *solvable, int mode) my $type = $trans->steptype($solvable, $mode); type = trans.steptype(solvable, mode) type = trans.steptype(solvable, mode)
TransactionClass *classify(int mode = 0) my @classes = $trans->classify(); classes = trans.classify() classes = trans.classify()
Solvable othersolvable(Solvable *solvable); my $other = $trans->othersolvable($solvable); other = trans.othersolvable(solvable) other = trans.othersolvable(solvable)
Solvable *allothersolvables(Solvable *solvable); my @others = $trans->allothersolvables($solvable); others = trans.allothersolvables(solvable) others = trans.allothersolvables(solvable)
int calc_installsizechange(); my $change = $trans->calc_installsizechange(); change = trans.calc_installsizechange() change = trans.calc_installsizechange()
void order(int flags = 0); $trans->order(); trans.order() trans.order()
ACTIVE/PASSIVE VIEW¶
Active view list what new packages get installed, while passive view shows what happens to the installed packages. Most often there’s not much difference between the two modes, but things get interesting of multiple package get replaced by one new package. Say you have installed package A-1-1 and B-1-1, and now install A-2-1 with has a new dependency that obsoletes B. The transaction elements will beupdated A-1-1 (other: A-2-1) obsoleted B-1-1 (other: A-2-1)
update A-2-1 (other: A-1-1) erase B
THE TRANSACTIONCLASS CLASS¶
Objects of this type are returned by the classify() Transaction method.ATTRIBUTES¶
Transaction *transaction; /* read only */ $class->{transaction} class.transaction class.transaction
int type; /* read only */ $class->{type} class.type class.type
int count; /* read only */ $class->{count} class.count class.count
const char *fromstr; $class->{fromstr} class.fromstr class.fromstr
const char *tostr; $class->{tostr} class.tostr class.tostr
Id fromid; $class->{fromid} class.fromid class.fromid
Id toid; $class->{toid} class.toid class.toid
METHODS¶
void solvables(); my @solvables = $class->solvables(); solvables = class.solvables() solvables = class.solvables()
CHECKSUMS¶
Checksums (also called hashes) are used to make sure that downloaded data is not corrupt and also as a fingerprint mechanism to check if data has changed.CLASS METHODS¶
Chksum Chksum(Id type) my $chksum = solv::Chksum->new($type); chksum = solv.Chksum(type) chksum = Solv::Chksum.new(type)
REPOKEY_TYPE_MD5 REPOKEY_TYPE_SHA1 REPOKEY_TYPE_SHA256
Chksum Chksum(Id type, const char *hex) my $chksum = solv::Chksum->new($type, $hex); chksum = solv.Chksum(type, hex) chksum = Solv::Chksum.new(type, hex)
ATTRIBUTES¶
Id type; /* read only */ $chksum->{type} chksum.type chksum.type
METHODS¶
void add(const char *str) $chksum->add($str); chksum.add(str) chksum.add(str)
void add_fp(FILE *fp) $chksum->add_fp($file); chksum.add_fp(file) chksum.add_fp(file)
void add_stat(const char *filename) $chksum->add_stat($filename); chksum.add_stat(filename) chksum.add_stat(filename)
void add_fstat(int fd) $chksum->add_fstat($fd); chksum.add_fstat(fd) chksum.add_fstat(fd)
unsigned char *raw() my $raw = $chksum->raw(); raw = chksum.raw() raw = chksum.raw()
const char *hex() my $raw = $chksum->hex(); raw = chksum.hex() raw = chksum.hex()
const char *typestr() my $typestr = $chksum->typestr(); typestr = chksum.typestr typestr = chksum.typestr
<equality> if ($chksum1 == $chksum2) if chksum1 == chksum2: if chksum1 == chksum2
<stringification> my $str = $chksum->str; str = str(chksum) str = chksum.to_s
FILE MANAGEMENT¶
This functions were added because libsolv uses standard FILE pointers to read/write files, but languages like perl have their own implementation of files. The libsolv functions also support decompression and compression, the algorithm is selected by looking at the file name extension.FILE *xfopen(char *fn, char *mode = "r") my $file = solv::xfopen($path); file = solv.xfopen(path) file = Solv::xfopen(path)
FILE *xfopen_fd(char *fn, int fileno) my $file = solv::xfopen_fd($path, $fileno); file = solv.xfopen_fd(path, fileno) file = Solv::xfopen_fd(path, fileno)
METHODS¶
int fileno() my $fileno = $file->fileno(); fileno = file.fileno() fileno = file.fileno()
int dup() my $fileno = $file->dup(); fileno = file.dup() fileno = file.dup()
bool flush() $file->flush(); file.flush() file.flush()
bool close() $file->close(); file.close() file.close()
THE REPODATA CLASS¶
The Repodata stores attributes for packages and the repository itself, each repository can have multiple repodata areas. You normally only need to directly access them if you implement lazy downloading of repository data. Repodata areas are created by calling the repository’s add_repodata() method or by using repo_add methods without the REPO_REUSE_REPODATA or REPO_USE_LOADING flag.ATTRIBUTES¶
Repo *repo; /* read only */ $data->{repo} data.repo data.repo
Id id; /* read only */ $data->{id} data.id data.id
METHODS¶
internalize(); $data->internalize(); data.internalize() data.internalize()
bool write(FILE *fp); $data->write($fp); data.write(fp) data.write(fp)
bool add_solv(FILE *fp, int flags = 0); $data->add_solv($fp); data.add_solv(fp) data.add_solv(fp)
void create_stubs(); $data->create_stubs() data.create_stubs() data.create_stubs()
void extend_to_repo(); $data->extend_to_repo(); data.extend_to_repo() data.extend_to_repo()
<equality> if ($data1 == $data2) if data1 == data2: if data1 == data2
DATA RETRIEVAL METHODS¶
const char *lookup_str(Id solvid, Id keyname) my $string = $data->lookup_str($solvid, $keyname); string = data.lookup_str(solvid, keyname) string = data.lookup_str(solvid, keyname)
Id *lookup_idarray(Id solvid, Id keyname) my @ids = $data->lookup_idarray($solvid, $keyname); ids = data.lookup_idarray(solvid, keyname) ids = data.lookup_idarray(solvid, keyname)
Chksum lookup_checksum(Id solvid, Id keyname) my $chksum = $data->lookup_checksum($solvid, $keyname); chksum = data.lookup_checksum(solvid, keyname) chksum = data.lookup_checksum(solvid, keyname)
DATA STORAGE METHODS¶
void set_id(Id solvid, Id keyname, DepId id); $data->set_id($solvid, $keyname, $id); data.set_id(solvid, keyname, id) data.set_id(solvid, keyname, id)
void set_str(Id solvid, Id keyname, const char *str); $data->set_str($solvid, $keyname, $str); data.set_str(solvid, keyname, str) data.set_str(solvid, keyname, str)
void set_poolstr(Id solvid, Id keyname, const char *str); $data->set_poolstr($solvid, $keyname, $str); data.set_poolstr(solvid, keyname, str) data.set_poolstr(solvid, keyname, str)
void set_checksum(Id solvid, Id keyname, Chksum *chksum); $data->set_checksum($solvid, $keyname, $chksum); data.set_checksum(solvid, keyname, chksum) data.set_checksum(solvid, keyname, chksum)
void add_idarray(Id solvid, Id keyname, DepId id); $data->add_idarray($solvid, $keyname, $id); data.add_idarray(solvid, keyname, id) data.add_idarray(solvid, keyname, id)
Id new_handle(); my $handle = $data->new_handle(); handle = data.new_handle() handle = data.new_handle()
void add_flexarray(Id solvid, Id keyname, Id handle); $data->add_flexarray($solvid, $keyname, $handle); data.add_flexarray(solvid, keyname, handle) data.add_flexarray(solvid, keyname, handle)
THE DATAPOS CLASS¶
Datapos objects describe a specific position in the repository data area. Thus they are only valid until the repository is modified in some way. Datapos objects can be created by the pos() and parentpos() methods of a Datamatch object or by accessing the “meta” attribute of a repository.ATTRIBUTES¶
Repo *repo; /* read only */ $data->{repo} data.repo data.repo
METHODS¶
Dataiterator(Id keyname, const char *match, int flags) my $di = $datapos->Dataiterator($keyname, $match, $flags); di = datapos.Dataiterator(keyname, match, flags) di = datapos.Dataiterator(keyname, match, flags)
const char *lookup_deltalocation(unsigned int *OUTPUT); my ($location, $medianr) = $datapos->lookup_deltalocation(); location, medianr = datapos.lookup_deltalocation() location, medianr = datapos.lookup_deltalocation()
const char *lookup_deltaseq(); my $seq = $datapos->lookup_deltaseq(); seq = datapos.lookup_deltaseq(); seq = datapos.lookup_deltaseq();
DATA RETRIEVAL METHODS¶
const char *lookup_str(Id keyname) my $string = $datapos->lookup_str($keyname); string = datapos.lookup_str(keyname) string = datapos.lookup_str(keyname)
Id lookup_id(Id solvid, Id keyname) my $id = $datapos->lookup_id($keyname); id = datapos.lookup_id(keyname) id = datapos.lookup_id(keyname)
unsigned long long lookup_num(Id keyname, unsigned long long notfound = 0) my $num = $datapos->lookup_num($keyname); num = datapos.lookup_num(keyname) num = datapos.lookup_num(keyname)
bool lookup_void(Id keyname) my $bool = $datapos->lookup_void($keyname); bool = datapos.lookup_void(keyname) bool = datapos.lookup_void(keyname)
Id *lookup_idarray(Id keyname) my @ids = $datapos->lookup_idarray($keyname); ids = datapos.lookup_idarray(keyname) ids = datapos.lookup_idarray(keyname)
Chksum lookup_checksum(Id keyname) my $chksum = $datapos->lookup_checksum($keyname); chksum = datapos.lookup_checksum(keyname) chksum = datapos.lookup_checksum(keyname)
Dataiterator Dataiterator(Id keyname, const char *match = 0, int flags = 0) my $di = $datapos->Dataiterator($keyname, $match, $flags); di = datapos.Dataiterator(keyname, match, flags) di = datapos.Dataiterator(keyname, match, flags)
for my $d (@$di) for d in di: for d in di
AUTHOR¶
Michael Schroeder <mls@suse.de>04/04/2014 | libsolv |