]> git.ipfire.org Git - people/ms/ipfire-3.x.git/blame - pakfire/patches/0011-Move-C-module-to-newer-version-of-libsolv.patch
pakfire: Rebase on latest development status.
[people/ms/ipfire-3.x.git] / pakfire / patches / 0011-Move-C-module-to-newer-version-of-libsolv.patch
CommitLineData
d72d822f
MT
1From 9b68f47c96625fdafc9b3810de08563abe8e78be Mon Sep 17 00:00:00 2001
2From: Michael Tremer <michael.tremer@ipfire.org>
3Date: Wed, 16 May 2012 12:43:25 +0000
4Subject: [PATCH 11/16] Move C module to newer version of libsolv.
5
6Many more improvements which should make the
7transaction check much faster.
8---
9 po/pakfire.pot | 155 +++++++++++++++++----------------
10 python/pakfire/actions.py | 10 +--
11 python/pakfire/base.py | 36 +++++---
12 python/pakfire/builder.py | 3 +-
13 python/pakfire/filelist.py | 13 +--
14 python/pakfire/packages/installed.py | 18 ++--
15 python/pakfire/repository/database.py | 46 +++++-----
16 python/pakfire/repository/index.py | 9 +-
17 python/pakfire/repository/system.py | 50 +++++++++--
18 python/pakfire/satsolver.py | 65 ++++----------
19 python/pakfire/transaction.py | 49 +++++------
20 python/src/_pakfiremodule.c | 18 +++-
21 python/src/repo.c | 31 ++++---
22 python/src/repo.h | 1 +
23 python/src/request.c | 64 +++++++-------
24 python/src/request.h | 4 +
25 python/src/solution.c | 8 +-
26 python/src/solver.c | 88 +++++++++++--------
27 python/src/solver.h | 5 +-
28 19 files changed, 368 insertions(+), 305 deletions(-)
29
30diff --git a/po/pakfire.pot b/po/pakfire.pot
31index 4fd12e7..db3a88f 100644
32--- a/po/pakfire.pot
33+++ b/po/pakfire.pot
34@@ -8,7 +8,7 @@ msgid ""
35 msgstr ""
36 "Project-Id-Version: PACKAGE VERSION\n"
37 "Report-Msgid-Bugs-To: \n"
38-"POT-Creation-Date: 2012-04-19 16:57+0200\n"
39+"POT-Creation-Date: 2012-05-16 12:33+0000\n"
40 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
41 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
42 "Language-Team: LANGUAGE <LL@li.org>\n"
43@@ -73,13 +73,13 @@ msgid "Exception occured: %s"
44 msgstr ""
45
46 #: ../python/pakfire/actions.py:364 ../python/pakfire/actions.py:402
47-#: ../python/pakfire/actions.py:425 ../python/pakfire/actions.py:448
48-#: ../python/pakfire/actions.py:465 ../python/pakfire/actions.py:484
49+#: ../python/pakfire/actions.py:424 ../python/pakfire/actions.py:446
50+#: ../python/pakfire/actions.py:463 ../python/pakfire/actions.py:482
51 #, python-format
52 msgid "Running transaction test for %s"
53 msgstr ""
54
55-#: ../python/pakfire/actions.py:373 ../python/pakfire/actions.py:477
56+#: ../python/pakfire/actions.py:373
57 msgid "Installing"
58 msgstr ""
59
60@@ -87,63 +87,67 @@ msgstr ""
61 msgid "Updating"
62 msgstr ""
63
64-#: ../python/pakfire/actions.py:431
65+#: ../python/pakfire/actions.py:430
66 msgid "Removing"
67 msgstr ""
68
69 #. Cleaning up leftover files and stuff.
70-#: ../python/pakfire/actions.py:455
71+#: ../python/pakfire/actions.py:453
72 msgid "Cleanup"
73 msgstr ""
74
75-#: ../python/pakfire/actions.py:493
76+#: ../python/pakfire/actions.py:475
77+msgid "Reinstalling"
78+msgstr ""
79+
80+#: ../python/pakfire/actions.py:491
81 msgid "Downgrading"
82 msgstr ""
83
84-#: ../python/pakfire/base.py:315
85+#: ../python/pakfire/base.py:320
86 msgid "Local install repository"
87 msgstr ""
88
89-#: ../python/pakfire/base.py:372
90+#: ../python/pakfire/base.py:377
91 #, python-format
92 msgid "Could not find any installed package providing \"%s\"."
93 msgstr ""
94
95-#: ../python/pakfire/base.py:378
96+#: ../python/pakfire/base.py:383
97 #, python-format
98 msgid "Multiple reinstall candidates for \"%(pattern)s\": %(pkgs)s"
99 msgstr ""
100
101-#: ../python/pakfire/base.py:382 ../python/pakfire/base.py:450
102-#: ../python/pakfire/base.py:487 ../python/pakfire/base.py:546
103-#: ../python/pakfire/base.py:567 ../python/pakfire/transaction.py:396
104+#: ../python/pakfire/base.py:387 ../python/pakfire/base.py:455
105+#: ../python/pakfire/base.py:491 ../python/pakfire/base.py:553
106+#: ../python/pakfire/base.py:574 ../python/pakfire/transaction.py:390
107 msgid "Nothing to do"
108 msgstr ""
109
110-#: ../python/pakfire/base.py:407
111+#: ../python/pakfire/base.py:412
112 #, python-format
113 msgid "Could not find package %s in a remote repository."
114 msgstr ""
115
116-#: ../python/pakfire/base.py:479
117+#: ../python/pakfire/base.py:483
118 #, python-format
119 msgid "Excluding %s."
120 msgstr ""
121
122-#: ../python/pakfire/base.py:531
123+#: ../python/pakfire/base.py:535
124 #, python-format
125 msgid "\"%s\" package does not seem to be installed."
126 msgstr ""
127
128-#: ../python/pakfire/base.py:681
129+#: ../python/pakfire/base.py:688
130 msgid "Build command has failed."
131 msgstr ""
132
133-#: ../python/pakfire/base.py:716
134+#: ../python/pakfire/base.py:723
135 msgid "New repository"
136 msgstr ""
137
138-#: ../python/pakfire/base.py:752
139+#: ../python/pakfire/base.py:764
140 msgid "Everything is fine."
141 msgstr ""
142
143@@ -199,72 +203,72 @@ msgstr ""
144 msgid "Running installation test..."
145 msgstr ""
146
147-#: ../python/pakfire/builder.py:766
148+#: ../python/pakfire/builder.py:767
149 msgid "Installation test succeeded."
150 msgstr ""
151
152 #. Create a progressbar.
153-#: ../python/pakfire/builder.py:803
154+#: ../python/pakfire/builder.py:804
155 msgid "Signing packages..."
156 msgstr ""
157
158-#: ../python/pakfire/builder.py:837
159+#: ../python/pakfire/builder.py:838
160 msgid "Dumping package information:"
161 msgstr ""
162
163 #. Walk through the whole tree and collect all files
164 #. that are on the same disk (not crossing mountpoints).
165-#: ../python/pakfire/builder.py:867
166+#: ../python/pakfire/builder.py:868
167 msgid "Creating filelist..."
168 msgstr ""
169
170 #. Create a nice progressbar.
171-#: ../python/pakfire/builder.py:886
172+#: ../python/pakfire/builder.py:887
173 msgid "Compressing files..."
174 msgstr ""
175
176-#: ../python/pakfire/builder.py:905
177+#: ../python/pakfire/builder.py:906
178 #, python-format
179 msgid "Cache file was successfully created at %s."
180 msgstr ""
181
182-#: ../python/pakfire/builder.py:906
183+#: ../python/pakfire/builder.py:907
184 #, python-format
185 msgid " Containing %(files)s files, it has a size of %(size)s."
186 msgstr ""
187
188 #. Make a nice progress bar as always.
189-#: ../python/pakfire/builder.py:917
190+#: ../python/pakfire/builder.py:918
191 msgid "Extracting files..."
192 msgstr ""
193
194 #. Update all packages.
195-#: ../python/pakfire/builder.py:937
196+#: ../python/pakfire/builder.py:938
197 msgid "Updating packages from cache..."
198 msgstr ""
199
200 #. Package the result.
201 #. Make all these little package from the build environment.
202-#: ../python/pakfire/builder.py:1075
203+#: ../python/pakfire/builder.py:1076
204 msgid "Creating packages:"
205 msgstr ""
206
207 #. Execute the buildscript of this stage.
208-#: ../python/pakfire/builder.py:1089
209+#: ../python/pakfire/builder.py:1090
210 #, python-format
211 msgid "Running stage %s:"
212 msgstr ""
213
214-#: ../python/pakfire/builder.py:1107
215+#: ../python/pakfire/builder.py:1108
216 #, python-format
217 msgid "Could not remove static libraries: %s"
218 msgstr ""
219
220-#: ../python/pakfire/builder.py:1113
221+#: ../python/pakfire/builder.py:1114
222 msgid "Compressing man pages did not complete successfully."
223 msgstr ""
224
225-#: ../python/pakfire/builder.py:1133
226+#: ../python/pakfire/builder.py:1134
227 msgid "Extracting debuginfo did not complete with success. Aborting build."
228 msgstr ""
229
230@@ -416,7 +420,7 @@ msgstr ""
231 msgid "Give name of at least one package to check."
232 msgstr ""
233
234-#: ../python/pakfire/cli.py:348 ../python/pakfire/transaction.py:405
235+#: ../python/pakfire/cli.py:348 ../python/pakfire/transaction.py:399
236 msgid "Repository"
237 msgstr ""
238
239@@ -740,7 +744,7 @@ msgid "Job: %(name)s"
240 msgstr ""
241
242 #: ../python/pakfire/cli.py:1078 ../python/pakfire/packages/base.py:107
243-#: ../python/pakfire/transaction.py:404
244+#: ../python/pakfire/transaction.py:398
245 msgid "Arch"
246 msgstr ""
247
248@@ -992,7 +996,7 @@ msgstr ""
249 msgid "Running pakfire-build in a pakfire container?"
250 msgstr ""
251
252-#: ../python/pakfire/errors.py:94 ../python/pakfire/transaction.py:475
253+#: ../python/pakfire/errors.py:94 ../python/pakfire/transaction.py:469
254 msgid "Transaction test was not successful"
255 msgstr ""
256
257@@ -1085,7 +1089,7 @@ msgstr ""
258 msgid "Name"
259 msgstr ""
260
261-#: ../python/pakfire/packages/base.py:110 ../python/pakfire/transaction.py:404
262+#: ../python/pakfire/packages/base.py:110 ../python/pakfire/transaction.py:398
263 msgid "Version"
264 msgstr ""
265
266@@ -1093,7 +1097,7 @@ msgstr ""
267 msgid "Release"
268 msgstr ""
269
270-#: ../python/pakfire/packages/base.py:115 ../python/pakfire/transaction.py:405
271+#: ../python/pakfire/packages/base.py:115 ../python/pakfire/transaction.py:399
272 msgid "Size"
273 msgstr ""
274
275@@ -1173,7 +1177,7 @@ msgstr ""
276 msgid "Not set"
277 msgstr ""
278
279-#: ../python/pakfire/packages/base.py:528
280+#: ../python/pakfire/packages/base.py:534
281 #, python-format
282 msgid "Config file saved as %s."
283 msgstr ""
284@@ -1243,16 +1247,16 @@ msgstr ""
285 msgid "Building source package %s:"
286 msgstr ""
287
288-#: ../python/pakfire/repository/database.py:116
289+#: ../python/pakfire/repository/database.py:123
290 msgid "The format of the database is not supported by this version of pakfire."
291 msgstr ""
292
293-#: ../python/pakfire/repository/database.py:224
294+#: ../python/pakfire/repository/database.py:231
295 #, python-format
296 msgid "Cannot use database with version greater than %s."
297 msgstr ""
298
299-#: ../python/pakfire/repository/database.py:226
300+#: ../python/pakfire/repository/database.py:233
301 #, python-format
302 msgid "Migrating database from format %(old)s to %(new)s."
303 msgstr ""
304@@ -1320,33 +1324,38 @@ msgstr ""
305 msgid "Trying an other mirror."
306 msgstr ""
307
308-#: ../python/pakfire/satsolver.py:230 ../python/pakfire/satsolver.py:256
309+#. Create a progressbar.
310+#: ../python/pakfire/repository/system.py:66
311+msgid "Loading installed packages"
312+msgstr ""
313+
314+#: ../python/pakfire/satsolver.py:199 ../python/pakfire/satsolver.py:225
315 msgid "The solver returned one problem:"
316 msgstr ""
317
318 #. Ask the user if he or she want to modify the request. If not, just exit.
319-#: ../python/pakfire/satsolver.py:272
320+#: ../python/pakfire/satsolver.py:241
321 msgid "Do you want to manually alter the request?"
322 msgstr ""
323
324-#: ../python/pakfire/satsolver.py:275
325+#: ../python/pakfire/satsolver.py:244
326 msgid "You can now try to satisfy the solver by modifying your request."
327 msgstr ""
328
329-#: ../python/pakfire/satsolver.py:280
330+#: ../python/pakfire/satsolver.py:249
331 msgid "Which problem to you want to resolve?"
332 msgstr ""
333
334-#: ../python/pakfire/satsolver.py:282
335+#: ../python/pakfire/satsolver.py:251
336 msgid "Press enter to try to re-solve the request."
337 msgstr ""
338
339-#: ../python/pakfire/satsolver.py:313
340+#: ../python/pakfire/satsolver.py:282
341 #, python-format
342 msgid " Solution: %s"
343 msgstr ""
344
345-#: ../python/pakfire/satsolver.py:322
346+#: ../python/pakfire/satsolver.py:291
347 msgid " Solutions:"
348 msgstr ""
349
350@@ -1354,110 +1363,110 @@ msgstr ""
351 msgid "Could not be determined"
352 msgstr ""
353
354-#: ../python/pakfire/transaction.py:95
355+#: ../python/pakfire/transaction.py:94
356 #, python-format
357 msgid "file %(name)s from %(pkg1)s conflicts with file from package %(pkg2)s"
358 msgstr ""
359
360-#: ../python/pakfire/transaction.py:101
361+#: ../python/pakfire/transaction.py:100
362 #, python-format
363 msgid "file %(name)s from %(pkg)s conflicts with files from %(pkgs)s"
364 msgstr ""
365
366-#: ../python/pakfire/transaction.py:109
367+#: ../python/pakfire/transaction.py:108
368 #, python-format
369 msgid ""
370 "There is not enough space left on %(name)s. Need at least %(size)s to "
371 "perform transaction."
372 msgstr ""
373
374-#: ../python/pakfire/transaction.py:327
375+#: ../python/pakfire/transaction.py:321
376 #, python-format
377 msgid "Not enough space to download %s of packages."
378 msgstr ""
379
380-#: ../python/pakfire/transaction.py:330
381+#: ../python/pakfire/transaction.py:324
382 msgid "Downloading packages:"
383 msgstr ""
384
385-#: ../python/pakfire/transaction.py:404
386+#: ../python/pakfire/transaction.py:398
387 msgid "Package"
388 msgstr ""
389
390-#: ../python/pakfire/transaction.py:409
391+#: ../python/pakfire/transaction.py:403
392 msgid "Installing:"
393 msgstr ""
394
395-#: ../python/pakfire/transaction.py:410
396+#: ../python/pakfire/transaction.py:404
397 msgid "Reinstalling:"
398 msgstr ""
399
400-#: ../python/pakfire/transaction.py:411
401+#: ../python/pakfire/transaction.py:405
402 msgid "Updating:"
403 msgstr ""
404
405-#: ../python/pakfire/transaction.py:412
406+#: ../python/pakfire/transaction.py:406
407 msgid "Downgrading:"
408 msgstr ""
409
410-#: ../python/pakfire/transaction.py:413
411+#: ../python/pakfire/transaction.py:407
412 msgid "Removing:"
413 msgstr ""
414
415-#: ../python/pakfire/transaction.py:419
416+#: ../python/pakfire/transaction.py:413
417 msgid "Transaction Summary"
418 msgstr ""
419
420-#: ../python/pakfire/transaction.py:426
421+#: ../python/pakfire/transaction.py:420
422 msgid "package"
423 msgstr ""
424
425-#: ../python/pakfire/transaction.py:432
426+#: ../python/pakfire/transaction.py:426
427 #, python-format
428 msgid "Total download size: %s"
429 msgstr ""
430
431-#: ../python/pakfire/transaction.py:436
432+#: ../python/pakfire/transaction.py:430
433 #, python-format
434 msgid "Installed size: %s"
435 msgstr ""
436
437-#: ../python/pakfire/transaction.py:439
438+#: ../python/pakfire/transaction.py:433
439 #, python-format
440 msgid "Freed size: %s"
441 msgstr ""
442
443-#: ../python/pakfire/transaction.py:450
444+#: ../python/pakfire/transaction.py:444
445 msgid "Is this okay?"
446 msgstr ""
447
448-#: ../python/pakfire/transaction.py:456
449+#: ../python/pakfire/transaction.py:450
450 msgid "Running Transaction Test"
451 msgstr ""
452
453-#: ../python/pakfire/transaction.py:468
454+#: ../python/pakfire/transaction.py:462
455 msgid "Transaction Test Succeeded"
456 msgstr ""
457
458 #. Make a nice progressbar.
459-#: ../python/pakfire/transaction.py:501
460+#: ../python/pakfire/transaction.py:495
461 msgid "Verifying signatures..."
462 msgstr ""
463
464-#: ../python/pakfire/transaction.py:533
465+#: ../python/pakfire/transaction.py:527
466 #, python-format
467 msgid "Found %s signature error(s)!"
468 msgstr ""
469
470-#: ../python/pakfire/transaction.py:538
471+#: ../python/pakfire/transaction.py:532
472 msgid "Going on because we are running in permissive mode."
473 msgstr ""
474
475-#: ../python/pakfire/transaction.py:539
476+#: ../python/pakfire/transaction.py:533
477 msgid "This is dangerous!"
478 msgstr ""
479
480-#: ../python/pakfire/transaction.py:560
481+#: ../python/pakfire/transaction.py:554
482 msgid "Running transaction"
483 msgstr ""
484
485diff --git a/python/pakfire/actions.py b/python/pakfire/actions.py
486index cdc2778..9fda261 100644
487--- a/python/pakfire/actions.py
488+++ b/python/pakfire/actions.py
489@@ -417,7 +417,6 @@ class ActionRemove(Action):
490 def __init__(self, *args, **kwargs):
491 Action.__init__(self, *args, **kwargs)
492
493- # XXX This is ugly, but works for the moment.
494 self.pkg = self.local.db.get_package_from_solv(self.pkg_solv)
495 assert self.pkg
496
497@@ -431,7 +430,7 @@ class ActionRemove(Action):
498 self.pkg.cleanup(_("Removing"), prefix=self.pakfire.path)
499
500 # Remove package from the database.
501- self.local.rem_package(self.pkg)
502+ self.local.rem_package(self.pkg_solv)
503
504
505 class ActionCleanup(Action):
506@@ -440,7 +439,6 @@ class ActionCleanup(Action):
507 def __init__(self, *args, **kwargs):
508 Action.__init__(self, *args, **kwargs)
509
510- # XXX This is ugly, but works for the moment.
511 self.pkg = self.local.db.get_package_from_solv(self.pkg_solv)
512 assert self.pkg
513
514@@ -455,7 +453,7 @@ class ActionCleanup(Action):
515 self.pkg.cleanup(_("Cleanup"), prefix=self.pakfire.path)
516
517 # Remove package from the database.
518- self.local.rem_package(self.pkg)
519+ self.local.rem_package(self.pkg_solv)
520
521
522 class ActionReinstall(Action):
523@@ -471,10 +469,10 @@ class ActionReinstall(Action):
524 def run(self):
525 # Remove package from the database and add it afterwards.
526 # Sounds weird, but fixes broken entries in the database.
527- self.local.rem_package(self.pkg)
528+ self.local.rem_package(self.pkg_solv)
529 self.local.add_package(self.pkg)
530
531- self.pkg.extract(_("Installing"), prefix=self.pakfire.path)
532+ self.pkg.extract(_("Reinstalling"), prefix=self.pakfire.path)
533
534
535 class ActionDowngrade(Action):
536diff --git a/python/pakfire/base.py b/python/pakfire/base.py
537index 6e2e52e..54485a5 100644
538--- a/python/pakfire/base.py
539+++ b/python/pakfire/base.py
540@@ -132,7 +132,7 @@ class Pakfire(object):
541
542 return ret
543
544- def create_request(self, builder=False, install=None, remove=None, update=None):
545+ def create_request(self, builder=False, install=None, remove=None, update=None, updateall=False):
546 request = satsolver.Request(self.pool)
547
548 # Add multiinstall information.
549@@ -151,6 +151,11 @@ class Pakfire(object):
550 for req in self.expand_requires(update):
551 request.update(req)
552
553+ # Configure the request to update all packages
554+ # if requested.
555+ if updateall:
556+ request.updateall()
557+
558 # Return the request.
559 return request
560
561@@ -467,12 +472,11 @@ class Pakfire(object):
562
563 # If there are given any packets on the command line, we will
564 # only update them. Otherwise, we update the whole system.
565+ updateall = True
566 if pkgs:
567- update = False
568- else:
569- update = True
570+ updateall = False
571
572- request = self.create_request(update=pkgs)
573+ request = self.create_request(update=pkgs, updateall=updateall)
574
575 # Exclude packages that should not be updated.
576 for exclude in excludes or []:
577@@ -481,7 +485,7 @@ class Pakfire(object):
578 exclude = self.create_relation(exclude)
579 request.lock(exclude)
580
581- solver = self.solv(request, logger=logger, update=update, **kwargs)
582+ solver = self.solv(request, logger=logger, **kwargs)
583
584 if not solver.status:
585 logger.info(_("Nothing to do"))
586@@ -534,8 +538,11 @@ class Pakfire(object):
587 request.install(rel)
588
589 # Solve the request.
590- solver = self.solv(request, allow_downgrade=True, allow_vendorchange=allow_vendorchange,
591- allow_archchange=allow_archchange)
592+ solver = self.solv(request,
593+ allow_downgrade=True,
594+ allow_vendorchange=allow_vendorchange,
595+ allow_archchange=allow_archchange,
596+ )
597 assert solver.status is True
598
599 # Create the transaction.
600@@ -556,7 +563,7 @@ class Pakfire(object):
601 request = self.create_request(remove=pkgs)
602
603 # Solve the request.
604- solver = self.solv(request, uninstall=True)
605+ solver = self.solv(request, allow_uninstall=True)
606 assert solver.status is True
607
608 # Create the transaction.
609@@ -737,7 +744,7 @@ class Pakfire(object):
610 # Clean up repository caches.
611 self.repos.clean()
612
613- def check(self, downgrade=True, uninstall=True):
614+ def check(self, allow_downgrade=True, allow_uninstall=True):
615 """
616 Try to fix any errors in the system.
617 """
618@@ -745,8 +752,13 @@ class Pakfire(object):
619 # For that we create an empty request and solver and try to solve
620 # something.
621 request = self.create_request()
622- solver = self.solv(request, fix_system=True, allow_downgrade=downgrade,
623- uninstall=uninstall)
624+ request.verify()
625+
626+ solver = self.solv(
627+ request,
628+ allow_downgrade=allow_downgrade,
629+ allow_uninstall=allow_uninstall,
630+ )
631
632 if solver.status is False:
633 log.info(_("Everything is fine."))
634diff --git a/python/pakfire/builder.py b/python/pakfire/builder.py
635index 494049e..863ade3 100644
636--- a/python/pakfire/builder.py
637+++ b/python/pakfire/builder.py
638@@ -761,7 +761,8 @@ class BuildEnviron(object):
639
640 # Install all packages that were built.
641 self.install(self.find_result_packages(),
642- uninstall=True, signatures_mode="disabled")
643+ allow_vendorchange=True, allow_archchange=True,
644+ allow_uninstall=True, signatures_mode="disabled")
645
646 self.log.info(_("Installation test succeeded."))
647 self.log.info("")
648diff --git a/python/pakfire/filelist.py b/python/pakfire/filelist.py
649index ef7ee35..4bac6ef 100644
650--- a/python/pakfire/filelist.py
651+++ b/python/pakfire/filelist.py
652@@ -74,13 +74,12 @@ class File(_File):
653
654
655 class FileDatabase(_File):
656- def __init__(self, pakfire, db, row_id):
657+ def __init__(self, pakfire, db, row_id, row=None):
658 _File.__init__(self, pakfire)
659
660 self.db = db
661 self.row_id = row_id
662-
663- self.__row = None
664+ self.__row = row
665
666 @property
667 def row(self):
668@@ -91,13 +90,7 @@ class FileDatabase(_File):
669 c = self.db.cursor()
670 c.execute("SELECT * FROM files WHERE id = ? LIMIT 1", (self.row_id,))
671
672- # Check if we got the same row.
673- #assert c.lastrowid == self.row_id
674-
675- for row in c:
676- self.__row = row
677- break
678-
679+ self.__row = c.fetchone()
680 c.close()
681
682 return self.__row
683diff --git a/python/pakfire/packages/installed.py b/python/pakfire/packages/installed.py
684index 5a7763b..33c241d 100644
685--- a/python/pakfire/packages/installed.py
686+++ b/python/pakfire/packages/installed.py
687@@ -39,6 +39,7 @@ class DatabasePackage(Package):
688 self.db = db
689
690 self._data = {}
691+ self._filelist = None
692
693 for key in data.keys():
694 self._data[key] = data[key]
695@@ -169,20 +170,21 @@ class DatabasePackage(Package):
696
697 @property
698 def filename(self):
699- return self.metadata.get("filename") # XXX basename?
700+ return self.metadata.get("filename")
701
702 @property
703 def filelist(self):
704- filelist = []
705+ if self._filelist is None:
706+ self._filelist = []
707
708- c = self.db.cursor()
709- c.execute("SELECT id FROM files WHERE pkg = ?", (self.id,))
710+ c = self.db.cursor()
711+ c.execute("SELECT * FROM files WHERE pkg = ?", (self.id,))
712
713- for id in c:
714- file = pakfire.filelist.FileDatabase(self.pakfire, self.db, id[0])
715- filelist.append(file)
716+ for row in c.fetchall():
717+ file = pakfire.filelist.FileDatabase(self.pakfire, self.db, row["id"], row)
718+ self._filelist.append(file)
719
720- return filelist
721+ return self._filelist
722
723 @property
724 def configfiles(self):
725diff --git a/python/pakfire/repository/database.py b/python/pakfire/repository/database.py
726index 6f8f397..a5e5b85 100644
727--- a/python/pakfire/repository/database.py
728+++ b/python/pakfire/repository/database.py
729@@ -53,6 +53,13 @@ class Database(object):
730 self._db.close()
731 self._db = None
732
733+ @property
734+ def db(self):
735+ if self._db is None:
736+ self.open()
737+
738+ return self._db
739+
740 def create(self):
741 pass
742
743@@ -338,11 +345,11 @@ class DatabaseLocal(Database):
744 #c.execute("SELECT id FROM packages WHERE name = ? AND epoch = ? AND version = ?"
745 # " AND release = ? LIMIT 1", (pkg.name, pkg.epoch, pkg.version, pkg.release,))
746
747- id = None
748- for row in c:
749- id = row["id"]
750- break
751- assert id
752+ row = c.fetchone()
753+ if not row:
754+ return
755+
756+ id = row["id"]
757
758 # First, delete all files from the database and then delete the pkg itself.
759 c.execute("DELETE FROM files WHERE pkg = ?", (id,))
760@@ -364,34 +371,29 @@ class DatabaseLocal(Database):
761
762 @property
763 def packages(self):
764- c = self.cursor()
765+ c = self.db.execute("SELECT * FROM packages ORDER BY name")
766
767- c.execute("SELECT * FROM packages ORDER BY name")
768-
769- for row in c:
770+ for row in c.fetchall():
771 yield packages.DatabasePackage(self.pakfire, self.repo, self, row)
772
773 c.close()
774
775 def get_filelist(self):
776- c = self.cursor()
777- c.execute("SELECT DISTINCT name FROM files")
778-
779- ret = []
780- for row in c:
781- ret.append(row["name"])
782-
783- c.close()
784+ c = self.db.execute("SELECT name FROM files")
785
786- return ret
787+ return [r["name"] for r in c.fetchall()]
788
789 def get_package_from_solv(self, solv_pkg):
790- c = self.cursor()
791- c.execute("SELECT * FROM packages WHERE uuid = ? LIMIT 1", (solv_pkg.uuid,))
792+ assert solv_pkg.uuid
793+
794+ c = self.db.execute("SELECT * FROM packages WHERE uuid = ? LIMIT 1", (solv_pkg.uuid,))
795
796 try:
797- for row in c:
798- return packages.DatabasePackage(self.pakfire, self.repo, self, row)
799+ row = c.fetchone()
800+ if row is None:
801+ return
802+
803+ return packages.DatabasePackage(self.pakfire, self.repo, self, row)
804
805 finally:
806 c.close()
807diff --git a/python/pakfire/repository/index.py b/python/pakfire/repository/index.py
808index fac1c2f..7620b38 100644
809--- a/python/pakfire/repository/index.py
810+++ b/python/pakfire/repository/index.py
811@@ -24,6 +24,7 @@ import os
812 import logging
813 log = logging.getLogger("pakfire")
814
815+import pakfire.packages as packages
816 import pakfire.satsolver as satsolver
817
818 class Index(object):
819@@ -147,8 +148,12 @@ class Index(object):
820 solvable.add_provides(rel)
821
822 def rem_package(self, pkg):
823- # XXX delete the solvable from the index.
824- pass # TODO
825+ """
826+ Delete the solvable from the index.
827+ """
828+ assert isinstance(pkg, packages.SolvPackage)
829+
830+ self.solver_repo.rem_solv(pkg)
831
832 def clear(self):
833 """
834diff --git a/python/pakfire/repository/system.py b/python/pakfire/repository/system.py
835index ce3e979..386f252 100644
836--- a/python/pakfire/repository/system.py
837+++ b/python/pakfire/repository/system.py
838@@ -19,9 +19,17 @@
839 # #
840 ###############################################################################
841
842+import os
843+
844 import base
845 import database
846
847+import pakfire.packages as packages
848+import pakfire.util as util
849+
850+from pakfire.constants import *
851+from pakfire.i18n import _
852+
853 class RepositorySystem(base.RepositoryFactory):
854 def __init__(self, pakfire):
855 base.RepositoryFactory.__init__(self, pakfire, "@system", "Local repository")
856@@ -33,6 +41,10 @@ class RepositorySystem(base.RepositoryFactory):
857 self.pool.set_installed(self.solver_repo)
858
859 @property
860+ def cache_file(self):
861+ return os.path.join(self.pakfire.path, PACKAGES_SOLV)
862+
863+ @property
864 def priority(self):
865 """
866 The local repository has always a high priority.
867@@ -40,14 +52,35 @@ class RepositorySystem(base.RepositoryFactory):
868 return 10
869
870 def update(self, force=False, offline=False):
871- if not force:
872- force = len(self) == 0
873+ # XXX using the cache is currently disabled
874+ #if not force:
875+ # if os.path.exists(self.cache_file):
876+ # self.index.read(self.cache_file)
877+ #
878+ # force = len(self) == 0
879+
880+ force = True
881
882 if force:
883+ # Create a progressbar.
884+ pb = util.make_progress(_("Loading installed packages"), len(self.db))
885+
886+ # Remove all data from the current index.
887 self.index.clear()
888+
889+ i = 0
890 for pkg in self.db.packages:
891+ if pb:
892+ i += 1
893+ pb.update(i)
894+
895 self.index.add_package(pkg)
896
897+ self.index.optimize()
898+
899+ if pb:
900+ pb.finish()
901+
902 def commit(self):
903 # Commit the database to disk.
904 self.db.commit()
905@@ -55,20 +88,23 @@ class RepositorySystem(base.RepositoryFactory):
906 # Make sure that all data in the index is accessable.
907 self.index.optimize()
908
909+ # Write the content of the index to a file
910+ # for fast parsing.
911+ # XXX this is currently disabled
912+ #self.index.write(self.cache_file)
913+
914 def add_package(self, pkg):
915 # Add package to the database.
916 self.db.add_package(pkg)
917 self.index.add_package(pkg)
918
919 def rem_package(self, pkg):
920+ assert isinstance(pkg, packages.SolvPackage), pkg
921+
922 # Remove package from the database.
923 self.db.rem_package(pkg)
924 self.index.rem_package(pkg)
925
926 @property
927 def filelist(self):
928- # XXX ugly?
929-
930- for pkg in self.db.packages:
931- for file in pkg.filelist:
932- yield file
933+ return self.db.get_filelist()
934diff --git a/python/pakfire/satsolver.py b/python/pakfire/satsolver.py
935index c3629ce..48c6d0d 100644
936--- a/python/pakfire/satsolver.py
937+++ b/python/pakfire/satsolver.py
938@@ -111,6 +111,13 @@ class Request(_pakfire.Request):
939
940
941 class Solver(object):
942+ option2flag = {
943+ "allow_archchange" : SOLVER_FLAG_ALLOW_ARCHCHANGE,
944+ "allow_downgrade" : SOLVER_FLAG_ALLOW_DOWNGRADE,
945+ "allow_uninstall" : SOLVER_FLAG_ALLOW_UNINSTALL,
946+ "allow_vendorchange" : SOLVER_FLAG_ALLOW_VENDORCHANGE,
947+ }
948+
949 def __init__(self, pakfire, request, logger=None):
950 if logger is None:
951 logger = logging.getLogger("pakfire")
952@@ -119,27 +126,6 @@ class Solver(object):
953 self.pakfire = pakfire
954 self.pool = self.pakfire.pool
955
956- # Default settings.
957- self.settings = {
958- # Update all installed packages?
959- "update" : False,
960-
961- # Allow to uninstall any packages?
962- "uninstall" : False,
963-
964- # Allow to downgrade any packages?
965- "allow_downgrade" : False,
966-
967- # Allow packages to change their vendors?
968- "allow_vendorchange" : False,
969-
970- # Allow packages to change their arch?
971- "allow_archchange" : False,
972-
973- # Fix system?
974- "fix_system" : False,
975- }
976-
977 self.request = request
978 assert self.request, "Empty request?"
979
980@@ -159,40 +145,23 @@ class Solver(object):
981 self.__problems = None
982 self.__transaction = None
983
984- def set(self, key, value):
985- assert self.settings.has_key(key), "Unknown configuration setting: %s" % key
986- assert value in (True, False), "Invalid value: %s" % value
987-
988+ def set(self, option, value):
989 try:
990- self.settings[key] = value
991+ flag = self.option2flag[option]
992 except KeyError:
993- pass
994+ raise Exception, "Unknown configuration setting: %s" % option
995+ self.solver.set_flag(flag, value)
996
997- def get(self, key):
998- assert self.settings.has_key(key), "Unknown configuration setting: %s" % key
999-
1000- return self.settings.get(key)
1001+ def get(self, option):
1002+ try:
1003+ flag = self.option2flag[option]
1004+ except KeyError:
1005+ raise Exception, "Unknown configuration setting: %s" % option
1006+ return self.solver.get_flag(flag)
1007
1008 def solve(self):
1009 assert self.status is None, "Solver did already solve something."
1010
1011- # Apply solver configuration.
1012- self.solver.set_fix_system(self.get("fix_system"))
1013- self.solver.set_allow_uninstall(self.get("uninstall"))
1014- self.solver.set_allow_downgrade(self.get("allow_downgrade"))
1015-
1016- # Optionally allow packages to change their vendors.
1017- # This is not recommended because it may have weird effects.
1018- self.solver.set_allow_vendorchange(self.get("allow_vendorchange"))
1019-
1020- # Optionally allow packages ot change their architecture.
1021- self.solver.set_allow_archchange(self.get("allow_archchange"))
1022-
1023- # Configure the solver for an update.
1024- if self.get("update"):
1025- self.solver.set_updatesystem(True)
1026- self.solver.set_do_split_provides(True)
1027-
1028 # Actually solve the request.
1029 start_time = time.time()
1030 self.status = self.solver.solve(self.request)
1031diff --git a/python/pakfire/transaction.py b/python/pakfire/transaction.py
1032index 58b52c6..10a1277 100644
1033--- a/python/pakfire/transaction.py
1034+++ b/python/pakfire/transaction.py
1035@@ -59,15 +59,16 @@ class TransactionCheck(object):
1036
1037 @property
1038 def error_files(self):
1039- ret = {}
1040+ ret = []
1041
1042- for name, files in self.filelist.items():
1043- if len(files) <= 1:
1044- continue
1045+ for name, count in self.filelist.items():
1046+ if count > 1:
1047+ ret.append(name)
1048
1049- ret[name] = files
1050+ return sorted(ret)
1051
1052- return ret
1053+ def provides_file(self, name):
1054+ return [] # XXX TODO
1055
1056 @property
1057 def successful(self):
1058@@ -85,18 +86,16 @@ class TransactionCheck(object):
1059 if logger is None:
1060 logger = logging.getLogger("pakfire")
1061
1062- for name, files in sorted(self.error_files.items()):
1063- assert len(files) >= 2
1064-
1065- pkgs = [f.pkg.friendly_name for f in files]
1066+ for file in self.error_files:
1067+ pkgs = self.provides_file(file)
1068
1069- if len(files) == 2:
1070+ if len(pkgs) == 2:
1071 logger.critical(
1072 _("file %(name)s from %(pkg1)s conflicts with file from package %(pkg2)s") % \
1073 { "name" : name, "pkg1" : pkgs[0], "pkg2" : pkgs[1] }
1074 )
1075
1076- elif len(files) >= 3:
1077+ elif len(pkgs) >= 3:
1078 logger.critical(
1079 _("file %(name)s from %(pkg)s conflicts with files from %(pkgs)s") % \
1080 { "name" : name, "pkg" : pkgs[0], "pkgs" : i18n.list(pkgs[1:])}
1081@@ -113,7 +112,7 @@ class TransactionCheck(object):
1082 filelist = {}
1083
1084 for file in self.pakfire.repos.local.filelist:
1085- filelist[file.name] = [file,]
1086+ filelist[file] = 1
1087
1088 return filelist
1089
1090@@ -122,11 +121,10 @@ class TransactionCheck(object):
1091 if file.is_dir():
1092 continue
1093
1094- if self.filelist.has_key(file.name):
1095- self.filelist[file.name].append(file)
1096-
1097- else:
1098- self.filelist[file.name] = [file,]
1099+ try:
1100+ self.filelist[file.name] += 1
1101+ except KeyError:
1102+ self.filelist[file.name] = 1
1103
1104 # Add all filesize data to mountpoints.
1105 self.mountpoints.add_pkg(pkg)
1106@@ -136,14 +134,10 @@ class TransactionCheck(object):
1107 if file.is_dir():
1108 continue
1109
1110- if not self.filelist.has_key(file.name):
1111- continue
1112-
1113- for f in self.filelist[file.name]:
1114- if not f.pkg == pkg:
1115- continue
1116-
1117- self.filelist[file.name].remove(f)
1118+ try:
1119+ self.filelist[file.name] -= 1
1120+ except KeyError:
1121+ pass
1122
1123 # Remove all filesize data from mountpoints.
1124 self.mountpoints.rem_pkg(pkg)
1125@@ -562,8 +556,11 @@ class Transaction(object):
1126 for action in self.actions:
1127 try:
1128 action.run()
1129+
1130 except ActionError, e:
1131 logger.error("Action finished with an error: %s - %s" % (action, e))
1132+ #except Exception, e:
1133+ # logger.error(_("An unforeseen error occoured: %s") % e)
1134
1135 logger.info("")
1136
1137diff --git a/python/src/_pakfiremodule.c b/python/src/_pakfiremodule.c
1138index d4ea688..8e80468 100644
1139--- a/python/src/_pakfiremodule.c
1140+++ b/python/src/_pakfiremodule.c
1141@@ -80,6 +80,9 @@ static PyMethodDef Request_methods[] = {
1142 {"noobsoletes_solvable", (PyCFunction)Request_noobsoletes_solvable, METH_VARARGS, NULL},
1143 {"noobsoletes_relation", (PyCFunction)Request_noobsoletes_relation, METH_VARARGS, NULL},
1144 {"noobsoletes_name", (PyCFunction)Request_noobsoletes_name, METH_VARARGS, NULL},
1145+ {"updateall", (PyCFunction)Request_updateall, METH_NOARGS, NULL},
1146+ {"distupgrade", (PyCFunction)Request_distupgrade, METH_NOARGS, NULL},
1147+ {"verify", (PyCFunction)Request_verify, METH_NOARGS, NULL},
1148 { NULL, NULL, 0, NULL }
1149 };
1150
1151@@ -99,6 +102,7 @@ static PyMethodDef Repo_methods[] = {
1152 {"internalize", (PyCFunction)Repo_internalize, METH_NOARGS, NULL},
1153 {"clear", (PyCFunction)Repo_clear, METH_NOARGS, NULL},
1154 {"get_all", (PyCFunction)Repo_get_all, METH_NOARGS, NULL},
1155+ {"rem_solv", (PyCFunction)Repo_rem_solv, METH_VARARGS, NULL},
1156 { NULL, NULL, 0, NULL }
1157 };
1158
1159@@ -152,10 +156,8 @@ static PyMethodDef Solution_methods[] = {
1160
1161 static PyMethodDef Solver_methods[] = {
1162 {"solve", (PyCFunction)Solver_solve, METH_VARARGS, NULL},
1163- {"get_fix_system", (PyCFunction)Solver_get_fix_system, METH_NOARGS, NULL},
1164- {"set_fix_system", (PyCFunction)Solver_set_fix_system, METH_VARARGS, NULL},
1165- {"get_allow_downgrade", (PyCFunction)Solver_get_allow_downgrade, METH_NOARGS, NULL},
1166- {"set_allow_downgrade", (PyCFunction)Solver_set_allow_downgrade, METH_VARARGS, NULL},
1167+ {"get_flag", (PyCFunction)Solver_get_flag, METH_VARARGS, NULL},
1168+ {"set_flag", (PyCFunction)Solver_set_flag, METH_VARARGS, NULL},
1169 {"get_allow_archchange", (PyCFunction)Solver_get_allow_archchange, METH_NOARGS, NULL},
1170 {"set_allow_archchange", (PyCFunction)Solver_set_allow_archchange, METH_VARARGS, NULL},
1171 {"get_allow_vendorchange", (PyCFunction)Solver_get_allow_vendorchange, METH_NOARGS, NULL},
1172@@ -307,4 +309,12 @@ void init_pakfire(void) {
1173 PyDict_SetItemString(d, "SOLVER_RULE_FEATURE", Py_BuildValue("i", SOLVER_RULE_FEATURE));
1174 PyDict_SetItemString(d, "SOLVER_RULE_LEARNT", Py_BuildValue("i", SOLVER_RULE_LEARNT));
1175 PyDict_SetItemString(d, "SOLVER_RULE_CHOICE", Py_BuildValue("i", SOLVER_RULE_CHOICE));
1176+
1177+ /* Solver flags */
1178+ PyDict_SetItemString(d, "SOLVER_FLAG_ALLOW_DOWNGRADE", Py_BuildValue("i", SOLVER_FLAG_ALLOW_DOWNGRADE));
1179+ PyDict_SetItemString(d, "SOLVER_FLAG_ALLOW_ARCHCHANGE", Py_BuildValue("i", SOLVER_FLAG_ALLOW_ARCHCHANGE));
1180+ PyDict_SetItemString(d, "SOLVER_FLAG_ALLOW_VENDORCHANGE", Py_BuildValue("i", SOLVER_FLAG_ALLOW_VENDORCHANGE));
1181+ PyDict_SetItemString(d, "SOLVER_FLAG_ALLOW_UNINSTALL", Py_BuildValue("i", SOLVER_FLAG_ALLOW_UNINSTALL));
1182+ PyDict_SetItemString(d, "SOLVER_FLAG_NO_UPDATEPROVIDE", Py_BuildValue("i", SOLVER_FLAG_NO_UPDATEPROVIDE));
1183+ PyDict_SetItemString(d, "SOLVER_FLAG_SPLITPROVIDES", Py_BuildValue("i", SOLVER_FLAG_SPLITPROVIDES));
1184 }
1185diff --git a/python/src/repo.c b/python/src/repo.c
1186index 6621c3b..4bc112a 100644
1187--- a/python/src/repo.c
1188+++ b/python/src/repo.c
1189@@ -47,7 +47,6 @@ PyObject* Repo_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1190 const char *name;
1191
1192 if (!PyArg_ParseTuple(args, "Os", &pool, &name)) {
1193- /* XXX raise exception */
1194 return NULL;
1195 }
1196
1197@@ -67,7 +66,6 @@ PyObject* Repo_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1198 }
1199
1200 PyObject *Repo_dealloc(RepoObject *self) {
1201- // repo_free(self->_repo, 0);
1202 self->ob_type->tp_free((PyObject *)self);
1203
1204 Py_RETURN_NONE;
1205@@ -97,7 +95,6 @@ PyObject *Repo_set_enabled(RepoObject *self, PyObject *args) {
1206 bool enabled;
1207
1208 if (!PyArg_ParseTuple(args, "b", &enabled)) {
1209- /* XXX raise exception */
1210 return NULL;
1211 }
1212
1213@@ -132,13 +129,12 @@ PyObject *Repo_write(RepoObject *self, PyObject *args) {
1214 char exception[STRING_SIZE];
1215
1216 if (!PyArg_ParseTuple(args, "s", &filename)) {
1217- /* XXX raise exception */
1218+ return NULL;
1219 }
1220
1221 // Prepare the pool and internalize all attributes.
1222- _Pool_prepare(self->_repo->pool);
1223+ //_Pool_prepare(self->_repo->pool);
1224
1225- // XXX catch if file cannot be opened
1226 FILE *fp = NULL;
1227 if ((fp = fopen(filename, "wb")) == NULL) {
1228 snprintf(exception, STRING_SIZE - 1, "Could not open file for writing: %s (%s).",
1229@@ -147,8 +143,7 @@ PyObject *Repo_write(RepoObject *self, PyObject *args) {
1230 return NULL;
1231 }
1232
1233- repo_write(self->_repo, fp, NULL, NULL, 0);
1234-
1235+ repo_write(self->_repo, fp);
1236 fclose(fp);
1237
1238 Py_RETURN_NONE;
1239@@ -158,14 +153,12 @@ PyObject *Repo_read(RepoObject *self, PyObject *args) {
1240 const char *filename;
1241
1242 if (!PyArg_ParseTuple(args, "s", &filename)) {
1243- /* XXX raise exception */
1244+ return NULL;
1245 }
1246
1247 // XXX catch if file cannot be opened
1248 FILE *fp = fopen(filename, "rb");
1249-
1250- repo_add_solv(self->_repo, fp);
1251-
1252+ repo_add_solv(self->_repo, fp, 0);
1253 fclose(fp);
1254
1255 Py_RETURN_NONE;
1256@@ -209,3 +202,17 @@ PyObject *Repo_get_all(RepoObject *self) {
1257
1258 return list;
1259 }
1260+
1261+PyObject *Repo_rem_solv(RepoObject *self, PyObject *args) {
1262+ Repo *repo = self->_repo;
1263+ SolvableObject *solv;
1264+
1265+ if (!PyArg_ParseTuple(args, "O", &solv)) {
1266+ return NULL;
1267+ }
1268+
1269+ Solvable *s = pool_id2solvable(repo->pool, solv->_id);
1270+ repo_free_solvable(repo, s - repo->pool->solvables, 1);
1271+
1272+ Py_RETURN_NONE;
1273+}
1274diff --git a/python/src/repo.h b/python/src/repo.h
1275index 9de636f..3ef96df 100644
1276--- a/python/src/repo.h
1277+++ b/python/src/repo.h
1278@@ -44,6 +44,7 @@ extern PyObject *Repo_read(RepoObject *self, PyObject *args);
1279 extern PyObject *Repo_internalize(RepoObject *self);
1280 extern PyObject *Repo_clear(RepoObject *self);
1281 extern PyObject *Repo_get_all(RepoObject *self);
1282+extern PyObject *Repo_rem_solv(RepoObject *self, PyObject *args);
1283
1284 extern PyTypeObject RepoType;
1285
1286diff --git a/python/src/request.c b/python/src/request.c
1287index 168b455..7d7c5b2 100644
1288--- a/python/src/request.c
1289+++ b/python/src/request.c
1290@@ -64,29 +64,25 @@ PyObject *Request_dealloc(RequestObject *self) {
1291 }
1292
1293 void _Request_solvable(RequestObject *self, Id what, Id solvable) {
1294- queue_push(&self->_queue, what|SOLVER_SOLVABLE);
1295- queue_push(&self->_queue, solvable);
1296+ queue_push2(&self->_queue, what|SOLVER_SOLVABLE, solvable);
1297 }
1298
1299 void _Request_relation(RequestObject *self, Id what, Id relation) {
1300- queue_push(&self->_queue, what|SOLVER_SOLVABLE_PROVIDES);
1301- queue_push(&self->_queue, relation);
1302+ queue_push2(&self->_queue, what|SOLVER_SOLVABLE_PROVIDES, relation);
1303 }
1304
1305 void _Request_name(RequestObject *self, Id what, Id provides) {
1306- queue_push(&self->_queue, what|SOLVER_SOLVABLE_NAME);
1307- queue_push(&self->_queue, provides);
1308+ queue_push2(&self->_queue, what|SOLVER_SOLVABLE_NAME, provides);
1309 }
1310
1311 PyObject *Request_install_solvable(RequestObject *self, PyObject *args) {
1312 SolvableObject *solv;
1313
1314 if (!PyArg_ParseTuple(args, "O", &solv)) {
1315- /* XXX raise exception */
1316+ return NULL;
1317 }
1318
1319 _Request_solvable(self, SOLVER_INSTALL, solv->_id);
1320-
1321 Py_RETURN_NONE;
1322 }
1323
1324@@ -94,11 +90,10 @@ PyObject *Request_install_relation(RequestObject *self, PyObject *args) {
1325 RelationObject *rel;
1326
1327 if (!PyArg_ParseTuple(args, "O", &rel)) {
1328- /* XXX raise exception */
1329+ return NULL;
1330 }
1331
1332 _Request_relation(self, SOLVER_INSTALL, rel->_id);
1333-
1334 Py_RETURN_NONE;
1335 }
1336
1337@@ -106,7 +101,7 @@ PyObject *Request_install_name(RequestObject *self, PyObject *args) {
1338 const char *name;
1339
1340 if (!PyArg_ParseTuple(args, "s", &name)) {
1341- /* XXX raise exception */
1342+ return NULL;
1343 }
1344
1345 Id _name = pool_str2id(self->_pool, name, 1);
1346@@ -119,11 +114,10 @@ PyObject *Request_remove_solvable(RequestObject *self, PyObject *args) {
1347 SolvableObject *solv;
1348
1349 if (!PyArg_ParseTuple(args, "O", &solv)) {
1350- /* XXX raise exception */
1351+ return NULL;
1352 }
1353
1354 _Request_solvable(self, SOLVER_ERASE, solv->_id);
1355-
1356 Py_RETURN_NONE;
1357 }
1358
1359@@ -131,11 +125,10 @@ PyObject *Request_remove_relation(RequestObject *self, PyObject *args) {
1360 RelationObject *rel;
1361
1362 if (!PyArg_ParseTuple(args, "O", &rel)) {
1363- /* XXX raise exception */
1364+ return NULL;
1365 }
1366
1367 _Request_relation(self, SOLVER_ERASE, rel->_id);
1368-
1369 Py_RETURN_NONE;
1370 }
1371
1372@@ -143,7 +136,7 @@ PyObject *Request_remove_name(RequestObject *self, PyObject *args) {
1373 const char *name;
1374
1375 if (!PyArg_ParseTuple(args, "s", &name)) {
1376- /* XXX raise exception */
1377+ return NULL;
1378 }
1379
1380 Id _name = pool_str2id(self->_pool, name, 1);
1381@@ -156,11 +149,10 @@ PyObject *Request_update_solvable(RequestObject *self, PyObject *args) {
1382 SolvableObject *solv;
1383
1384 if (!PyArg_ParseTuple(args, "O", &solv)) {
1385- /* XXX raise exception */
1386+ return NULL;
1387 }
1388
1389 _Request_solvable(self, SOLVER_UPDATE, solv->_id);
1390-
1391 Py_RETURN_NONE;
1392 }
1393
1394@@ -168,11 +160,10 @@ PyObject *Request_update_relation(RequestObject *self, PyObject *args) {
1395 RelationObject *rel;
1396
1397 if (!PyArg_ParseTuple(args, "O", &rel)) {
1398- /* XXX raise exception */
1399+ return NULL;
1400 }
1401
1402 _Request_relation(self, SOLVER_UPDATE, rel->_id);
1403-
1404 Py_RETURN_NONE;
1405 }
1406
1407@@ -180,7 +171,7 @@ PyObject *Request_update_name(RequestObject *self, PyObject *args) {
1408 const char *name;
1409
1410 if (!PyArg_ParseTuple(args, "s", &name)) {
1411- /* XXX raise exception */
1412+ return NULL;
1413 }
1414
1415 Id _name = pool_str2id(self->_pool, name, 1);
1416@@ -193,11 +184,10 @@ PyObject *Request_lock_solvable(RequestObject *self, PyObject *args) {
1417 SolvableObject *solv;
1418
1419 if (!PyArg_ParseTuple(args, "O", &solv)) {
1420- /* XXX raise exception */
1421+ return NULL;
1422 }
1423
1424 _Request_solvable(self, SOLVER_LOCK, solv->_id);
1425-
1426 Py_RETURN_NONE;
1427 }
1428
1429@@ -205,11 +195,10 @@ PyObject *Request_lock_relation(RequestObject *self, PyObject *args) {
1430 RelationObject *rel;
1431
1432 if (!PyArg_ParseTuple(args, "O", &rel)) {
1433- /* XXX raise exception */
1434+ return NULL;
1435 }
1436
1437 _Request_relation(self, SOLVER_LOCK, rel->_id);
1438-
1439 Py_RETURN_NONE;
1440 }
1441
1442@@ -217,7 +206,7 @@ PyObject *Request_lock_name(RequestObject *self, PyObject *args) {
1443 const char *name;
1444
1445 if (!PyArg_ParseTuple(args, "s", &name)) {
1446- /* XXX raise exception */
1447+ return NULL;
1448 }
1449
1450 Id _name = pool_str2id(self->_pool, name, 1);
1451@@ -230,11 +219,10 @@ PyObject *Request_noobsoletes_solvable(RequestObject *self, PyObject *args) {
1452 SolvableObject *solv;
1453
1454 if (!PyArg_ParseTuple(args, "O", &solv)) {
1455- /* XXX raise exception */
1456+ return NULL;
1457 }
1458
1459 _Request_solvable(self, SOLVER_NOOBSOLETES, solv->_id);
1460-
1461 Py_RETURN_NONE;
1462 }
1463
1464@@ -242,11 +230,10 @@ PyObject *Request_noobsoletes_relation(RequestObject *self, PyObject *args) {
1465 RelationObject *rel;
1466
1467 if (!PyArg_ParseTuple(args, "O", &rel)) {
1468- /* XXX raise exception */
1469+ return NULL;
1470 }
1471
1472 _Request_relation(self, SOLVER_NOOBSOLETES, rel->_id);
1473-
1474 Py_RETURN_NONE;
1475 }
1476
1477@@ -254,7 +241,7 @@ PyObject *Request_noobsoletes_name(RequestObject *self, PyObject *args) {
1478 const char *name;
1479
1480 if (!PyArg_ParseTuple(args, "s", &name)) {
1481- /* XXX raise exception */
1482+ return NULL;
1483 }
1484
1485 Id _name = pool_str2id(self->_pool, name, 1);
1486@@ -262,3 +249,18 @@ PyObject *Request_noobsoletes_name(RequestObject *self, PyObject *args) {
1487
1488 Py_RETURN_NONE;
1489 }
1490+
1491+PyObject *Request_updateall(RequestObject *self, PyObject *args) {
1492+ queue_push2(&self->_queue, SOLVER_UPDATE|SOLVER_SOLVABLE_ALL, 0);
1493+ Py_RETURN_NONE;
1494+}
1495+
1496+PyObject *Request_distupgrade(RequestObject *self, PyObject *args) {
1497+ queue_push2(&self->_queue, SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL, 0);
1498+ Py_RETURN_NONE;
1499+}
1500+
1501+PyObject *Request_verify(RequestObject *self, PyObject *args) {
1502+ queue_push2(&self->_queue, SOLVER_VERIFY|SOLVER_SOLVABLE_ALL, 0);
1503+ Py_RETURN_NONE;
1504+}
1505diff --git a/python/src/request.h b/python/src/request.h
1506index b936801..aa79274 100644
1507--- a/python/src/request.h
1508+++ b/python/src/request.h
1509@@ -59,6 +59,10 @@ extern PyObject *Request_noobsoletes_solvable(RequestObject *self, PyObject *arg
1510 extern PyObject *Request_noobsoletes_relation(RequestObject *self, PyObject *args);
1511 extern PyObject *Request_noobsoletes_name(RequestObject *self, PyObject *args);
1512
1513+extern PyObject *Request_updateall(RequestObject *self, PyObject *args);
1514+extern PyObject *Request_distupgrade(RequestObject *self, PyObject *args);
1515+extern PyObject *Request_verify(RequestObject *self, PyObject *args);
1516+
1517 extern PyTypeObject RequestType;
1518
1519 #endif
1520diff --git a/python/src/solution.c b/python/src/solution.c
1521index b52a1b5..7360a37 100644
1522--- a/python/src/solution.c
1523+++ b/python/src/solution.c
1524@@ -82,7 +82,7 @@ PyObject *Solution_string(SolutionObject *self) {
1525
1526 switch (how & SOLVER_JOBMASK) {
1527 case SOLVER_INSTALL:
1528- if (select == SOLVER_SOLVABLE && solver->installed && pool->solvables[what].repo == solver->installed)
1529+ if (select == SOLVER_SOLVABLE && pool->installed && pool->solvables[what].repo == pool->installed)
1530 snprintf(str, STRING_SIZE - 1, _("do not keep %s installed"),
1531 pool_solvid2str(pool, what));
1532 else if (select == SOLVER_SOLVABLE_PROVIDES)
1533@@ -94,7 +94,7 @@ PyObject *Solution_string(SolutionObject *self) {
1534 break;
1535
1536 case SOLVER_ERASE:
1537- if (select == SOLVER_SOLVABLE && !(solver->installed && pool->solvables[what].repo == solver->installed))
1538+ if (select == SOLVER_SOLVABLE && !(pool->installed && pool->solvables[what].repo == pool->installed))
1539 snprintf(str, STRING_SIZE - 1, _("do not forbid installation of %s"),
1540 pool_solvid2str(pool, what));
1541 else if (select == SOLVER_SOLVABLE_PROVIDES)
1542@@ -122,7 +122,7 @@ PyObject *Solution_string(SolutionObject *self) {
1543
1544 } else if (p == SOLVER_SOLUTION_INFARCH) {
1545 s = pool->solvables + rp;
1546- if (solver->installed && s->repo == solver->installed)
1547+ if (pool->installed && s->repo == pool->installed)
1548 snprintf(str, STRING_SIZE - 1, _("keep %s despite the inferior architecture"),
1549 pool_solvable2str(pool, s));
1550 else
1551@@ -131,7 +131,7 @@ PyObject *Solution_string(SolutionObject *self) {
1552
1553 } else if (p == SOLVER_SOLUTION_DISTUPGRADE) {
1554 s = pool->solvables + rp;
1555- if (solver->installed && s->repo == solver->installed)
1556+ if (pool->installed && s->repo == pool->installed)
1557 snprintf(str, STRING_SIZE - 1, _("keep obsolete %s"),
1558 pool_solvable2str(pool, s));
1559 else
1560diff --git a/python/src/solver.c b/python/src/solver.c
1561index 5079510..54e1294 100644
1562--- a/python/src/solver.c
1563+++ b/python/src/solver.c
1564@@ -53,6 +53,9 @@ PyObject* Solver_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1565 }
1566 }
1567
1568+ /* enable splitprovides by default */
1569+ solver_set_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES, 1);
1570+
1571 return (PyObject *)self;
1572 }
1573
1574@@ -63,138 +66,150 @@ PyObject *Solver_dealloc(SolverObject *self) {
1575 Py_RETURN_NONE;
1576 }
1577
1578-PyObject *Solver_get_fix_system(SolverObject *self, PyObject *args) {
1579- return Py_BuildValue("i", self->_solver->fixsystem);
1580+PyObject *Solver_get_flag(SolverObject *self, PyObject *args) {
1581+ int flag = 0;
1582+
1583+ if (!PyArg_ParseTuple(args, "i", &flag)) {
1584+ return NULL;
1585+ }
1586+
1587+ int val = solver_get_flag(self->_solver, flag);
1588+ return Py_BuildValue("i", val);
1589 }
1590
1591-PyObject *Solver_set_fix_system(SolverObject *self, PyObject *args) {
1592- int val;
1593+PyObject *Solver_set_flag(SolverObject *self, PyObject *args) {
1594+ int flag = 0, val = 0;
1595
1596- if (!PyArg_ParseTuple(args, "i", &val)) {
1597- /* XXX raise exception */
1598+ if (!PyArg_ParseTuple(args, "ii", &flag, &val)) {
1599+ return NULL;
1600 }
1601
1602- self->_solver->fixsystem = val;
1603-
1604+ solver_set_flag(self->_solver, flag, val);
1605 Py_RETURN_NONE;
1606 }
1607
1608 PyObject *Solver_get_allow_downgrade(SolverObject *self, PyObject *args) {
1609- return Py_BuildValue("i", self->_solver->allowdowngrade);
1610+ int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_DOWNGRADE);
1611+
1612+ return Py_BuildValue("i", val);
1613 }
1614
1615 PyObject *Solver_set_allow_downgrade(SolverObject *self, PyObject *args) {
1616 int val;
1617
1618 if (!PyArg_ParseTuple(args, "i", &val)) {
1619- /* XXX raise exception */
1620+ return NULL;
1621 }
1622
1623- self->_solver->allowdowngrade = val;
1624-
1625+ solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_DOWNGRADE, val);
1626 Py_RETURN_NONE;
1627 }
1628
1629 PyObject *Solver_get_allow_archchange(SolverObject *self, PyObject *args) {
1630- return Py_BuildValue("i", self->_solver->allowarchchange);
1631+ int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_ARCHCHANGE);
1632+
1633+ return Py_BuildValue("i", val);
1634 }
1635
1636 PyObject *Solver_set_allow_archchange(SolverObject *self, PyObject *args) {
1637 int val;
1638
1639 if (!PyArg_ParseTuple(args, "i", &val)) {
1640- /* XXX raise exception */
1641+ return NULL;
1642 }
1643
1644- self->_solver->allowarchchange = val;
1645-
1646+ solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_ARCHCHANGE, val);
1647 Py_RETURN_NONE;
1648 }
1649
1650 PyObject *Solver_get_allow_vendorchange(SolverObject *self, PyObject *args) {
1651- return Py_BuildValue("i", self->_solver->allowvendorchange);
1652+ int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_VENDORCHANGE);
1653+
1654+ return Py_BuildValue("i", val);
1655 }
1656
1657 PyObject *Solver_set_allow_vendorchange(SolverObject *self, PyObject *args) {
1658 int val;
1659
1660 if (!PyArg_ParseTuple(args, "i", &val)) {
1661- /* XXX raise exception */
1662+ return NULL;
1663 }
1664
1665- self->_solver->allowvendorchange = val;
1666-
1667+ solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_VENDORCHANGE, val);
1668 Py_RETURN_NONE;
1669 }
1670
1671 PyObject *Solver_get_allow_uninstall(SolverObject *self, PyObject *args) {
1672- return Py_BuildValue("i", self->_solver->allowuninstall);
1673+ int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_UNINSTALL);
1674+
1675+ return Py_BuildValue("i", val);
1676 }
1677
1678 PyObject *Solver_set_allow_uninstall(SolverObject *self, PyObject *args) {
1679 int val;
1680
1681 if (!PyArg_ParseTuple(args, "i", &val)) {
1682- /* XXX raise exception */
1683+ return NULL;
1684 }
1685
1686- self->_solver->allowuninstall = val;
1687-
1688+ solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_UNINSTALL, val);
1689 Py_RETURN_NONE;
1690 }
1691
1692 PyObject *Solver_get_updatesystem(SolverObject *self, PyObject *args) {
1693- return Py_BuildValue("i", self->_solver->updatesystem);
1694+ //return Py_BuildValue("i", self->_solver->updatesystem);
1695+ Py_RETURN_NONE;
1696 }
1697
1698 PyObject *Solver_set_updatesystem(SolverObject *self, PyObject *args) {
1699- int val;
1700+ /*int val;
1701
1702 if (!PyArg_ParseTuple(args, "i", &val)) {
1703- /* XXX raise exception */
1704+ return NULL;
1705 }
1706
1707- self->_solver->updatesystem = val;
1708+ self->_solver->updatesystem = val; */
1709
1710 Py_RETURN_NONE;
1711 }
1712
1713 PyObject *Solver_get_do_split_provides(SolverObject *self, PyObject *args) {
1714- return Py_BuildValue("i", self->_solver->dosplitprovides);
1715+ int val = solver_get_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES);
1716+
1717+ return Py_BuildValue("i", val);
1718 }
1719
1720 PyObject *Solver_set_do_split_provides(SolverObject *self, PyObject *args) {
1721 int val;
1722
1723 if (!PyArg_ParseTuple(args, "i", &val)) {
1724- /* XXX raise exception */
1725+ return NULL;
1726 }
1727
1728- self->_solver->dosplitprovides = val;
1729-
1730+ solver_set_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES, val);
1731 Py_RETURN_NONE;
1732 }
1733
1734 PyObject *Solver_solve(SolverObject *self, PyObject *args) {
1735 RequestObject *request;
1736+ int res = 0;
1737
1738 if (!PyArg_ParseTuple(args, "O", &request)) {
1739- /* XXX raise exception */
1740+ return NULL;
1741 }
1742
1743 // Make sure, the pool is prepared.
1744 _Pool_prepare(self->_solver->pool);
1745
1746- solver_solve(self->_solver, &request->_queue);
1747+ res = solver_solve(self->_solver, &request->_queue);
1748
1749 #ifdef DEBUG
1750 solver_printallsolutions(self->_solver);
1751 #endif
1752
1753- if (self->_solver->problems.count == 0) {
1754+ if (res == 0) {
1755 Py_RETURN_TRUE;
1756 }
1757-
1758 Py_RETURN_FALSE;
1759 }
1760
1761@@ -202,7 +217,6 @@ PyObject *Solver_get_problems(SolverObject *self, PyObject *args) {
1762 RequestObject *request;
1763
1764 if (!PyArg_ParseTuple(args, "O", &request)) {
1765- /* XXX raise exception */
1766 return NULL;
1767 }
1768
1769diff --git a/python/src/solver.h b/python/src/solver.h
1770index 604cb83..8a4478b 100644
1771--- a/python/src/solver.h
1772+++ b/python/src/solver.h
1773@@ -34,8 +34,9 @@ typedef struct {
1774 extern PyObject* Solver_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
1775 extern PyObject *Solver_dealloc(SolverObject *self);
1776
1777-extern PyObject *Solver_get_fix_system(SolverObject *self, PyObject *args);
1778-extern PyObject *Solver_set_fix_system(SolverObject *self, PyObject *args);
1779+extern PyObject *Solver_get_flag(SolverObject *self, PyObject *args);
1780+extern PyObject *Solver_set_flag(SolverObject *self, PyObject *args);
1781+
1782 extern PyObject *Solver_get_allow_downgrade(SolverObject *self, PyObject *args);
1783 extern PyObject *Solver_set_allow_downgrade(SolverObject *self, PyObject *args);
1784 extern PyObject *Solver_get_allow_archchange(SolverObject *self, PyObject *args);
1785--
17861.7.10.4
1787