Package entropy :: Module db

Source Code for Module entropy.db

   1  # -*- coding: utf-8 -*- 
   2  """ 
   3   
   4      @author: Fabio Erculiani <lxnay@sabayonlinux.org> 
   5      @contact: lxnay@sabayonlinux.org 
   6      @copyright: Fabio Erculiani 
   7      @license: GPL-2 
   8   
   9      B{Entropy Framework repository database module}. 
  10      Entropy repositories (server and client) are implemented as relational 
  11      databases. Currently, EntropyRepository class is the object that wraps 
  12      sqlite3 database queries and repository logic: there are no more 
  13      abstractions between the two because there is only one implementation 
  14      available at this time. In future, entropy.db will feature more backends 
  15      such as MySQL embedded, SparQL, remote repositories support via TCP socket, 
  16      etc. This will require a new layer between the repository interface now 
  17      offered by EntropyRepository and the underlying data retrieval logic. 
  18      Every repository interface available inherits from EntropyRepository 
  19      class and has to reimplement its own Schema subclass and its get_init 
  20      method (see EntropyRepository documentation for more information). 
  21   
  22      I{EntropyRepository} is the sqlite3 implementation of the repository 
  23      interface, as written above. 
  24   
  25      I{ServerRepositoryStatus} is a singleton containing the status of 
  26      server-side repositories. It is used to determine if repository has 
  27      been modified (tainted) or has been revision bumped already. 
  28      Revision bumps are automatic and happen on the very first data "commit". 
  29      Every repository features a revision number which is stored into the 
  30      "packages.db.revision" file. Only server-side (or community) repositories 
  31      are subject to this automation (revision file update on commit). 
  32   
  33      @todo: migrate to "_" (underscore) convention 
  34   
  35  """ 
  36   
  37  from __future__ import with_statement 
  38  import os 
  39  import shutil 
  40  from entropy.const import etpConst, etpCache 
  41  from entropy.exceptions import IncorrectParameter, InvalidAtom, \ 
  42      SystemDatabaseError, OperationNotPermitted 
  43  from entropy.i18n import _ 
  44  from entropy.output import brown, bold, red, blue, purple, darkred, darkgreen, \ 
  45      TextInterface 
  46  from entropy.cache import EntropyCacher 
  47  from entropy.core import Singleton, SystemSettings 
  48  from entropy.spm import get_spm 
  49   
  50  try: # try with sqlite3 from >=python 2.5 
  51      from sqlite3 import dbapi2 
  52  except ImportError: # fallback to pysqlite 
  53      try: 
  54          from pysqlite2 import dbapi2 
  55      except ImportError, e: 
  56          raise SystemError( 
  57              "%s. %s: %s" % ( 
  58                  _("Entropy needs Python compiled with sqlite3 support"), 
  59                  _("Error"), 
  60                  e, 
  61              ) 
  62          ) 
  63   
64 -class ServerRepositoryStatus(Singleton):
65 66 """ 67 Server-side Repositories status information container. 68 """ 69
70 - def init_singleton(self):
71 """ Singleton "constructor" """ 72 self.__data = {} 73 self.__updates_log = {}
74
75 - def __create_if_necessary(self, db):
76 if db not in self.__data: 77 self.__data[db] = {} 78 self.__data[db]['tainted'] = False 79 self.__data[db]['bumped'] = False 80 self.__data[db]['unlock_msg'] = False
81
82 - def set_unlock_msg(self, db):
83 """ 84 Set bit which determines if the unlock warning has been already 85 printed to user. 86 87 @param db: database identifier 88 @type db: string 89 """ 90 self.__create_if_necessary(db) 91 self.__data[db]['unlock_msg'] = True
92
93 - def unset_unlock_msg(self, db):
94 """ 95 Unset bit which determines if the unlock warning has been already 96 printed to user. 97 98 @param db: database identifier 99 @type db: string 100 """ 101 self.__create_if_necessary(db) 102 self.__data[db]['unlock_msg'] = False
103
104 - def set_tainted(self, db):
105 """ 106 Set bit which determines if the repository which db points to has been 107 modified. 108 109 @param db: database identifier 110 @type db: string 111 """ 112 self.__create_if_necessary(db) 113 self.__data[db]['tainted'] = True
114
115 - def unset_tainted(self, db):
116 """ 117 Unset bit which determines if the repository which db points to has been 118 modified. 119 120 @param db: database identifier 121 @type db: string 122 """ 123 self.__create_if_necessary(db) 124 self.__data[db]['tainted'] = False
125
126 - def set_bumped(self, db):
127 """ 128 Set bit which determines if the repository which db points to has been 129 revision bumped. 130 131 @param db: database identifier 132 @type db: string 133 """ 134 self.__create_if_necessary(db) 135 self.__data[db]['bumped'] = True
136
137 - def unset_bumped(self, db):
138 """ 139 Unset bit which determines if the repository which db points to has been 140 revision bumped. 141 142 @param db: database identifier 143 @type db: string 144 """ 145 self.__create_if_necessary(db) 146 self.__data[db]['bumped'] = False
147
148 - def is_tainted(self, db):
149 """ 150 Return whether repository which db points to has been modified. 151 152 @param db: database identifier 153 @type db: string 154 """ 155 self.__create_if_necessary(db) 156 return self.__data[db]['tainted']
157
158 - def is_bumped(self, db):
159 """ 160 Return whether repository which db points to has been revision bumped. 161 162 @param db: database identifier 163 @type db: string 164 """ 165 self.__create_if_necessary(db) 166 return self.__data[db]['bumped']
167
168 - def is_unlock_msg(self, db):
169 """ 170 Return whether repository which db points to has outputed the unlock 171 warning message. 172 173 @param db: database identifier 174 @type db: string 175 """ 176 self.__create_if_necessary(db) 177 return self.__data[db]['unlock_msg']
178
179 - def get_updates_log(self, db):
180 """ 181 Return dict() object containing metadata related to package 182 updates occured in a server-side repository. 183 """ 184 if db not in self.__updates_log: 185 self.__updates_log[db] = {} 186 return self.__updates_log[db]
187
188 -class EntropyRepository:
189 190 """ 191 EntropyRepository implements SQLite3 based storage. In a Model-View based 192 pattern, it can be considered the "model". 193 Actually it's the only one available but more model backends will be 194 supported in future (which will inherit this class directly). 195 196 Every Entropy repository storage interface MUST inherit from this base 197 class. 198 199 @todo: refactoring and generalization needed 200 """ 201
202 - class Schema:
203
204 - def get_init(self):
205 return """ 206 CREATE TABLE baseinfo ( 207 idpackage INTEGER PRIMARY KEY AUTOINCREMENT, 208 atom VARCHAR, 209 idcategory INTEGER, 210 name VARCHAR, 211 version VARCHAR, 212 versiontag VARCHAR, 213 revision INTEGER, 214 branch VARCHAR, 215 slot VARCHAR, 216 idlicense INTEGER, 217 etpapi INTEGER, 218 trigger INTEGER 219 ); 220 221 CREATE TABLE extrainfo ( 222 idpackage INTEGER PRIMARY KEY, 223 description VARCHAR, 224 homepage VARCHAR, 225 download VARCHAR, 226 size VARCHAR, 227 idflags INTEGER, 228 digest VARCHAR, 229 datecreation VARCHAR 230 ); 231 232 CREATE TABLE content ( 233 idpackage INTEGER, 234 file VARCHAR, 235 type VARCHAR 236 ); 237 238 CREATE TABLE provide ( 239 idpackage INTEGER, 240 atom VARCHAR 241 ); 242 243 CREATE TABLE dependencies ( 244 idpackage INTEGER, 245 iddependency INTEGER, 246 type INTEGER 247 ); 248 249 CREATE TABLE dependenciesreference ( 250 iddependency INTEGER PRIMARY KEY AUTOINCREMENT, 251 dependency VARCHAR 252 ); 253 254 CREATE TABLE dependstable ( 255 iddependency INTEGER PRIMARY KEY, 256 idpackage INTEGER 257 ); 258 259 CREATE TABLE conflicts ( 260 idpackage INTEGER, 261 conflict VARCHAR 262 ); 263 264 CREATE TABLE mirrorlinks ( 265 mirrorname VARCHAR, 266 mirrorlink VARCHAR 267 ); 268 269 CREATE TABLE sources ( 270 idpackage INTEGER, 271 idsource INTEGER 272 ); 273 274 CREATE TABLE sourcesreference ( 275 idsource INTEGER PRIMARY KEY AUTOINCREMENT, 276 source VARCHAR 277 ); 278 279 CREATE TABLE useflags ( 280 idpackage INTEGER, 281 idflag INTEGER 282 ); 283 284 CREATE TABLE useflagsreference ( 285 idflag INTEGER PRIMARY KEY AUTOINCREMENT, 286 flagname VARCHAR 287 ); 288 289 CREATE TABLE keywords ( 290 idpackage INTEGER, 291 idkeyword INTEGER 292 ); 293 294 CREATE TABLE keywordsreference ( 295 idkeyword INTEGER PRIMARY KEY AUTOINCREMENT, 296 keywordname VARCHAR 297 ); 298 299 CREATE TABLE categories ( 300 idcategory INTEGER PRIMARY KEY AUTOINCREMENT, 301 category VARCHAR 302 ); 303 304 CREATE TABLE licenses ( 305 idlicense INTEGER PRIMARY KEY AUTOINCREMENT, 306 license VARCHAR 307 ); 308 309 CREATE TABLE flags ( 310 idflags INTEGER PRIMARY KEY AUTOINCREMENT, 311 chost VARCHAR, 312 cflags VARCHAR, 313 cxxflags VARCHAR 314 ); 315 316 CREATE TABLE configprotect ( 317 idpackage INTEGER PRIMARY KEY, 318 idprotect INTEGER 319 ); 320 321 CREATE TABLE configprotectmask ( 322 idpackage INTEGER PRIMARY KEY, 323 idprotect INTEGER 324 ); 325 326 CREATE TABLE configprotectreference ( 327 idprotect INTEGER PRIMARY KEY AUTOINCREMENT, 328 protect VARCHAR 329 ); 330 331 CREATE TABLE systempackages ( 332 idpackage INTEGER PRIMARY KEY 333 ); 334 335 CREATE TABLE injected ( 336 idpackage INTEGER PRIMARY KEY 337 ); 338 339 CREATE TABLE installedtable ( 340 idpackage INTEGER PRIMARY KEY, 341 repositoryname VARCHAR, 342 source INTEGER 343 ); 344 345 CREATE TABLE sizes ( 346 idpackage INTEGER PRIMARY KEY, 347 size INTEGER 348 ); 349 350 CREATE TABLE messages ( 351 idpackage INTEGER, 352 message VARCHAR 353 ); 354 355 CREATE TABLE counters ( 356 counter INTEGER, 357 idpackage INTEGER, 358 branch VARCHAR, 359 PRIMARY KEY(idpackage,branch) 360 ); 361 362 CREATE TABLE trashedcounters ( 363 counter INTEGER 364 ); 365 366 CREATE TABLE eclasses ( 367 idpackage INTEGER, 368 idclass INTEGER 369 ); 370 371 CREATE TABLE eclassesreference ( 372 idclass INTEGER PRIMARY KEY AUTOINCREMENT, 373 classname VARCHAR 374 ); 375 376 CREATE TABLE needed ( 377 idpackage INTEGER, 378 idneeded INTEGER, 379 elfclass INTEGER 380 ); 381 382 CREATE TABLE neededreference ( 383 idneeded INTEGER PRIMARY KEY AUTOINCREMENT, 384 library VARCHAR 385 ); 386 387 CREATE TABLE neededlibrarypaths ( 388 library VARCHAR, 389 path VARCHAR, 390 elfclass INTEGER, 391 PRIMARY KEY(library, path, elfclass) 392 ); 393 394 CREATE TABLE neededlibraryidpackages ( 395 idpackage INTEGER, 396 library VARCHAR, 397 elfclass INTEGER 398 ); 399 400 CREATE TABLE treeupdates ( 401 repository VARCHAR PRIMARY KEY, 402 digest VARCHAR 403 ); 404 405 CREATE TABLE treeupdatesactions ( 406 idupdate INTEGER PRIMARY KEY AUTOINCREMENT, 407 repository VARCHAR, 408 command VARCHAR, 409 branch VARCHAR, 410 date VARCHAR 411 ); 412 413 CREATE TABLE licensedata ( 414 licensename VARCHAR UNIQUE, 415 text BLOB, 416 compressed INTEGER 417 ); 418 419 CREATE TABLE licenses_accepted ( 420 licensename VARCHAR UNIQUE 421 ); 422 423 CREATE TABLE triggers ( 424 idpackage INTEGER PRIMARY KEY, 425 data BLOB 426 ); 427 428 CREATE TABLE entropy_misc_counters ( 429 idtype INTEGER PRIMARY KEY, 430 counter INTEGER 431 ); 432 433 CREATE TABLE categoriesdescription ( 434 category VARCHAR, 435 locale VARCHAR, 436 description VARCHAR 437 ); 438 439 CREATE TABLE packagesets ( 440 setname VARCHAR, 441 dependency VARCHAR 442 ); 443 444 CREATE TABLE packagechangelogs ( 445 category VARCHAR, 446 name VARCHAR, 447 changelog BLOB, 448 PRIMARY KEY (category, name) 449 ); 450 451 CREATE TABLE automergefiles ( 452 idpackage INTEGER, 453 configfile VARCHAR, 454 md5 VARCHAR 455 ); 456 457 CREATE TABLE packagesignatures ( 458 idpackage INTEGER PRIMARY KEY, 459 sha1 VARCHAR, 460 sha256 VARCHAR, 461 sha512 VARCHAR 462 ); 463 464 CREATE TABLE packagespmphases ( 465 idpackage INTEGER PRIMARY KEY, 466 phases VARCHAR 467 ); 468 469 CREATE TABLE entropy_branch_migration ( 470 repository VARCHAR, 471 from_branch VARCHAR, 472 to_branch VARCHAR, 473 post_migration_md5sum VARCHAR, 474 post_upgrade_md5sum VARCHAR, 475 PRIMARY KEY (repository, from_branch, to_branch) 476 ); 477 478 """
479 480 import entropy.tools as entropyTools 481 import entropy.dump as dumpTools 482 import threading
483 - def __init__(self, readOnly = False, noUpload = False, dbFile = None, 484 clientDatabase = False, xcache = False, dbname = etpConst['serverdbid'], 485 indexing = True, OutputInterface = None, skipChecks = False, 486 useBranch = None, lockRemote = True):
487 488 """ 489 EntropyRepository constructor. 490 491 @keyword readOnly: open file in read-only mode 492 @type readOnly: bool 493 @keyword noUpload: server-side setting for not allowing database 494 uploads when remote revision is lower than local 495 @type noUpload: bool 496 @keyword dbFile: path to database to open 497 @type dbFile: string 498 @keyword clientDatabase: state that EntropyRepository instance is 499 a client-side one 500 @type clientDatabase: bool 501 @keyword xcache: enable on-disk cache 502 @type xcache: bool 503 @keyword dbname: EntropyRepository instance identifier 504 @type dbname: string 505 @keyword indexing: enable database indexes 506 @type indexing: bool 507 @keyword OutputInterface: interface used to communicate with the user. 508 must inherit entropy.output.TextInterface 509 @type OutputInterface: entropy.output.TextInterface based instance 510 @keyword skipChecks: if True, skip integrity checks 511 @type skipChecks: bool 512 @keyword useBranch: if True, it won't use SystemSettings' branch 513 setting but rather the one provided 514 @type useBranch: string 515 @keyword lockRemote: determine whether remote server-side database 516 should be locked when updating the local version 517 @type lockRemote: bool 518 """ 519 520 self.SystemSettings = SystemSettings() 521 self.srv_sys_settings_plugin = \ 522 etpConst['system_settings_plugins_ids']['server_plugin'] 523 self.dbMatchCacheKey = etpCache['dbMatch'] 524 self.client_settings_plugin_id = etpConst['system_settings_plugins_ids']['client_plugin'] 525 self.db_branch = self.SystemSettings['repositories']['branch'] 526 self.Cacher = EntropyCacher() 527 528 self.dbname = dbname 529 self.lockRemote = lockRemote 530 if self.dbname == etpConst['clientdbid']: 531 self.db_branch = None 532 if useBranch != None: 533 self.db_branch = useBranch 534 535 if OutputInterface == None: 536 OutputInterface = TextInterface() 537 538 if dbFile == None: 539 raise IncorrectParameter("IncorrectParameter: %s" % ( 540 _("valid database path needed"),) ) 541 542 self.__write_mutex = self.threading.RLock() 543 self.dbapi2 = dbapi2 544 # setup output interface 545 self.OutputInterface = OutputInterface 546 self.updateProgress = self.OutputInterface.updateProgress 547 self.askQuestion = self.OutputInterface.askQuestion 548 # setup service interface 549 self.readOnly = readOnly 550 self.noUpload = noUpload 551 self.clientDatabase = clientDatabase 552 self.xcache = xcache 553 self.indexing = indexing 554 self.skipChecks = skipChecks 555 if not self.skipChecks: 556 if not self.entropyTools.is_user_in_entropy_group(): 557 # forcing since we won't have write access to db 558 self.indexing = False 559 # live systems don't like wasting RAM 560 if self.entropyTools.islive(): 561 self.indexing = False 562 self.dbFile = dbFile 563 self.dbclosed = True 564 self.server_repo = None 565 566 if not self.clientDatabase: 567 self.server_repo = self.dbname[len(etpConst['serverdbid']):] 568 self._create_dbstatus_data() 569 570 if not self.skipChecks: 571 # no caching for non root and server connections 572 if (self.dbname.startswith(etpConst['serverdbid'])) or \ 573 (not self.entropyTools.is_user_in_entropy_group()): 574 self.xcache = False 575 self.live_cache = {} 576 577 # create connection 578 self.connection = self.dbapi2.connect(dbFile, timeout=300.0, 579 check_same_thread = False) 580 self.cursor = self.connection.cursor() 581 582 if not self.skipChecks: 583 try: 584 if os.access(self.dbFile, os.W_OK) and \ 585 self.doesTableExist('baseinfo') and \ 586 self.doesTableExist('extrainfo'): 587 588 if self.entropyTools.islive() and etpConst['systemroot']: 589 self.databaseStructureUpdates() 590 else: 591 self.databaseStructureUpdates() 592 except self.dbapi2.Error: 593 self.cursor.close() 594 self.connection.close() 595 raise 596 597 # now we can set this to False 598 self.dbclosed = False
599
600 - def setCacheSize(self, size):
601 """ 602 Change low-level, storage engine based cache size. 603 604 @param size: new size 605 @type size: int 606 """ 607 self.cursor.execute('PRAGMA cache_size = '+str(size))
608
609 - def setDefaultCacheSize(self, size):
610 """ 611 Change default low-level, storage engine based cache size. 612 613 @param size: new default size 614 @type size: int 615 """ 616 self.cursor.execute('PRAGMA default_cache_size = '+str(size))
617 618
619 - def __del__(self):
620 if not self.dbclosed: 621 self.closeDB()
622
623 - def _create_dbstatus_data(self):
624 """ 625 Server-side function that setups server status information 626 """ 627 from entropy.server.interfaces import Server 628 srv = Server() 629 taint_file = srv.get_local_database_taint_file(self.server_repo) 630 if os.path.isfile(taint_file): 631 dbs = ServerRepositoryStatus() 632 dbs.set_tainted(self.dbFile) 633 dbs.set_bumped(self.dbFile)
634
635 - def closeDB(self):
636 """ 637 Close repository storage communication. 638 Note: once issues this, you won't be able to use such instance 639 anymore. 640 """ 641 self.dbclosed = True 642 643 # if the class is opened readOnly, close and forget 644 if self.readOnly: 645 self.cursor.close() 646 self.connection.close() 647 return 648 649 if self.clientDatabase: 650 self.commitChanges() 651 self.cursor.close() 652 self.connection.close() 653 return 654 655 sts = ServerRepositoryStatus() 656 if not sts.is_tainted(self.dbFile): 657 # we can unlock it, no changes were made 658 from entropy.server.interfaces import Server 659 srv = Server() 660 srv.MirrorsService.lock_mirrors(False, repo = self.server_repo) 661 elif not sts.is_unlock_msg(self.dbFile): 662 u_msg = _("Mirrors have not been unlocked. Remember to sync them.") 663 self.updateProgress( 664 darkgreen(u_msg), 665 importance = 1, 666 type = "info", 667 header = brown(" * ") 668 ) 669 sts.set_unlock_msg(self.dbFile) # avoid spamming 670 671 self.commitChanges() 672 self.cursor.close() 673 self.connection.close()
674
675 - def vacuum(self):
676 """ 677 Repository storage cleanup and optimization function. 678 """ 679 self.cursor.execute("vacuum")
680
681 - def commitChanges(self):
682 """ 683 Commit actual changes and make them permanently stored. 684 """ 685 if self.readOnly: 686 return 687 688 try: 689 self.connection.commit() 690 except self.dbapi2.Error: 691 pass 692 693 if not self.clientDatabase: 694 self.taintDatabase() 695 dbs = ServerRepositoryStatus() 696 if (dbs.is_tainted(self.dbFile)) and \ 697 (not dbs.is_bumped(self.dbFile)): 698 # bump revision, setting DatabaseBump causes 699 # the session to just bump once 700 dbs.set_bumped(self.dbFile) 701 self._revisionBump()
702
703 - def taintDatabase(self):
704 """ 705 Server-side method that render your repository storage tainted, 706 modified. 707 """ 708 # if it's equo to open it, this should be avoided 709 from entropy.server.interfaces import Server 710 srv = Server() 711 # taint the database status 712 taint_file = srv.get_local_database_taint_file(repo = self.server_repo) 713 f = open(taint_file, "w") 714 f.write(etpConst['currentarch']+" database tainted\n") 715 f.flush() 716 f.close() 717 ServerRepositoryStatus().set_tainted(self.dbFile)
718
719 - def untaintDatabase(self):
720 """ 721 Server-side method that render your repository storage NOT tainted, 722 modified. 723 """ 724 # if it's equo to open it, this should be avoided 725 from entropy.server.interfaces import Server 726 srv = Server() 727 ServerRepositoryStatus().unset_tainted(self.dbFile) 728 # untaint the database status 729 taint_file = srv.get_local_database_taint_file(repo = self.server_repo) 730 if os.path.isfile(taint_file): 731 os.remove(taint_file)
732
733 - def _revisionBump(self):
734 """ 735 Entropy repository revision bumping function. Every time it's called, 736 revision is incremented by 1. 737 """ 738 from entropy.server.interfaces import Server 739 srv = Server() 740 revision_file = srv.get_local_database_revision_file( 741 repo = self.server_repo) 742 if not os.path.isfile(revision_file): 743 revision = 1 744 else: 745 f = open(revision_file, "r") 746 revision = int(f.readline().strip()) 747 revision += 1 748 f.close() 749 f = open(revision_file, "w") 750 f.write(str(revision)+"\n") 751 f.flush() 752 f.close()
753
754 - def isDatabaseTainted(self):
755 """ 756 Server-side function used to determine whether repository database 757 has been modified. 758 759 @return: taint status 760 @rtype: bool 761 """ 762 from entropy.server.interfaces import Server 763 srv = Server() 764 taint_file = srv.get_local_database_taint_file(repo = self.server_repo) 765 if os.path.isfile(taint_file): 766 return True 767 return False
768
769 - def initializeDatabase(self):
770 """ 771 WARNING: it will erase your database. 772 This method (re)initialize the repository, dropping all its content. 773 """ 774 my = self.Schema() 775 for table in self.listAllTables(): 776 try: 777 self.cursor.execute("DROP TABLE %s" % (table,)) 778 except self.dbapi2.OperationalError: 779 # skip tables that can't be dropped 780 continue 781 self.cursor.executescript(my.get_init()) 782 self.databaseStructureUpdates() 783 # set cache size 784 self.setCacheSize(8192) 785 self.setDefaultCacheSize(8192) 786 self.commitChanges()
787
788 - def filterTreeUpdatesActions(self, actions):
789 """ 790 This method should be considered internal and not suited for general 791 audience. Given a raw package name/slot updates list, it returns 792 the action that should be really taken because not applied. 793 794 @param actions: list of raw treeupdates actions, for example: 795 ['move x11-foo/bar app-foo/bar', 'slotmove x11-foo/bar 2 3'] 796 @type actions: list 797 @return: list of raw treeupdates actions that should be really 798 worked out 799 @rtype: list 800 """ 801 new_actions = [] 802 for action in actions: 803 804 if action in new_actions: # skip dupies 805 continue 806 807 doaction = action.split() 808 if doaction[0] == "slotmove": 809 810 # slot move 811 atom = doaction[1] 812 from_slot = doaction[2] 813 to_slot = doaction[3] 814 atom_key = self.entropyTools.dep_getkey(atom) 815 category = atom_key.split("/")[0] 816 matches = self.atomMatch(atom, matchSlot = from_slot, 817 multiMatch = True) 818 found = False 819 # found atoms, check category 820 for idpackage in matches[0]: 821 myslot = self.retrieveSlot(idpackage) 822 mycategory = self.retrieveCategory(idpackage) 823 if mycategory == category: 824 if (myslot != to_slot) and \ 825 (action not in new_actions): 826 new_actions.append(action) 827 found = True 828 break 829 if found: 830 continue 831 # if we get here it means found == False 832 # search into dependencies 833 dep_atoms = self.searchDependency(atom_key, like = True, 834 multi = True, strings = True) 835 dep_atoms = [x for x in dep_atoms if x.endswith(":"+from_slot) \ 836 and self.entropyTools.dep_getkey(x) == atom_key] 837 if dep_atoms: 838 new_actions.append(action) 839 840 elif doaction[0] == "move": 841 atom = doaction[1] # usually a key 842 atom_key = self.entropyTools.dep_getkey(atom) 843 category = atom_key.split("/")[0] 844 matches = self.atomMatch(atom, multiMatch = True) 845 found = False 846 for idpackage in matches[0]: 847 mycategory = self.retrieveCategory(idpackage) 848 if (mycategory == category) and (action \ 849 not in new_actions): 850 new_actions.append(action) 851 found = True 852 break 853 if found: 854 continue 855 # if we get here it means found == False 856 # search into dependencies 857 dep_atoms = self.searchDependency(atom_key, like = True, 858 multi = True, strings = True) 859 dep_atoms = [x for x in dep_atoms if \ 860 self.entropyTools.dep_getkey(x) == atom_key] 861 if dep_atoms: 862 new_actions.append(action) 863 return new_actions
864
865 - def runTreeUpdatesActions(self, actions):
866 """ 867 docstring_title 868 869 @param actions: 870 @type actions: 871 @return: 872 @rtype: 873 874 """ 875 # this is the place to add extra actions support 876 """ 877 Method not suited for general purpose usage. 878 Executes package name/slot update actions passed. 879 880 @param actions: list of raw treeupdates actions, for example: 881 ['move x11-foo/bar app-foo/bar', 'slotmove x11-foo/bar 2 3'] 882 @type actions: list 883 884 @return: list (set) of packages that should be repackaged 885 @rtype: set 886 """ 887 mytxt = "%s: %s, %s." % ( 888 bold(_("SPM")), 889 blue(_("Running fixpackages")), 890 red(_("it could take a while")), 891 ) 892 self.updateProgress( 893 mytxt, 894 importance = 1, 895 type = "warning", 896 header = darkred(" * ") 897 ) 898 try: 899 spm = get_spm(self) 900 spm.run_fixpackages() 901 except: 902 self.entropyTools.print_traceback() 903 pass 904 905 spm_moves = set() 906 quickpkg_atoms = set() 907 for action in actions: 908 command = action.split() 909 mytxt = "%s: %s: %s." % ( 910 bold(_("ENTROPY")), 911 red(_("action")), 912 blue(action), 913 ) 914 self.updateProgress( 915 mytxt, 916 importance = 1, 917 type = "warning", 918 header = darkred(" * ") 919 ) 920 if command[0] == "move": 921 spm_moves.add(action) 922 quickpkg_atoms |= self.runTreeUpdatesMoveAction(command[1:], 923 quickpkg_atoms) 924 elif command[0] == "slotmove": 925 quickpkg_atoms |= self.runTreeUpdatesSlotmoveAction(command[1:], 926 quickpkg_atoms) 927 928 mytxt = "%s: %s." % ( 929 bold(_("ENTROPY")), 930 blue(_("package move actions complete")), 931 ) 932 self.updateProgress( 933 mytxt, 934 importance = 1, 935 type = "info", 936 header = purple(" @@ ") 937 ) 938 939 if spm_moves: 940 try: 941 self.doTreeupdatesSpmCleanup(spm_moves) 942 except Exception, e: 943 mytxt = "%s: %s: %s, %s." % ( 944 bold(_("WARNING")), 945 red(_("Cannot run SPM cleanup, error")), 946 Exception, 947 e, 948 ) 949 self.entropyTools.print_traceback() 950 951 mytxt = "%s: %s." % ( 952 bold(_("ENTROPY")), 953 blue(_("package moves completed successfully")), 954 ) 955 self.updateProgress( 956 mytxt, 957 importance = 1, 958 type = "info", 959 header = brown(" @@ ") 960 ) 961 962 # discard cache 963 self.clearCache() 964 965 return quickpkg_atoms
966 967
968 - def runTreeUpdatesMoveAction(self, move_command, quickpkg_queue):
969 """ 970 docstring_title 971 972 @param move_command: 973 @type move_command: 974 @param quickpkg_queue: 975 @type quickpkg_queue: 976 @return: 977 @rtype: 978 979 """ 980 # -- move action: 981 # 1) move package key to the new name: category + name + atom 982 # 2) update all the dependencies in dependenciesreference to the new key 983 # 3) run fixpackages which will update /var/db/pkg files 984 # 4) automatically run quickpkg() to build the new binary and 985 # tainted binaries owning tainted iddependency and taint database 986 """ 987 Method not suited for general purpose usage. 988 Executes package name move action passed. 989 990 @param move_command: raw treeupdates move action, for example: 991 'move x11-foo/bar app-foo/bar' 992 @type move_command: string 993 @param quickpkg_queue: current package regeneration queue 994 @type quickpkg_queue: list 995 @return: updated package regeneration queue 996 @rtype: list 997 """ 998 dep_from = move_command[0] 999 key_from = self.entropyTools.dep_getkey(dep_from) 1000 key_to = move_command[1] 1001 cat_to = key_to.split("/")[0] 1002 name_to = key_to.split("/")[1] 1003 matches = self.atomMatch(dep_from, multiMatch = True) 1004 iddependencies = set() 1005 1006 for idpackage in matches[0]: 1007 1008 slot = self.retrieveSlot(idpackage) 1009 old_atom = self.retrieveAtom(idpackage) 1010 new_atom = old_atom.replace(key_from, key_to) 1011 1012 ### UPDATE DATABASE 1013 # update category 1014 self.setCategory(idpackage, cat_to) 1015 # update name 1016 self.setName(idpackage, name_to) 1017 # update atom 1018 self.setAtom(idpackage, new_atom) 1019 1020 # look for packages we need to quickpkg again 1021 # note: quickpkg_queue is simply ignored if self.clientDatabase 1022 quickpkg_queue.add(key_to+":"+str(slot)) 1023 1024 if not self.clientDatabase: 1025 1026 # check for injection and warn the developer 1027 injected = self.isInjected(idpackage) 1028 if injected: 1029 mytxt = "%s: %s %s. %s !!! %s." % ( 1030 bold(_("INJECT")), 1031 blue(str(new_atom)), 1032 red(_("has been injected")), 1033 red(_("quickpkg manually to update embedded db")), 1034 red(_("Repository database updated anyway")), 1035 ) 1036 self.updateProgress( 1037 mytxt, 1038 importance = 1, 1039 type = "warning", 1040 header = darkred(" * ") 1041 ) 1042 1043 iddeps = self.searchDependency(key_from, like = True, multi = True) 1044 for iddep in iddeps: 1045 # update string 1046 mydep = self.retrieveDependencyFromIddependency(iddep) 1047 mydep_key = self.entropyTools.dep_getkey(mydep) 1048 # avoid changing wrong atoms -> dev-python/qscintilla-python would 1049 # become x11-libs/qscintilla if we don't do this check 1050 if mydep_key != key_from: 1051 continue 1052 mydep = mydep.replace(key_from, key_to) 1053 # now update 1054 # dependstable on server is always re-generated 1055 self.setDependency(iddep, mydep) 1056 # we have to repackage also package owning this iddep 1057 iddependencies |= self.searchIdpackageFromIddependency(iddep) 1058 1059 self.commitChanges() 1060 quickpkg_queue = list(quickpkg_queue) 1061 for x in range(len(quickpkg_queue)): 1062 myatom = quickpkg_queue[x] 1063 myatom = myatom.replace(key_from, key_to) 1064 quickpkg_queue[x] = myatom 1065 quickpkg_queue = set(quickpkg_queue) 1066 for idpackage_owner in iddependencies: 1067 myatom = self.retrieveAtom(idpackage_owner) 1068 myatom = myatom.replace(key_from, key_to) 1069 quickpkg_queue.add(myatom) 1070 return quickpkg_queue
1071 1072
1073 - def runTreeUpdatesSlotmoveAction(self, slotmove_command, quickpkg_queue):
1074 """ 1075 docstring_title 1076 1077 @param slotmove_command: 1078 @type slotmove_command: 1079 @param quickpkg_queue: 1080 @type quickpkg_queue: 1081 @return: 1082 @rtype: 1083 1084 """ 1085 # -- slotmove action: 1086 # 1) move package slot 1087 # 2) update all the dependencies in dependenciesreference owning 1088 # same matched atom + slot 1089 # 3) run fixpackages which will update /var/db/pkg files 1090 # 4) automatically run quickpkg() to build the new 1091 # binary and tainted binaries owning tainted iddependency 1092 # and taint database 1093 """ 1094 Method not suited for general purpose usage. 1095 Executes package slot move action passed. 1096 1097 @param slotmove_command: raw treeupdates slot move action, for example: 1098 'slotmove x11-foo/bar 2 3' 1099 @type slotmove_command: string 1100 @param quickpkg_queue: current package regeneration queue 1101 @type quickpkg_queue: list 1102 @return: updated package regeneration queue 1103 @rtype: list 1104 """ 1105 atom = slotmove_command[0] 1106 atomkey = self.entropyTools.dep_getkey(atom) 1107 slot_from = slotmove_command[1] 1108 slot_to = slotmove_command[2] 1109 matches = self.atomMatch(atom, multiMatch = True) 1110 iddependencies = set() 1111 1112 matched_idpackages = matches[0] 1113 for idpackage in matched_idpackages: 1114 1115 ### UPDATE DATABASE 1116 # update slot 1117 self.setSlot(idpackage, slot_to) 1118 1119 # look for packages we need to quickpkg again 1120 # note: quickpkg_queue is simply ignored if self.clientDatabase 1121 quickpkg_queue.add(atom+":"+str(slot_to)) 1122 1123 if not self.clientDatabase: 1124 1125 # check for injection and warn the developer 1126 injected = self.isInjected(idpackage) 1127 if injected: 1128 mytxt = "%s: %s %s. %s !!! %s." % ( 1129 bold(_("INJECT")), 1130 blue(str(atom)), 1131 red(_("has been injected")), 1132 red(_("quickpkg manually to update embedded db")), 1133 red(_("Repository database updated anyway")), 1134 ) 1135 self.updateProgress( 1136 mytxt, 1137 importance = 1, 1138 type = "warning", 1139 header = darkred(" * ") 1140 ) 1141 1142 # only if we've found VALID matches ! 1143 iddeps = self.searchDependency(atomkey, like = True, multi = True) 1144 for iddep in iddeps: 1145 # update string 1146 mydep = self.retrieveDependencyFromIddependency(iddep) 1147 mydep_key = self.entropyTools.dep_getkey(mydep) 1148 if mydep_key != atomkey: 1149 continue 1150 if not mydep.endswith(":"+slot_from): # probably slotted dep 1151 continue 1152 mydep_match = self.atomMatch(mydep) 1153 if mydep_match not in matched_idpackages: 1154 continue 1155 mydep = mydep.replace(":"+slot_from, ":"+slot_to) 1156 # now update 1157 # dependstable on server is always re-generated 1158 self.setDependency(iddep, mydep) 1159 # we have to repackage also package owning this iddep 1160 iddependencies |= self.searchIdpackageFromIddependency(iddep) 1161 1162 self.commitChanges() 1163 for idpackage_owner in iddependencies: 1164 myatom = self.retrieveAtom(idpackage_owner) 1165 quickpkg_queue.add(myatom) 1166 return quickpkg_queue
1167
1168 - def doTreeupdatesSpmCleanup(self, spm_moves):
1169 """ 1170 Erase dead Source Package Manager db entries. 1171 1172 @todo: make more Portage independent (create proper entropy.spm 1173 methods for dealing with this) 1174 @param spm_moves: list of raw package name/slot update actions. 1175 @type spm_moves: list 1176 """ 1177 # now erase Spm entries if necessary 1178 for action in spm_moves: 1179 command = action.split() 1180 if len(command) < 2: 1181 continue 1182 key = command[1] 1183 name = key.split("/")[1] 1184 try: 1185 spm = get_spm(self) 1186 except: 1187 self.entropyTools.print_traceback() 1188 continue 1189 1190 vdb_path = spm.get_vdb_path() 1191 pkg_path = os.path.join(vdb_path, key.split("/")[0]) 1192 try: 1193 mydirs = [os.path.join(pkg_path, x) for x in \ 1194 os.listdir(pkg_path) if x.startswith(name)] 1195 except OSError: # no dir, no party! 1196 continue 1197 mydirs = [x for x in mydirs if os.path.isdir(x)] 1198 # now move these dirs 1199 for mydir in mydirs: 1200 to_path = os.path.join(etpConst['packagestmpdir'], 1201 os.path.basename(mydir)) 1202 mytxt = "%s: %s '%s' %s '%s'" % ( 1203 bold(_("SPM")), 1204 red(_("Moving old entry")), 1205 blue(mydir), 1206 red(_("to")), 1207 blue(to_path), 1208 ) 1209 self.updateProgress( 1210 mytxt, 1211 importance = 1, 1212 type = "warning", 1213 header = darkred(" * ") 1214 ) 1215 if os.path.isdir(to_path): 1216 shutil.rmtree(to_path, True) 1217 try: 1218 os.rmdir(to_path) 1219 except OSError: 1220 pass 1221 shutil.move(mydir, to_path)
1222 1223
1224 - def handlePackage(self, etpData, forcedRevision = -1, 1225 formattedContent = False):
1226 """ 1227 Update or add a package to repository automatically handling 1228 its scope and thus removal of previous versions if requested by 1229 the given metadata. 1230 etpData is a dict() containing all the information bound to 1231 a package: 1232 1233 { 1234 'signatures': 1235 { 1236 'sha256': u'zzz', 1237 'sha1': u'zzz', 1238 'sha512': u'zzz' 1239 }, 1240 'slot': u'0', 1241 'datecreation': u'1247681752.93', 1242 'description': u'Standard (de)compression library', 1243 'useflags': set([u'kernel_linux']), 1244 'eclasses': set([u'multilib']), 1245 'config_protect_mask': u'string string', 'etpapi': 3, 1246 'mirrorlinks': [], 1247 'cxxflags': u'-Os -march=x86-64 -pipe', 1248 'injected': False, 1249 'licensedata': {u'ZLIB': u"lictext"}, 1250 'dependencies': {}, 1251 'chost': u'x86_64-pc-linux-gnu', 1252 'config_protect': u'string string', 1253 'download': u'packages/amd64/4/sys-libs:zlib-1.2.3-r1.tbz2', 1254 'conflicts': set([]), 1255 'digest': u'fd54248ae060c287b1ec939de3e55332', 1256 'size': u'136302', 1257 'category': u'sys-libs', 1258 'license': u'ZLIB', 1259 'needed_paths': {}, 1260 'sources': set(), 1261 'name': u'zlib', 1262 'versiontag': u'', 1263 'changelog': u"text", 1264 'provide': set([]), 1265 'trigger': u'text', 1266 'counter': 22331, 1267 'messages': [], 1268 'branch': u'4', 1269 'content': {}, 1270 'needed': [(u'libc.so.6', 2)], 1271 'version': u'1.2.3-r1', 1272 'keywords': set(), 1273 'cflags': u'-Os -march=x86-64 -pipe', 1274 'disksize': 932206, 'spm_phases': None, 1275 'homepage': u'http://www.zlib.net/', 1276 'systempackage': True, 1277 'revision': 0 1278 } 1279 1280 @param etpData: Entropy package metadata dict 1281 @type etpData: dict 1282 @keyword forcedRevision: force a specific package revision 1283 @type forcedRevision: int 1284 @keyword formattedContent: tells whether content metadata is already 1285 formatted for insertion 1286 @type formattedContent: bool 1287 @return: tuple composed by 1288 - idpackage: unique Entropy Repository package identifier 1289 - revision: final package revision selected 1290 - etpData: new Entropy package metadata dict 1291 @rtype: tuple 1292 """ 1293 1294 def remove_conflicting_packages(pkgdata): 1295 """ 1296 docstring_title 1297 1298 @param pkgdata: 1299 @type pkgdata: 1300 @return: 1301 @rtype: 1302 1303 """ 1304 1305 manual_deps = set() 1306 removelist = self.retrieve_packages_to_remove( 1307 pkgdata['name'], pkgdata['category'], 1308 pkgdata['slot'], pkgdata['injected'] 1309 ) 1310 1311 for r_idpackage in removelist: 1312 manual_deps |= self.retrieveManualDependencies(r_idpackage) 1313 self.removePackage(r_idpackage, do_cleanup = False, 1314 do_commit = False) 1315 1316 # inject old manual dependencies back to package metadata 1317 for manual_dep in manual_deps: 1318 if manual_dep in pkgdata['dependencies']: 1319 continue 1320 pkgdata['dependencies'][manual_dep] = etpConst['spm']['mdepend_id']
1321 1322 1323 1324 if self.clientDatabase: 1325 remove_conflicting_packages(etpData) 1326 return self.addPackage(etpData, revision = forcedRevision, 1327 formatted_content = formattedContent) 1328 1329 # build atom string, server side 1330 pkgatom = self.entropyTools.create_package_atom_string( 1331 etpData['category'], etpData['name'], etpData['version'], 1332 etpData['versiontag']) 1333 1334 foundid = self.isPackageAvailable(pkgatom) 1335 if foundid < 0: # same atom doesn't exist in any branch 1336 remove_conflicting_packages(etpData) 1337 return self.addPackage(etpData, revision = forcedRevision, 1338 formatted_content = formattedContent) 1339 1340 idpackage = self.getIDPackage(pkgatom) 1341 curRevision = forcedRevision 1342 if forcedRevision is -1: 1343 curRevision = 0 1344 if idpackage != -1: 1345 curRevision = self.retrieveRevision(idpackage) 1346 1347 # remove old package atom, we do it here because othersie 1348 if idpackage != -1: 1349 # injected packages wouldn't be removed by addPackages 1350 self.removePackage(idpackage) 1351 if forcedRevision is -1: 1352 curRevision += 1 1353 1354 # add the new one 1355 remove_conflicting_packages(etpData) 1356 return self.addPackage(etpData, revision = curRevision, 1357 formatted_content = formattedContent)
1358
1359 - def retrieve_packages_to_remove(self, name, category, slot, injected):
1360 """ 1361 Return a list of packages that would be removed given name, category, 1362 slot and injection status. 1363 1364 @param name: package name 1365 @type name: string 1366 @param category: package category 1367 @type category: string 1368 @param slot: package slot 1369 @type slot: string 1370 @param injected: injection status (packages marked as injected are 1371 always considered not automatically removable) 1372 @type injected: bool 1373 1374 @return: list (set) of removable packages (idpackages) 1375 @rtype: set 1376 """ 1377 1378 removelist = set() 1379 if injected: 1380 # read: if package has been injected, we'll skip 1381 # the removal of packages in the same slot, 1382 # usually used server side btw 1383 return removelist 1384 1385 # support for expiration-based packages handling, also internally 1386 # called Fat Scope. 1387 filter_similar = False 1388 srv_ss_plg = etpConst['system_settings_plugins_ids']['server_plugin'] 1389 srv_ss_fs_plg = \ 1390 etpConst['system_settings_plugins_ids']['server_plugin_fatscope'] 1391 1392 if not self.clientDatabase: # server-side db 1393 srv_plug_settings = self.SystemSettings.get(srv_ss_plg) 1394 if srv_plug_settings != None: 1395 if srv_plug_settings['server']['exp_based_scope']: 1396 # in case support is enabled, return an empty set 1397 filter_similar = True 1398 1399 searchsimilar = self.searchPackagesByNameAndCategory( 1400 name = name, 1401 category = category, 1402 sensitive = True 1403 ) 1404 if filter_similar: 1405 # filter out packages in the same scope that are allowed to stay 1406 idpkgs = self.SystemSettings[srv_ss_fs_plg]['repos'].get( 1407 self.server_repo) 1408 if idpkgs: 1409 if -1 in idpkgs: 1410 del searchsimilar[:] 1411 else: 1412 searchsimilar = [x for x in searchsimilar if x[1] \ 1413 not in idpkgs] 1414 1415 for atom, idpackage in searchsimilar: 1416 # get the package slot 1417 myslot = self.retrieveSlot(idpackage) 1418 # we merely ignore packages with 1419 # negative counters, since they're the injected ones 1420 if self.isInjected(idpackage): continue 1421 if slot == myslot: 1422 # remove! 1423 removelist.add(idpackage) 1424 1425 return removelist
1426
1427 - def addPackage(self, etpData, revision = -1, idpackage = None, 1428 do_commit = True, formatted_content = False):
1429 """ 1430 Add package to this Entropy repository. The main difference between 1431 handlePackage and this is that from here, no packages are going to be 1432 removed, in any case. 1433 For more information about etpData layout, please see 1434 I{handlePackage()}. 1435 1436 @param etpData: Entropy package metadata 1437 @type etpData: dict 1438 @keyword revision: force a specific Entropy package revision 1439 @type revision: int 1440 @keyword idpackage: add package to Entropy repository using the 1441 provided package identifier, this is very dangerous and could 1442 cause packages with the same identifier to be removed. 1443 @type idpackage: int 1444 @keyword do_commit: if True, automatically commits the executed 1445 transaction (could cause slowness) 1446 @type do_commit: bool 1447 @keyword formatted_content: if True, determines whether the content 1448 metadata (usually the biggest part) in etpData is already 1449 prepared for insertion 1450 @type formatted_content: bool 1451 @return: tuple composed by 1452 - idpackage: unique Entropy Repository package identifier 1453 - revision: final package revision selected 1454 - etpData: new Entropy package metadata dict 1455 @rtype: tuple 1456 """ 1457 if revision is -1: 1458 try: 1459 revision = int(etpData['revision']) 1460 except (KeyError, ValueError): 1461 etpData['revision'] = 0 # revision not specified 1462 revision = 0 1463 elif not etpData.has_key('revision'): 1464 etpData['revision'] = revision 1465 1466 # create new category if it doesn't exist 1467 catid = self.isCategoryAvailable(etpData['category']) 1468 if catid is -1: catid = self.addCategory(etpData['category']) 1469 1470 # create new license if it doesn't exist 1471 licid = self.isLicenseAvailable(etpData['license']) 1472 if licid is -1: licid = self.addLicense(etpData['license']) 1473 1474 idprotect = self.isProtectAvailable(etpData['config_protect']) 1475 if idprotect is -1: idprotect = self.addProtect( 1476 etpData['config_protect']) 1477 1478 idprotect_mask = self.isProtectAvailable( 1479 etpData['config_protect_mask']) 1480 if idprotect_mask is -1: idprotect_mask = self.addProtect( 1481 etpData['config_protect_mask']) 1482 1483 idflags = self.areCompileFlagsAvailable( 1484 etpData['chost'],etpData['cflags'],etpData['cxxflags']) 1485 if idflags is -1: idflags = self.addCompileFlags( 1486 etpData['chost'],etpData['cflags'],etpData['cxxflags']) 1487 1488 trigger = 0 1489 if etpData['trigger']: 1490 trigger = 1 1491 1492 # baseinfo 1493 pkgatom = self.entropyTools.create_package_atom_string( 1494 etpData['category'], etpData['name'], etpData['version'], 1495 etpData['versiontag']) 1496 # add atom metadatum 1497 etpData['atom'] = pkgatom 1498 1499 mybaseinfo_data = (pkgatom, catid, etpData['name'], etpData['version'], 1500 etpData['versiontag'], revision, etpData['branch'], etpData['slot'], 1501 licid, etpData['etpapi'], trigger,) 1502 1503 myidpackage_string = 'NULL' 1504 if isinstance(idpackage, (int, long,)): 1505 1506 manual_deps = self.retrieveManualDependencies(idpackage) 1507 1508 # does it exist? 1509 self.removePackage(idpackage, do_cleanup = False, 1510 do_commit = False, do_rss = False) 1511 myidpackage_string = '?' 1512 mybaseinfo_data = (idpackage,)+mybaseinfo_data 1513 1514 # merge old manual dependencies 1515 dep_dict = etpData['dependencies'] 1516 for manual_dep in manual_deps: 1517 if manual_dep in dep_dict: 1518 continue 1519 dep_dict[manual_dep] = etpConst['spm']['mdepend_id'] 1520 1521 else: 1522 # force to None 1523 idpackage = None 1524 1525 1526 with self.__write_mutex: 1527 1528 cur = self.cursor.execute(""" 1529 INSERT INTO baseinfo VALUES (%s,?,?,?,?,?,?,?,?,?,?,?)""" % ( 1530 myidpackage_string,), mybaseinfo_data) 1531 if idpackage == None: 1532 idpackage = cur.lastrowid 1533 1534 # extrainfo 1535 self.cursor.execute( 1536 'INSERT INTO extrainfo VALUES (?,?,?,?,?,?,?,?)', 1537 ( idpackage, 1538 etpData['description'], 1539 etpData['homepage'], 1540 etpData['download'], 1541 etpData['size'], 1542 idflags, 1543 etpData['digest'], 1544 etpData['datecreation'], 1545 ) 1546 ) 1547 ### other information iserted below are not as critical as these above 1548 1549 # tables using a select 1550 self.insertEclasses(idpackage, etpData['eclasses']) 1551 self.insertNeeded(idpackage, etpData['needed']) 1552 self.insertDependencies(idpackage, etpData['dependencies']) 1553 self.insertSources(idpackage, etpData['sources']) 1554 self.insertUseflags(idpackage, etpData['useflags']) 1555 self.insertKeywords(idpackage, etpData['keywords']) 1556 self.insertLicenses(etpData['licensedata']) 1557 self.insertMirrors(etpData['mirrorlinks']) 1558 # package ChangeLog 1559 if etpData.get('changelog'): 1560 self.insertChangelog(etpData['category'], etpData['name'], 1561 etpData['changelog']) 1562 # package signatures 1563 if etpData.get('signatures'): 1564 signatures = etpData['signatures'] 1565 sha1, sha256, sha512 = signatures['sha1'], signatures['sha256'], \ 1566 signatures['sha512'] 1567 self.insertSignatures(idpackage, sha1, sha256, sha512) 1568 # needed libraries paths 1569 if etpData.get('needed_paths'): 1570 for lib in sorted(etpData['needed_paths']): 1571 self.insertNeededPaths(lib, etpData['needed_paths'][lib]) 1572 1573 # spm phases 1574 if etpData.get('spm_phases') != None: 1575 self.insertSpmPhases(idpackage, etpData['spm_phases']) 1576 1577 # not depending on other tables == no select done 1578 self.insertContent(idpackage, etpData['content'], 1579 already_formatted = formatted_content) 1580 etpData['counter'] = int(etpData['counter']) # cast to integer 1581 etpData['counter'] = self.insertPortageCounter( 1582 idpackage, 1583 etpData['counter'], 1584 etpData['branch'], 1585 etpData['injected'] 1586 ) 1587 self.insertOnDiskSize(idpackage, etpData['disksize']) 1588 if etpData['trigger']: 1589 self.insertTrigger(idpackage, etpData['trigger']) 1590 self.insertConflicts(idpackage, etpData['conflicts']) 1591 self.insertProvide(idpackage, etpData['provide']) 1592 self.insertMessages(idpackage, etpData['messages']) 1593 self.insertConfigProtect(idpackage, idprotect) 1594 self.insertConfigProtect(idpackage, idprotect_mask, mask = True) 1595 # injected? 1596 if etpData.get('injected'): 1597 self.setInjected(idpackage, do_commit = False) 1598 # is it a system package? 1599 if etpData.get('systempackage'): 1600 self.setSystemPackage(idpackage, do_commit = False) 1601 1602 self.clearCache() # we do live_cache.clear() here too 1603 if do_commit: 1604 self.commitChanges() 1605 1606 ### RSS Atom support 1607 ### dictionary will be elaborated by activator 1608 if self.SystemSettings.has_key(self.srv_sys_settings_plugin): 1609 if self.SystemSettings[self.srv_sys_settings_plugin]['server']['rss']['enabled'] and \ 1610 not self.clientDatabase: 1611 1612 self._write_rss_for_added_package(pkgatom, revision, 1613 etpData['description'], etpData['homepage']) 1614 1615 # Update category description 1616 if not self.clientDatabase: 1617 mycategory = etpData['category'] 1618 descdata = {} 1619 try: 1620 descdata = self.get_category_description_from_disk(mycategory) 1621 except (IOError, OSError, EOFError,): 1622 pass 1623 if descdata: 1624 self.setCategoryDescription(mycategory, descdata) 1625 1626 return idpackage, revision, etpData
1627
1628 - def _write_rss_for_added_package(self, pkgatom, revision, description, 1629 homepage):
1630 1631 # setup variables we're going to use 1632 srv_repo = self.server_repo 1633 rss_atom = "%s~%s" % (pkgatom, revision,) 1634 status = ServerRepositoryStatus() 1635 srv_updates = status.get_updates_log(srv_repo) 1636 rss_name = srv_repo + etpConst['rss-dump-name'] 1637 1638 # load metadata from on disk cache, if available 1639 rss_obj = self.dumpTools.loadobj(rss_name) 1640 if rss_obj: 1641 srv_updates.update(rss_obj) 1642 1643 # setup metadata keys, if not available 1644 if not srv_updates.has_key('added'): 1645 srv_updates['added'] = {} 1646 if not srv_updates.has_key('removed'): 1647 srv_updates['removed'] = {} 1648 1649 # if pkgatom (rss_atom) is in the "removed" metadata, drop it 1650 if rss_atom in srv_updates['removed']: 1651 del srv_updates['removed'][rss_atom] 1652 1653 # add metadata 1654 srv_updates['added'][rss_atom] = {} 1655 srv_updates['added'][rss_atom]['description'] = description 1656 srv_updates['added'][rss_atom]['homepage'] = homepage 1657 srv_updates['light'][rss_atom] = {} 1658 srv_updates['light'][rss_atom]['description'] = description 1659 1660 # save to disk 1661 self.dumpTools.dumpobj(rss_name, srv_updates)
1662
1663 - def _write_rss_for_removed_package(self, idpackage):
1664 """ 1665 docstring_title 1666 1667 @param idpackage: 1668 @type idpackage: 1669 @return: 1670 @rtype: 1671 1672 """ 1673 1674 # setup variables we're going to use 1675 srv_repo = self.server_repo 1676 rss_revision = self.retrieveRevision(idpackage) 1677 rss_atom = "%s~%s" % (self.retrieveAtom(idpackage), rss_revision,) 1678 status = ServerRepositoryStatus() 1679 srv_updates = status.get_updates_log(srv_repo) 1680 rss_name = srv_repo + etpConst['rss-dump-name'] 1681 1682 # load metadata from on disk cache, if available 1683 rss_obj = self.dumpTools.loadobj(rss_name) 1684 if rss_obj: 1685 srv_updates.update(rss_obj) 1686 1687 # setup metadata keys, if not available 1688 if not srv_updates.has_key('added'): 1689 srv_updates['added'] = {} 1690 if not srv_updates.has_key('removed'): 1691 srv_updates['removed'] = {} 1692 if not srv_updates.has_key('light'): 1693 srv_updates['light'] = [] 1694 1695 # if pkgatom (rss_atom) is in the "added" metadata, drop it 1696 if rss_atom in srv_updates['added']: 1697 del srv_updates['added'][rss_atom] 1698 # same thing for light key 1699 if rss_atom in srv_updates['light']: 1700 del srv_updates['light'][rss_atom] 1701 1702 # add metadata 1703 mydict = {} 1704 try: 1705 mydict['description'] = self.retrieveDescription(idpackage) 1706 except TypeError: 1707 mydict['description'] = "N/A" 1708 try: 1709 mydict['homepage'] = self.retrieveHomepage(idpackage) 1710 except TypeError: 1711 mydict['homepage'] = "" 1712 srv_updates['removed'][rss_atom] = mydict 1713 1714 # save to disk 1715 self.dumpTools.dumpobj(rss_name, srv_updates)
1716
1717 - def removePackage(self, idpackage, do_cleanup = True, do_commit = True, 1718 do_rss = True):
1719 """ 1720 Remove package from this Entropy repository using it's identifier 1721 (idpackage). 1722 1723 @param idpackage: Entropy repository package indentifier 1724 @type idpackage: int 1725 @keyword do_cleanup: if True, executes repository metadata cleanup 1726 at the end 1727 @type do_cleanup: bool 1728 @keyword do_commit: if True, commits the transaction (could cause 1729 slowness) 1730 @type do_commit: bool 1731 @keyword do_rss: triggered only for server-side repositories, if True, 1732 generates information about the removal in RSS form, dumping data 1733 to cache (used internally to handle RSS support for repositories). 1734 @type do_rss: bool 1735 """ 1736 # clear caches 1737 self.clearCache() 1738 1739 ### RSS Atom support 1740 ### dictionary will be elaborated by activator 1741 if self.SystemSettings.has_key(self.srv_sys_settings_plugin): 1742 if self.SystemSettings[self.srv_sys_settings_plugin]['server']['rss']['enabled'] and \ 1743 (not self.clientDatabase) and do_rss: 1744 1745 # store addPackage action 1746 self._write_rss_for_removed_package(idpackage) 1747 1748 with self.__write_mutex: 1749 1750 r_tup = (idpackage,)*20 1751 self.cursor.executescript(""" 1752 DELETE FROM baseinfo WHERE idpackage = %d; 1753 DELETE FROM extrainfo WHERE idpackage = %d; 1754 DELETE FROM dependencies WHERE idpackage = %d; 1755 DELETE FROM provide WHERE idpackage = %d; 1756 DELETE FROM conflicts WHERE idpackage = %d; 1757 DELETE FROM configprotect WHERE idpackage = %d; 1758 DELETE FROM configprotectmask WHERE idpackage = %d; 1759 DELETE FROM sources WHERE idpackage = %d; 1760 DELETE FROM useflags WHERE idpackage = %d; 1761 DELETE FROM keywords WHERE idpackage = %d; 1762 DELETE FROM content WHERE idpackage = %d; 1763 DELETE FROM messages WHERE idpackage = %d; 1764 DELETE FROM counters WHERE idpackage = %d; 1765 DELETE FROM sizes WHERE idpackage = %d; 1766 DELETE FROM eclasses WHERE idpackage = %d; 1767 DELETE FROM needed WHERE idpackage = %d; 1768 DELETE FROM triggers WHERE idpackage = %d; 1769 DELETE FROM systempackages WHERE idpackage = %d; 1770 DELETE FROM injected WHERE idpackage = %d; 1771 DELETE FROM installedtable WHERE idpackage = %d; 1772 """ % r_tup) 1773 1774 # FIXME: move these inside the main SQL script above 1775 try: 1776 self.removeAutomergefiles(idpackage) 1777 except self.dbapi2.OperationalError: 1778 pass 1779 try: 1780 self.removeSignatures(idpackage) 1781 except self.dbapi2.OperationalError: 1782 pass 1783 try: 1784 self.removeSpmPhases(idpackage) 1785 except self.dbapi2.OperationalError: 1786 pass 1787 1788 # Remove from dependstable if exists 1789 self.removePackageFromDependsTable(idpackage) 1790 1791 if do_cleanup: 1792 # Cleanups if at least one package has been removed 1793 self.doCleanups() 1794 1795 if do_commit: 1796 self.commitChanges()
1797
1798 - def removeMirrorEntries(self, mirrorname):
1799 """ 1800 Remove source packages mirror entries from database for the given 1801 mirror name. This is a representation of Portage's "thirdpartymirrors". 1802 1803 @param mirrorname: mirror name 1804 @type mirrorname: string 1805 """ 1806 with self.__write_mutex: 1807 self.cursor.execute(""" 1808 DELETE FROM mirrorlinks WHERE mirrorname = (?) 1809 """,(mirrorname,))
1810
1811 - def addMirrors(self, mirrorname, mirrorlist):
1812 """ 1813 Add source package mirror entry to database. 1814 This is a representation of Portage's "thirdpartymirrors". 1815 1816 @param mirrorname: name of the mirror from which "mirrorlist" belongs 1817 @type mirrorname: string 1818 @param mirrorlist: list of URLs belonging to the given mirror name 1819 @type mirrorlist: list 1820 """ 1821 with self.__write_mutex: 1822 data = [(mirrorname, x,) for x in mirrorlist] 1823 self.cursor.executemany(""" 1824 INSERT into mirrorlinks VALUES (?,?) 1825 """, data)
1826
1827 - def addCategory(self, category):
1828 """ 1829 Add package category string to repository. Return its identifier 1830 (idcategory). 1831 1832 @param category: name of the category to add 1833 @type category: string 1834 @return: category identifier (idcategory) 1835 @rtype: int 1836 """ 1837 with self.__write_mutex: 1838 cur = self.cursor.execute(""" 1839 INSERT into categories VALUES (NULL,?) 1840 """, (category,)) 1841 return cur.lastrowid
1842
1843 - def addProtect(self, protect):
1844 """ 1845 Add a single, generic CONFIG_PROTECT (not defined as _MASK/whatever 1846 here) path. Return its identifier (idprotect). 1847 1848 @param protect: CONFIG_PROTECT path to add 1849 @type protect: string 1850 @return: protect identifier (idprotect) 1851 @rtype: int 1852 """ 1853 with self.__write_mutex: 1854 cur = self.cursor.execute(""" 1855 INSERT into configprotectreference VALUES (NULL,?) 1856 """, (protect,)) 1857 return cur.lastrowid
1858
1859 - def addSource(self, source):
1860 """ 1861 Add source code package download path to repository. Return its 1862 identifier (idsource). 1863 1864 @param source: source package download path 1865 @type source: string 1866 @return: source identifier (idprotect) 1867 @rtype: int 1868 """ 1869 with self.__write_mutex: 1870 cur = self.cursor.execute(""" 1871 INSERT into sourcesreference VALUES (NULL,?) 1872 """, (source,)) 1873 return cur.lastrowid
1874
1875 - def addDependency(self, dependency):
1876 """ 1877 Add dependency string to repository. Return its identifier 1878 (iddependency). 1879 1880 @param dependency: dependency string 1881 @type dependency: string 1882 @return: dependency identifier (iddependency) 1883 @rtype: int 1884 """ 1885 with self.__write_mutex: 1886 cur = self.cursor.execute(""" 1887 INSERT into dependenciesreference VALUES (NULL,?) 1888 """, (dependency,)) 1889 return cur.lastrowid
1890
1891 - def addKeyword(self, keyword):
1892 """ 1893 Add package SPM keyword string to repository. 1894 Return its identifier (idkeyword). 1895 1896 @param keyword: keyword string 1897 @type keyword: string 1898 @return: keyword identifier (idkeyword) 1899 @rtype: int 1900 """ 1901 with self.__write_mutex: 1902 cur = self.cursor.execute(""" 1903 INSERT into keywordsreference VALUES (NULL,?) 1904 """, (keyword,)) 1905 return cur.lastrowid
1906
1907 - def addUseflag(self, useflag):
1908 """ 1909 Add package USE flag string to repository. 1910 Return its identifier (iduseflag). 1911 1912 @param useflag: useflag string 1913 @type useflag: string 1914 @return: useflag identifier (iduseflag) 1915 @rtype: int 1916 """ 1917 with self.__write_mutex: 1918 cur = self.cursor.execute(""" 1919 INSERT into useflagsreference VALUES (NULL,?) 1920 """, (useflag,)) 1921 return cur.lastrowid
1922
1923 - def addEclass(self, eclass):
1924 """ 1925 Add package SPM Eclass string to repository. 1926 Return its identifier (ideclass). 1927 1928 @param eclass: eclass string 1929 @type eclass: string 1930 @return: eclass identifier (ideclass) 1931 @rtype: int 1932 """ 1933 with self.__write_mutex: 1934 cur = self.cursor.execute(""" 1935 INSERT into eclassesreference VALUES (NULL,?) 1936 """, (eclass,)) 1937 return cur.lastrowid
1938
1939 - def addNeeded(self, needed):
1940 """ 1941 Add package libraries' ELF object NEEDED string to repository. 1942 Return its identifier (idneeded). 1943 1944 @param needed: NEEDED string (as shown in `readelf -d elf.so`) 1945 @type needed: string 1946 @return: needed identifier (idneeded) 1947 @rtype: int 1948 """ 1949 with self.__write_mutex: 1950 cur = self.cursor.execute(""" 1951 INSERT into neededreference VALUES (NULL,?) 1952 """, (needed,)) 1953 return cur.lastrowid
1954
1955 - def addLicense(self, pkglicense):
1956 """ 1957 Add package license name string to repository. 1958 Return its identifier (idlicense). 1959 1960 @param pkglicense: license name string 1961 @type pkglicense: string 1962 @return: license name identifier (idlicense) 1963 @rtype: int 1964 """ 1965 if not self.entropyTools.is_valid_string(pkglicense): 1966 pkglicense = ' ' # workaround for broken license entries 1967 with self.__write_mutex: 1968 cur = self.cursor.execute(""" 1969 INSERT into licenses VALUES (NULL,?) 1970 """, (pkglicense,)) 1971 return cur.lastrowid
1972
1973 - def addCompileFlags(self, chost, cflags, cxxflags):
1974 """ 1975 Add package Compiler flags used to repository. 1976 Return its identifier (idflags). 1977 1978 @param chost: CHOST string 1979 @type chost: string 1980 @param cflags: CFLAGS string 1981 @type cflags: string 1982 @param cxxflags: CXXFLAGS string 1983 @type cxxflags: string 1984 @return: Compiler flags triple identifier (idflags) 1985 @rtype: int 1986 """ 1987 with self.__write_mutex: 1988 cur = self.cursor.execute(""" 1989 INSERT into flags VALUES (NULL,?,?,?) 1990 """, (chost,cflags,cxxflags,)) 1991 return cur.lastrowid
1992
1993 - def setSystemPackage(self, idpackage, do_commit = True):
1994 """ 1995 Mark a package as system package, which means that entropy.client 1996 will deny its removal. 1997 1998 @param idpackage: package identifier 1999 @type idpackage: int 2000 @keyword do_commit: determine whether executing commit or not 2001 @type do_commit: bool 2002 """ 2003 with self.__write_mutex: 2004 self.cursor.execute(""" 2005 INSERT into systempackages VALUES (?) 2006 """, (idpackage,)) 2007 if do_commit: 2008 self.commitChanges()
2009
2010 - def setInjected(self, idpackage, do_commit = True):
2011 """ 2012 Mark package as injected, injection is usually set for packages 2013 manually added to repository. Injected packages are not removed 2014 automatically even when featuring conflicting scope with other 2015 that are being added. If a package is injected, it means that 2016 maintainers have to handle it manually. 2017 2018 @param idpackage: package indentifier 2019 @type idpackage: int 2020 @keyword do_commit: determine whether executing commit or not 2021 @type do_commit: bool 2022 """ 2023 with self.__write_mutex: 2024 if not self.isInjected(idpackage): 2025 self.cursor.execute(""" 2026 INSERT into injected VALUES (?) 2027 """, (idpackage,)) 2028 if do_commit: 2029 self.commitChanges()
2030
2031 - def setDateCreation(self, idpackage, date):
2032 """ 2033 Update the creation date for package. Creation date is stored in 2034 string based unix time format. 2035 2036 @param idpackage: package indentifier 2037 @type idpackage: int 2038 @param date: unix time in string form 2039 @type date: string 2040 """ 2041 with self.__write_mutex: 2042 self.cursor.execute(""" 2043 UPDATE extrainfo SET datecreation = (?) WHERE idpackage = (?) 2044 """, (str(date), idpackage,)) 2045 self.commitChanges()
2046
2047 - def setDigest(self, idpackage, digest):
2048 """ 2049 Set package file md5sum for package. This information is used 2050 by entropy.client when downloading packages. 2051 2052 @param idpackage: package indentifier 2053 @type idpackage: int 2054 @param digest: md5 hash for package file 2055 @type digest: string 2056 """ 2057 with self.__write_mutex: 2058 self.cursor.execute(""" 2059 UPDATE extrainfo SET digest = (?) WHERE idpackage = (?) 2060 """, (digest, idpackage,)) 2061 self.commitChanges()
2062
2063 - def setSignatures(self, idpackage, sha1, sha256, sha512):
2064 """ 2065 Set package file extra hashes (sha1, sha256, sha512) for package. 2066 2067 @param idpackage: package indentifier 2068 @type idpackage: int 2069 @param sha1: SHA1 hash for package file 2070 @type sha1: string 2071 @param sha256: SHA256 hash for package file 2072 @type sha256: string 2073 @param sha512: SHA512 hash for package file 2074 @type sha512: string 2075 """ 2076 with self.__write_mutex: 2077 self.cursor.execute(""" 2078 UPDATE packagesignatures SET sha1 = (?), sha256 = (?), sha512 = (?) 2079 WHERE idpackage = (?) 2080 """, (sha1, sha256, sha512, idpackage))
2081
2082 - def setDownloadURL(self, idpackage, url):
2083 """ 2084 Set download URL prefix for package. 2085 2086 @param idpackage: package indentifier 2087 @type idpackage: int 2088 @param url: URL prefix to set 2089 @type url: string 2090 """ 2091 with self.__write_mutex: 2092 self.cursor.execute(""" 2093 UPDATE extrainfo SET download = (?) WHERE idpackage = (?) 2094 """, (url, idpackage,)) 2095 self.commitChanges()
2096
2097 - def setCategory(self, idpackage, category):
2098 """ 2099 Set category name for package. 2100 2101 @param idpackage: package indentifier 2102 @type idpackage: int 2103 @param category: category to set 2104 @type category: string 2105 """ 2106 # create new category if it doesn't exist 2107 catid = self.isCategoryAvailable(category) 2108 if catid is -1: 2109 # create category 2110 catid = self.addCategory(category) 2111 2112 with self.__write_mutex: 2113 self.cursor.execute(""" 2114 UPDATE baseinfo SET idcategory = (?) WHERE idpackage = (?) 2115 """, (catid, idpackage,)) 2116 self.commitChanges()
2117
2118 - def setCategoryDescription(self, category, description_data):
2119 """ 2120 Set description for given category name. 2121 2122 @param category: category name 2123 @type category: string 2124 @param description_data: category description for several locales. 2125 {'en': "This is blah", 'it': "Questo e' blah", ... } 2126 @type description_data: dict 2127 """ 2128 with self.__write_mutex: 2129 2130 self.cursor.execute(""" 2131 DELETE FROM categoriesdescription WHERE category = (?) 2132 """, (category,)) 2133 for locale in description_data: 2134 mydesc = description_data[locale] 2135 self.cursor.execute(""" 2136 INSERT INTO categoriesdescription VALUES (?,?,?) 2137 """, (category, locale, mydesc,)) 2138 2139 self.commitChanges()
2140
2141 - def setName(self, idpackage, name):
2142 """ 2143 Set name for package. 2144 2145 @param idpackage: package indentifier 2146 @type idpackage: int 2147 @param name: package name 2148 @type name: string 2149 2150 """ 2151 with self.__write_mutex: 2152 self.cursor.execute(""" 2153 UPDATE baseinfo SET name = (?) WHERE idpackage = (?) 2154 """, (name, idpackage,)) 2155 self.commitChanges()
2156
2157 - def setDependency(self, iddependency, dependency):
2158 """ 2159 Set dependency string for iddependency (dependency identifier). 2160 2161 @param iddependency: dependency string identifier 2162 @type iddependency: int 2163 @param dependency: dependency string 2164 @type dependency: string 2165 """ 2166 with self.__write_mutex: 2167 self.cursor.execute(""" 2168 UPDATE dependenciesreference SET dependency = (?) 2169 WHERE iddependency = (?) 2170 """, (dependency, iddependency,)) 2171 self.commitChanges()
2172
2173 - def setAtom(self, idpackage, atom):
2174 """ 2175 Set atom string for package. "Atom" is the full, unique name of 2176 a package. 2177 2178 @param idpackage: package indentifier 2179 @type idpackage: int 2180 @param atom: atom string 2181 @type atom: string 2182 """ 2183 with self.__write_mutex: 2184 self.cursor.execute(""" 2185 UPDATE baseinfo SET atom = (?) WHERE idpackage = (?) 2186 """, (atom, idpackage,)) 2187 self.commitChanges()
2188
2189 - def setSlot(self, idpackage, slot):
2190 """ 2191 Set slot string for package. Please refer to Portage SLOT documentation 2192 for more info. 2193 2194 @param idpackage: package indentifier 2195 @type idpackage: int 2196 @param slot: slot string 2197 @type slot: string 2198 """ 2199 with self.__write_mutex: 2200 self.cursor.execute(""" 2201 UPDATE baseinfo SET slot = (?) WHERE idpackage = (?) 2202 """, (slot, idpackage,)) 2203 self.commitChanges()
2204
2205 - def removeLicensedata(self, license_name):
2206 """ 2207 Remove license text for given license name identifier. 2208 2209 @param license_name: available license name identifier 2210 @type license_name: string 2211 """ 2212 with self.__write_mutex: 2213 self.cursor.execute(""" 2214 DELETE FROM licensedata WHERE licensename = (?) 2215 """, (license_name,))
2216
2217 - def removeDependencies(self, idpackage):
2218 """ 2219 Remove all the dependencies of package. 2220 2221 @param idpackage: package indentifier 2222 @type idpackage: int 2223 """ 2224 with self.__write_mutex: 2225 self.cursor.execute(""" 2226 DELETE FROM dependencies WHERE idpackage = (?) 2227 """, (idpackage,)) 2228 self.commitChanges()
2229
2230 - def insertDependencies(self, idpackage, depdata):
2231 """ 2232 Insert dependencies for package. "depdata" is a dict() with dependency 2233 strings as keys and dependency type as values. 2234 2235 @param idpackage: package indentifier 2236 @type idpackage: int 2237 @param depdata: dependency dictionary 2238 {'app-foo/foo': dep_type_integer, ...} 2239 @type depdata: dict 2240 """ 2241 2242 dcache = set() 2243 add_dep = self.addDependency 2244 is_dep_avail = self.isDependencyAvailable 2245 def mymf(dep): 2246 2247 if dep in dcache: 2248 return 0 2249 iddep = is_dep_avail(dep) 2250 if iddep is -1: 2251 iddep = add_dep(dep) 2252 2253 deptype = 0 2254 if isinstance(depdata, dict): 2255 deptype = depdata[dep] 2256 2257 dcache.add(dep) 2258 return (idpackage, iddep, deptype,)
2259 2260 deps = (x for x in map(mymf, depdata) if type(x) != int) 2261 with self.__write_mutex: 2262 self.cursor.executemany(""" 2263 INSERT into dependencies VALUES (?,?,?) 2264 """, deps) 2265
2266 - def insertManualDependencies(self, idpackage, manual_deps):
2267 """ 2268 Insert manually added dependencies to dep. list of package. 2269 2270 @param idpackage: package indentifier 2271 @type idpackage: int 2272 @param manual_deps: list of dependency strings 2273 @type manual_deps: list 2274 """ 2275 mydict = {} 2276 for manual_dep in manual_deps: 2277 mydict[manual_dep] = etpConst['spm']['mdepend_id'] 2278 return self.insertDependencies(idpackage, mydict)
2279
2280 - def removeContent(self, idpackage):
2281 """ 2282 Remove content metadata for package. 2283 2284 @param idpackage: package indentifier 2285 @type idpackage: int 2286 """ 2287 with self.__write_mutex: 2288 self.cursor.execute("DELETE FROM content WHERE idpackage = (?)", (idpackage,)) 2289 self.commitChanges()
2290
2291 - def insertContent(self, idpackage, content, already_formatted = False):
2292 """ 2293 Insert content metadata for package. "content" can either be a dict() 2294 or a list of triples (tuples of length 3, (idpackage, path, type,)). 2295 2296 @param idpackage: package indentifier 2297 @type idpackage: int 2298 @param content: content metadata to insert. 2299 {'/path/to/foo': 'obj(content type)',} 2300 or 2301 [(idpackage, path, type,) ...] 2302 @type content: dict, list 2303 @keyword already_formatted: if True, "content" is expected to be 2304 already formatted for insertion, this means that "content" must be 2305 a list of tuples of length 3. 2306 @type already_formatted: bool 2307 """ 2308 2309 with self.__write_mutex: 2310 2311 if already_formatted: 2312 self.cursor.executemany(""" 2313 INSERT INTO content VALUES (?,?,?) 2314 """, ((idpackage, x, y,) for a, x, y in content)) 2315 return 2316 2317 def my_cmap(xfile): 2318 return (idpackage, xfile, content[xfile],)
2319 2320 self.cursor.executemany(""" 2321 INSERT INTO content VALUES (?,?,?) 2322 """, map(my_cmap, content)) 2323
2324 - def insertNeededPaths(self, library, paths):
2325 """ 2326 Insert paths where given ELF obj (library) name can be located. 2327 "library" is an ELF object name. 2328 2329 @param library: library name 2330 @type library: string 2331 @param paths: list of paths (list of strings) 2332 @type paths: list 2333 """ 2334 with self.__write_mutex: 2335 self.cursor.executemany(""" 2336 INSERT OR IGNORE INTO neededlibrarypaths VALUES (?,?,?) 2337 """, ((library, path, elfclass,) for path, elfclass in paths))
2338
2339 - def insertAutomergefiles(self, idpackage, automerge_data):
2340 """ 2341 Insert configuration files automerge information for package. 2342 "automerge_data" contains configuration files paths and their belonging 2343 md5 hash. 2344 This features allows entropy.client to "auto-merge" or "auto-remove" 2345 configuration files never touched by user. 2346 2347 @param idpackage: package indentifier 2348 @type idpackage: int 2349 @param automerge_data: list of tuples of length 2. 2350 [('/path/to/conf/file', 'md5_checksum_string',) ... ] 2351 @type automerge_data: list 2352 """ 2353 with self.__write_mutex: 2354 self.cursor.executemany('INSERT INTO automergefiles VALUES (?,?,?)', 2355 ((idpackage, x, y,) for x, y in automerge_data))
2356
2357 - def removeAutomergefiles(self, idpackage):
2358 """ 2359 Remove configuration files automerge information for package. 2360 "automerge_data" contains configuration files paths and their belonging 2361 md5 hash. 2362 This features allows entropy.client to "auto-merge" or "auto-remove" 2363 configuration files never touched by user. 2364 2365 @param idpackage: package indentifier 2366 @type idpackage: int 2367 """ 2368 with self.__write_mutex: 2369 self.cursor.execute(""" 2370 DELETE FROM automergefiles WHERE idpackage = (?) 2371 """, (idpackage,))
2372
2373 - def removeSignatures(self, idpackage):
2374 """ 2375 Remove extra package file hashes (SHA1, SHA256, SHA512) for package. 2376 Entropy package files metadata contains up to 4 hashes: 2377 md5, sha1, sha256, sha512 2378 While md5 is here for historical reasons (being the first supported) 2379 sha1, sha256, sha512 have been added recently and located into a 2380 separate database table called "packagesignatures". Such hashes 2381 can be not available for older packages, so don't be scared, aliens 2382 are not to blame. 2383 2384 @param idpackage: package indentifier 2385 @type idpackage: int 2386 """ 2387 with self.__write_mutex: 2388 self.cursor.execute(""" 2389 DELETE FROM packagesignatures WHERE idpackage = (?) 2390 """, (idpackage,))
2391
2392 - def removeSpmPhases(self, idpackage):
2393 """ 2394 Remove Source Package Manager phases for package. 2395 Entropy can call several Source Package Manager (the PM which Entropy 2396 relies on) package installation/removal phases. 2397 Such phase names are listed here. 2398 2399 @param idpackage: package indentifier 2400 @type idpackage: int 2401 """ 2402 with self.__write_mutex: 2403 self.cursor.execute(""" 2404 DELETE FROM packagespmphases WHERE idpackage = (?) 2405 """, (idpackage,))
2406
2407 - def insertChangelog(self, category, name, changelog_txt):
2408 """ 2409 Insert package changelog for package (in this case using category + 2410 name as key). 2411 2412 @param category: package category 2413 @type category: string 2414 @param name: package name 2415 @type name: string 2416 @param changelog_txt: changelog text 2417 @type changelog_txt: string 2418 """ 2419 with self.__write_mutex: 2420 2421 mytxt = changelog_txt.encode('raw_unicode_escape') 2422 2423 self.cursor.execute(""" 2424 DELETE FROM packagechangelogs WHERE category = (?) AND name = (?) 2425 """, (category, name,)) 2426 2427 self.cursor.execute(""" 2428 INSERT INTO packagechangelogs VALUES (?,?,?) 2429 """, (category, name, buffer(mytxt),))
2430
2431 - def removeChangelog(self, category, name):
2432 """ 2433 Remove ChangeLog for package (in this case using category + name as key) 2434 2435 @param category: package category 2436 @type category: string 2437 @param name: package name 2438 @type name: string 2439 """ 2440 with self.__write_mutex: 2441 self.cursor.execute(""" 2442 DELETE FROM packagechangelogs WHERE category = (?) AND name = (?) 2443 """, (category, name,))
2444
2445 - def insertLicenses(self, licenses_data):
2446 """ 2447 insert license data (license names and text) into repository. 2448 2449 @param licenses_data: dictionary containing license names as keys and 2450 text as values 2451 @type licenses_data: dict 2452 """ 2453 2454 mylicenses = licenses_data.keys() 2455 def my_mf(mylicense): 2456 return not self.isLicensedataKeyAvailable(mylicense)
2457 2458 def my_mm(mylicense): 2459 2460 lic_data = licenses_data.get(mylicense, '') 2461 2462 # support both utf8 and str input 2463 if isinstance(lic_data, unicode): # encode to str 2464 try: 2465 lic_data = lic_data.encode('raw_unicode_escape') 2466 except (UnicodeDecodeError,): 2467 lic_data = lic_data.encode('utf-8') 2468 2469 return (mylicense, buffer(lic_data), 0,) 2470 2471 with self.__write_mutex: 2472 self.cursor.executemany(""" 2473 INSERT into licensedata VALUES (?,?,?) 2474 """, map(my_mm, list(set(filter(my_mf, mylicenses))))) 2475
2476 - def insertConfigProtect(self, idpackage, idprotect, mask = False):
2477 """ 2478 Insert CONFIG_PROTECT (configuration files protection) entry identifier 2479 for package. This entry is usually a space separated string of directory 2480 and files which are used to handle user-protected configuration files 2481 or directories, those that are going to be stashed in separate paths 2482 waiting for user merge decisions. 2483 2484 @param idpackage: package indentifier 2485 @type idpackage: int 2486 @param idprotect: configuration files protection identifier 2487 @type idprotect: int 2488 @keyword mask: if True, idproctect will be considered a "mask" entry, 2489 meaning that configuration files starting with paths referenced 2490 by idprotect will be forcefully merged. 2491 @type mask: bool 2492 """ 2493 2494 mytable = 'configprotect' 2495 if mask: 2496 mytable += 'mask' 2497 with self.__write_mutex: 2498 self.cursor.execute(""" 2499 INSERT into %s VALUES (?,?) 2500 """ % (mytable,), (idpackage, idprotect,))
2501
2502 - def insertMirrors(self, mirrors):
2503 """ 2504 Insert list of "mirror name" and "mirror list" into repository. 2505 The term "mirror" in this case references to Source Package Manager 2506 package download mirrors. 2507 Argument format is like this for historical reasons and may change in 2508 future. 2509 2510 @todo: change argument format 2511 @param mirrors: list of tuples of length 2 containing string as first 2512 item and list as second. 2513 [('openoffice', ['http://openoffice1', 'http://..."],), ...] 2514 @type mirrors: list 2515 """ 2516 2517 for mirrorname, mirrorlist in mirrors: 2518 # remove old 2519 self.removeMirrorEntries(mirrorname) 2520 # add new 2521 self.addMirrors(mirrorname, mirrorlist)
2522
2523 - def insertKeywords(self, idpackage, keywords):
2524 """ 2525 Insert keywords for package. Keywords are strings contained in package 2526 metadata stating what architectures or subarchitectures are supported 2527 by package. It is historically used also for masking packages (making 2528 them not available). 2529 2530 @param idpackage: package indentifier 2531 @type idpackage: int 2532 @param keywords: list of keywords 2533 @type keywords: list 2534 """ 2535 2536 def mymf(key): 2537 idkeyword = self.isKeywordAvailable(key) 2538 if idkeyword is -1: 2539 # create category 2540 idkeyword = self.addKeyword(key) 2541 return (idpackage, idkeyword,)
2542 2543 with self.__write_mutex: 2544 self.cursor.executemany(""" 2545 INSERT into keywords VALUES (?,?) 2546 """, map(mymf, keywords)) 2547
2548 - def insertUseflags(self, idpackage, useflags):
2549 """ 2550 Insert Source Package Manager USE (components build) flags for package. 2551 2552 @param idpackage: package indentifier 2553 @type idpackage: int 2554 @param useflags: list of use flags strings 2555 @type useflags: list 2556 """ 2557 2558 def mymf(flag): 2559 iduseflag = self.isUseflagAvailable(flag) 2560 if iduseflag is -1: 2561 # create category 2562 iduseflag = self.addUseflag(flag) 2563 return (idpackage, iduseflag,)
2564 2565 with self.__write_mutex: 2566 self.cursor.executemany(""" 2567 INSERT into useflags VALUES (?,?) 2568 """, map(mymf, useflags)) 2569
2570 - def insertSignatures(self, idpackage, sha1, sha256, sha512):
2571 """ 2572 Insert package file extra hashes (sha1, sha256, sha512) for package. 2573 2574 @param idpackage: package indentifier 2575 @type idpackage: int 2576 @param sha1: SHA1 hash for package file 2577 @type sha1: string 2578 @param sha256: SHA256 hash for package file 2579 @type sha256: string 2580 @param sha512: SHA512 hash for package file 2581 @type sha512: string 2582 """ 2583 with self.__write_mutex: 2584 self.cursor.execute(""" 2585 INSERT INTO packagesignatures VALUES (?,?,?,?) 2586 """, (idpackage, sha1, sha256, sha512))
2587
2588 - def insertSpmPhases(self, idpackage, phases):
2589 """ 2590 Insert Source Package Manager phases for package. 2591 Entropy can call several Source Package Manager (the PM which Entropy 2592 relies on) package installation/removal phases. 2593 Such phase names are listed here. 2594 2595 @param idpackage: package indentifier 2596 @type idpackage: int 2597 @param phases: list of available Source Package Manager phases 2598 @type phases: list 2599 """ 2600 with self.__write_mutex: 2601 self.cursor.execute(""" 2602 INSERT INTO packagespmphases VALUES (?,?) 2603 """, (idpackage,phases,))
2604
2605 - def insertSources(self, idpackage, sources):
2606 """ 2607 Insert source code package download URLs for idpackage. 2608 2609 @param idpackage: package indentifier 2610 @type idpackage: int 2611 @param sources: list of source URLs 2612 @type sources: list 2613 """ 2614 def mymf(source): 2615 2616 if (not source) or (source == "") or \ 2617 (not self.entropyTools.is_valid_string(source)): 2618 return 0 2619 2620 idsource = self.isSourceAvailable(source) 2621 if idsource is -1: 2622 idsource = self.addSource(source) 2623 2624 return (idpackage, idsource,)
2625 2626 with self.__write_mutex: 2627 self.cursor.executemany(""" 2628 INSERT into sources VALUES (?,?) 2629 """, (x for x in map(mymf, sources) if x is not 0)) 2630
2631 - def insertConflicts(self, idpackage, conflicts):
2632 """ 2633 Insert dependency conflicts for package. 2634 2635 @param idpackage: package indentifier 2636 @type idpackage: int 2637 @param conflicts: list of dep. conflicts 2638 @type conflicts: list 2639 """ 2640 2641 def mymf(conflict): 2642 return (idpackage, conflict,)
2643 2644 with self.__write_mutex: 2645 self.cursor.executemany(""" 2646 INSERT into conflicts VALUES (?,?) 2647 """, map(mymf, conflicts)) 2648
2649 - def insertMessages(self, idpackage, messages):
2650 """ 2651 Insert user messages for package. 2652 2653 @param idpackage: package indentifier 2654 @type idpackage: int 2655 @param messages: list of messages 2656 @type messages: list 2657 """ 2658 def mymf(message): 2659 return (idpackage, message,)
2660 2661 with self.__write_mutex: 2662 self.cursor.executemany(""" 2663 INSERT into messages VALUES (?,?) 2664 """, map(mymf, messages)) 2665
2666 - def insertProvide(self, idpackage, provides):
2667 """ 2668 docstring_title 2669 2670 @param idpackage: package indentifier 2671 @type idpackage: int 2672 @param provides: 2673 @type provides: 2674 @return: 2675 @rtype: 2676 2677 """ 2678 2679 def myiter(): 2680 for atom in provides: 2681 yield (idpackage, atom,)
2682 2683 with self.__write_mutex: 2684 self.cursor.executemany('INSERT into provide VALUES (?,?)', myiter()) 2685
2686 - def insertNeeded(self, idpackage, neededs):
2687 """ 2688 docstring_title 2689 2690 @param idpackage: package indentifier 2691 @type idpackage: int 2692 @param neededs: 2693 @type neededs: 2694 @return: 2695 @rtype: 2696 2697 """ 2698 2699 mydata = set() 2700 for needed, elfclass in neededs: 2701 idneeded = self.isNeededAvailable(needed) 2702 if idneeded is -1: 2703 # create eclass 2704 idneeded = self.addNeeded(needed) 2705 mydata.add((idpackage, idneeded, elfclass)) 2706 2707 with self.__write_mutex: 2708 self.cursor.executemany('INSERT into needed VALUES (?,?,?)', mydata)
2709
2710 - def insertEclasses(self, idpackage, eclasses):
2711 """ 2712 docstring_title 2713 2714 @param idpackage: package indentifier 2715 @type idpackage: int 2716 @param eclasses: 2717 @type eclasses: 2718 @return: 2719 @rtype: 2720 2721 """ 2722 2723 mydata = set() 2724 for eclass in eclasses: 2725 idclass = self.isEclassAvailable(eclass) 2726 if (idclass is -1): 2727 # create eclass 2728 idclass = self.addEclass(eclass) 2729 mydata.add((idpackage, idclass,)) 2730 2731 with self.__write_mutex: 2732 self.cursor.executemany('INSERT into eclasses VALUES (?,?)', mydata)
2733
2734 - def insertOnDiskSize(self, idpackage, mysize):
2735 """ 2736 docstring_title 2737 2738 @param idpackage: package indentifier 2739 @type idpackage: int 2740 @param mysize: 2741 @type mysize: 2742 @return: 2743 @rtype: 2744 2745 """ 2746 with self.__write_mutex: 2747 self.cursor.execute('INSERT into sizes VALUES (?,?)', (idpackage, mysize,))
2748
2749 - def insertTrigger(self, idpackage, trigger):
2750 """ 2751 docstring_title 2752 2753 @param idpackage: package indentifier 2754 @type idpackage: int 2755 @param trigger: 2756 @type trigger: 2757 @return: 2758 @rtype: 2759 2760 """ 2761 with self.__write_mutex: 2762 self.cursor.execute('INSERT into triggers VALUES (?,?)', (idpackage, buffer(trigger),))
2763
2764 - def insertBranchMigration(self, repository, from_branch, to_branch, 2765 post_migration_md5sum, post_upgrade_md5sum):
2766 """ 2767 2768 """ 2769 with self.__write_mutex: 2770 self.cursor.execute(""" 2771 INSERT OR REPLACE INTO entropy_branch_migration VALUES (?,?,?,?,?) 2772 """, ( 2773 repository, from_branch, 2774 to_branch, post_migration_md5sum, 2775 post_upgrade_md5sum, 2776 ) 2777 )
2778
2779 - def setBranchMigrationPostUpgradeMd5sum(self, repository, from_branch, 2780 to_branch, post_upgrade_md5sum):
2781 """ 2782 2783 """ 2784 with self.__write_mutex: 2785 self.cursor.execute(""" 2786 UPDATE entropy_branch_migration SET post_upgrade_md5sum = (?) WHERE 2787 repository = (?) AND from_branch = (?) AND to_branch = (?) 2788 """, (post_upgrade_md5sum, repository, from_branch, to_branch,))
2789 2790
2791 - def insertPortageCounter(self, idpackage, counter, branch, injected):
2792 """ 2793 docstring_title 2794 2795 @param idpackage: package indentifier 2796 @type idpackage: int 2797 @param counter: 2798 @type counter: 2799 @param branch: 2800 @type branch: 2801 @param injected: 2802 @type injected: 2803 @return: 2804 @rtype: 2805 2806 """ 2807 2808 if (counter != -1) and not injected: 2809 2810 if counter <= -2: 2811 # special cases 2812 counter = self.getNewNegativeCounter() 2813 2814 with self.__write_mutex: 2815 try: 2816 self.cursor.execute( 2817 'INSERT into counters VALUES ' 2818 '(?,?,?)' 2819 , ( counter, 2820 idpackage, 2821 branch, 2822 ) 2823 ) 2824 except self.dbapi2.IntegrityError: 2825 # we have a PRIMARY KEY we need to remove 2826 self._migrateCountersTable() 2827 self.cursor.execute( 2828 'INSERT into counters VALUES ' 2829 '(?,?,?)' 2830 , ( counter, 2831 idpackage, 2832 branch, 2833 ) 2834 ) 2835 except: 2836 if self.dbname == etpConst['clientdbid']: 2837 # force only for client database 2838 if self.doesTableExist("counters"): 2839 raise 2840 self.cursor.execute( 2841 'INSERT into counters VALUES ' 2842 '(?,?,?)' 2843 , ( counter, 2844 idpackage, 2845 branch, 2846 ) 2847 ) 2848 elif self.dbname.startswith(etpConst['serverdbid']): 2849 raise 2850 2851 return counter
2852
2853 - def insertCounter(self, idpackage, counter, branch = None):
2854 """ 2855 docstring_title 2856 2857 @param idpackage: package indentifier 2858 @type idpackage: int 2859 @param counter: 2860 @type counter: 2861 @keyword branch: 2862 @type branch: 2863 @return: 2864 @rtype: 2865 2866 """ 2867 if not branch: branch = self.db_branch 2868 if not branch: branch = self.SystemSettings['repositories']['branch'] 2869 with self.__write_mutex: 2870 self.cursor.execute(""" 2871 DELETE FROM counters 2872 WHERE (counter = (?) OR 2873 idpackage = (?)) AND 2874 branch = (?)""", (counter, idpackage, branch,)) 2875 self.cursor.execute('INSERT INTO counters VALUES (?,?,?)', (counter, idpackage, branch,)) 2876 self.commitChanges()
2877
2878 - def setTrashedCounter(self, counter):
2879 """ 2880 docstring_title 2881 2882 @param counter: 2883 @type counter: 2884 @return: 2885 @rtype: 2886 2887 """ 2888 with self.__write_mutex: 2889 self.cursor.execute('DELETE FROM trashedcounters WHERE counter = (?)', (counter,)) 2890 self.cursor.execute('INSERT INTO trashedcounters VALUES (?)', (counter,)) 2891 self.commitChanges()
2892
2893 - def setCounter(self, idpackage, counter, branch = None):
2894 """ 2895 docstring_title 2896 2897 @param idpackage: package indentifier 2898 @type idpackage: int 2899 @param counter: 2900 @type counter: 2901 @keyword branch: 2902 @type branch: 2903 @return: 2904 @rtype: 2905 2906 """ 2907 2908 branchstring = '' 2909 insertdata = [counter, idpackage] 2910 if branch: 2911 branchstring = ', branch = (?)' 2912 insertdata.insert(1, branch) 2913 2914 with self.__write_mutex: 2915 try: 2916 self.cursor.execute('UPDATE counters SET counter = (?) '+branchstring+' WHERE idpackage = (?)', insertdata) 2917 self.commitChanges() 2918 except: 2919 if self.dbname == etpConst['clientdbid']: 2920 raise
2921
2922 - def contentDiff(self, idpackage, dbconn, dbconn_idpackage):
2923 """ 2924 docstring_title 2925 2926 @param idpackage: package indentifier 2927 @type idpackage: int 2928 @param dbconn: 2929 @type dbconn: 2930 @param dbconn_idpackage: 2931 @type dbconn_idpackage: 2932 @return: 2933 @rtype: 2934 2935 """ 2936 self.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 2937 # create a random table and fill 2938 randomtable = "cdiff%s" % (self.entropyTools.get_random_number(),) 2939 while self.doesTableExist(randomtable): 2940 randomtable = "cdiff%s" % (self.entropyTools.get_random_number(),) 2941 self.cursor.execute('CREATE TEMPORARY TABLE %s ( file VARCHAR )' % (randomtable,)) 2942 2943 try: 2944 dbconn.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 2945 dbconn.cursor.execute('select file from content where idpackage = (?)', (dbconn_idpackage,)) 2946 xfile = dbconn.cursor.fetchone() 2947 while xfile: 2948 self.cursor.execute('INSERT INTO %s VALUES (?)' % (randomtable,), (xfile[0],)) 2949 xfile = dbconn.cursor.fetchone() 2950 2951 # now compare 2952 cur = self.cursor.execute(""" 2953 SELECT file FROM content 2954 WHERE content.idpackage = (?) AND 2955 content.file NOT IN (SELECT file from %s)""" % (randomtable,), (idpackage,)) 2956 diff = self.fetchall2set(cur.fetchall()) 2957 return diff 2958 finally: 2959 self.cursor.execute('DROP TABLE IF EXISTS %s' % (randomtable,))
2960
2961 - def doCleanups(self):
2962 """ 2963 docstring_title 2964 2965 @return: 2966 @rtype: 2967 2968 """ 2969 self.cleanupUseflags() 2970 self.cleanupSources() 2971 self.cleanupEclasses() 2972 self.cleanupNeeded() 2973 self.cleanupNeededPaths() 2974 self.cleanupDependencies() 2975 self.cleanupChangelogs()
2976
2977 - def cleanupUseflags(self):
2978 """ 2979 docstring_title 2980 2981 @return: 2982 @rtype: 2983 2984 """ 2985 with self.__write_mutex: 2986 self.cursor.execute(""" 2987 DELETE FROM useflagsreference 2988 WHERE idflag NOT IN (SELECT idflag FROM useflags)""")
2989
2990 - def cleanupSources(self):
2991 """ 2992 docstring_title 2993 2994 @return: 2995 @rtype: 2996 2997 """ 2998 with self.__write_mutex: 2999 self.cursor.execute(""" 3000 DELETE FROM sourcesreference 3001 WHERE idsource NOT IN (SELECT idsource FROM sources)""")
3002
3003 - def cleanupEclasses(self):
3004 """ 3005 docstring_title 3006 3007 @return: 3008 @rtype: 3009 3010 """ 3011 with self.__write_mutex: 3012 self.cursor.execute(""" 3013 DELETE FROM eclassesreference 3014 WHERE idclass NOT IN (SELECT idclass FROM eclasses)""")
3015
3016 - def cleanupNeeded(self):
3017 """ 3018 docstring_title 3019 3020 @return: 3021 @rtype: 3022 3023 """ 3024 with self.__write_mutex: 3025 self.cursor.execute(""" 3026 DELETE FROM neededreference 3027 WHERE idneeded NOT IN (SELECT idneeded FROM needed)""")
3028
3029 - def cleanupNeededPaths(self):
3030 """ 3031 docstring_title 3032 3033 @return: 3034 @rtype: 3035 3036 """ 3037 with self.__write_mutex: 3038 self.cursor.execute(""" 3039 DELETE FROM neededlibrarypaths 3040 WHERE library NOT IN (SELECT library FROM neededreference)""")
3041
3042 - def cleanupDependencies(self):
3043 """ 3044 docstring_title 3045 3046 @return: 3047 @rtype: 3048 3049 """ 3050 with self.__write_mutex: 3051 self.cursor.execute(""" 3052 DELETE FROM dependenciesreference 3053 WHERE iddependency NOT IN (SELECT iddependency FROM dependencies)""")
3054
3055 - def cleanupChangelogs(self):
3056 """ 3057 docstring_title 3058 3059 @return: 3060 @rtype: 3061 3062 """ 3063 with self.__write_mutex: 3064 self.cursor.execute(""" 3065 DELETE FROM packagechangelogs 3066 WHERE category || "/" || name NOT IN 3067 (SELECT categories.category || "/" || baseinfo.name FROM baseinfo,categories 3068 WHERE baseinfo.idcategory = categories.idcategory 3069 )""")
3070
3071 - def getNewNegativeCounter(self):
3072 """ 3073 docstring_title 3074 3075 @return: 3076 @rtype: 3077 3078 """ 3079 counter = -2 3080 try: 3081 cur = self.cursor.execute('SELECT min(counter) FROM counters') 3082 dbcounter = cur.fetchone() 3083 mycounter = 0 3084 if dbcounter: 3085 mycounter = dbcounter[0] 3086 3087 if mycounter >= -1: 3088 counter = -2 3089 else: 3090 counter = mycounter-1 3091 3092 except: 3093 pass 3094 return counter
3095
3096 - def getApi(self):
3097 """ 3098 docstring_title 3099 3100 @return: 3101 @rtype: 3102 3103 """ 3104 cur = self.cursor.execute('SELECT max(etpapi) FROM baseinfo') 3105 api = cur.fetchone() 3106 if api: api = api[0] 3107 else: api = -1 3108 return api
3109
3110 - def getCategory(self, idcategory):
3111 cur = self.cursor.execute(""" 3112 SELECT category from categories WHERE idcategory = (?) 3113 """, (idcategory,)) 3114 cat = cur.fetchone() 3115 if cat: 3116 cat = cat[0] 3117 return cat
3118
3119 - def get_category_description_from_disk(self, category):
3120 """ 3121 docstring_title 3122 3123 @param category: 3124 @type category: 3125 @return: 3126 @rtype: 3127 3128 """ 3129 return get_spm(self).get_category_description_data(category)
3130
3131 - def getIDPackage(self, atom, branch = None):
3132 """ 3133 docstring_title 3134 3135 @param atom: 3136 @type atom: 3137 @keyword branch: 3138 @type branch: 3139 @return: 3140 @rtype: 3141 3142 """ 3143 branch_string = '' 3144 params = [atom] 3145 if branch: 3146 branch_string = ' AND branch = (?)' 3147 params.append(branch) 3148 cur = self.cursor.execute(""" 3149 SELECT idpackage FROM baseinfo WHERE atom = (?) 3150 """ + branch_string, params) 3151 idpackage = cur.fetchone() 3152 if idpackage: 3153 return idpackage[0] 3154 return -1
3155
3156 - def getIDPackageFromDownload(self, download_relative_path, 3157 endswith = False):
3158 if endswith: 3159 cur = self.cursor.execute(""" 3160 SELECT baseinfo.idpackage FROM baseinfo,extrainfo 3161 WHERE extrainfo.download LIKE (?) AND 3162 baseinfo.idpackage = extrainfo.idpackage 3163 """, ("%"+download_relative_path,)) 3164 else: 3165 cur = self.cursor.execute(""" 3166 SELECT baseinfo.idpackage FROM baseinfo,extrainfo 3167 WHERE extrainfo.download = (?) AND 3168 baseinfo.idpackage = extrainfo.idpackage 3169 """, (download_relative_path,)) 3170 idpackage = cur.fetchone() 3171 if idpackage: return idpackage[0] 3172 return -1
3173
3174 - def getIDPackagesFromFile(self, file):
3175 cur = self.cursor.execute(""" 3176 SELECT idpackage FROM content WHERE file = (?) 3177 """, (file,)) 3178 return self.fetchall2list(cur.fetchall())
3179
3180 - def getIDCategory(self, category):
3181 """ 3182 docstring_title 3183 3184 @param category: 3185 @type category: 3186 @return: 3187 @rtype: 3188 3189 """ 3190 self.cursor.execute('SELECT "idcategory" FROM categories WHERE category = (?)', (category,)) 3191 idcat = self.cursor.fetchone() 3192 if idcat: return idcat[0] 3193 return -1
3194
3195 - def getVersioningData(self, idpackage):
3196 """ 3197 docstring_title 3198 3199 @param idpackage: package indentifier 3200 @type idpackage: int 3201 @return: 3202 @rtype: 3203 3204 """ 3205 self.cursor.execute('SELECT version,versiontag,revision FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 3206 return self.cursor.fetchone()
3207
3208 - def getStrictData(self, idpackage):
3209 self.cursor.execute(""" 3210 SELECT categories.category || "/" || baseinfo.name, 3211 baseinfo.slot,baseinfo.version,baseinfo.versiontag, 3212 baseinfo.revision,baseinfo.atom FROM baseinfo,categories 3213 WHERE baseinfo.idpackage = (?) AND 3214 baseinfo.idcategory = categories.idcategory""", (idpackage,)) 3215 return self.cursor.fetchone()
3216
3217 - def getStrictScopeData(self, idpackage):
3218 self.cursor.execute(""" 3219 SELECT atom,slot,revision FROM baseinfo 3220 WHERE idpackage = (?)""", (idpackage,)) 3221 rslt = self.cursor.fetchone() 3222 return rslt
3223
3224 - def getScopeData(self, idpackage):
3225 self.cursor.execute(""" 3226 SELECT 3227 baseinfo.atom, 3228 categories.category, 3229 baseinfo.name, 3230 baseinfo.version, 3231 baseinfo.slot, 3232 baseinfo.versiontag, 3233 baseinfo.revision, 3234 baseinfo.branch, 3235 baseinfo.etpapi 3236 FROM 3237 baseinfo, 3238 categories 3239 WHERE 3240 baseinfo.idpackage = (?) 3241 and baseinfo.idcategory = categories.idcategory 3242 """, (idpackage,)) 3243 return self.cursor.fetchone()
3244
3245 - def getBaseData(self, idpackage):
3246 3247 sql = """ 3248 SELECT 3249 baseinfo.atom, 3250 baseinfo.name, 3251 baseinfo.version, 3252 baseinfo.versiontag, 3253 extrainfo.description, 3254 categories.category, 3255 flags.chost, 3256 flags.cflags, 3257 flags.cxxflags, 3258 extrainfo.homepage, 3259 licenses.license, 3260 baseinfo.branch, 3261 extrainfo.download, 3262 extrainfo.digest, 3263 baseinfo.slot, 3264 baseinfo.etpapi, 3265 extrainfo.datecreation, 3266 extrainfo.size, 3267 baseinfo.revision 3268 FROM 3269 baseinfo, 3270 extrainfo, 3271 categories, 3272 flags, 3273 licenses 3274 WHERE 3275 baseinfo.idpackage = (?) 3276 and baseinfo.idpackage = extrainfo.idpackage 3277 and baseinfo.idcategory = categories.idcategory 3278 and extrainfo.idflags = flags.idflags 3279 and baseinfo.idlicense = licenses.idlicense 3280 """ 3281 self.cursor.execute(sql, (idpackage,)) 3282 return self.cursor.fetchone()
3283
3284 - def getTriggerInfo(self, idpackage, content = True):
3285 """ 3286 docstring_title 3287 3288 @param idpackage: package indentifier 3289 @type idpackage: int 3290 @keyword content: 3291 @type content: 3292 @return: 3293 @rtype: 3294 3295 """ 3296 3297 atom, category, name, \ 3298 version, slot, versiontag, \ 3299 revision, branch, etpapi = self.getScopeData(idpackage) 3300 chost, cflags, cxxflags = self.retrieveCompileFlags(idpackage) 3301 3302 pkg_content = set() 3303 if content: 3304 pkg_content = self.retrieveContent(idpackage) 3305 3306 data = { 3307 'atom': atom, 3308 'category': category, 3309 'name': name, 3310 'version': version, 3311 'versiontag': versiontag, 3312 'revision': revision, 3313 'branch': branch, 3314 'chost': chost, 3315 'cflags': cflags, 3316 'cxxflags': cxxflags, 3317 'etpapi': etpapi, 3318 'trigger': self.retrieveTrigger(idpackage), 3319 'eclasses': self.retrieveEclasses(idpackage), 3320 'content': pkg_content, 3321 'spm_phases': self.retrieveSpmPhases(idpackage), 3322 } 3323 return data
3324
3325 - def getPackageData(self, idpackage, get_content = True, 3326 content_insert_formatted = False, trigger_unicode = True):
3327 data = {} 3328 3329 try: 3330 atom, name, version, versiontag, \ 3331 description, category, chost, \ 3332 cflags, cxxflags,homepage, \ 3333 mylicense, branch, download, \ 3334 digest, slot, etpapi, \ 3335 datecreation, size, revision = self.getBaseData(idpackage) 3336 except TypeError: 3337 return None 3338 3339 content = {} 3340 if get_content: 3341 content = self.retrieveContent( 3342 idpackage, extended = True, 3343 formatted = True, insert_formatted = content_insert_formatted 3344 ) 3345 3346 sources = self.retrieveSources(idpackage) 3347 mirrornames = set() 3348 for x in sources: 3349 if x.startswith("mirror://"): 3350 mirrornames.add(x.split("/")[2]) 3351 3352 data = { 3353 'atom': atom, 3354 'name': name, 3355 'version': version, 3356 'versiontag':versiontag, 3357 'description': description, 3358 'category': category, 3359 'chost': chost, 3360 'cflags': cflags, 3361 'cxxflags': cxxflags, 3362 'homepage': homepage, 3363 'license': mylicense, 3364 'branch': branch, 3365 'download': download, 3366 'digest': digest, 3367 'slot': slot, 3368 'etpapi': etpapi, 3369 'datecreation': datecreation, 3370 'size': size, 3371 'revision': revision, 3372 # risky to add to the sql above, still 3373 'counter': self.retrieveCounter(idpackage), 3374 'messages': self.retrieveMessages(idpackage), 3375 'trigger': self.retrieveTrigger(idpackage, get_unicode = trigger_unicode), 3376 'disksize': self.retrieveOnDiskSize(idpackage), 3377 'changelog': self.retrieveChangelog(idpackage), 3378 'injected': self.isInjected(idpackage), 3379 'systempackage': self.isSystemPackage(idpackage), 3380 'config_protect': self.retrieveProtect(idpackage), 3381 'config_protect_mask': self.retrieveProtectMask(idpackage), 3382 'useflags': self.retrieveUseflags(idpackage), 3383 'keywords': self.retrieveKeywords(idpackage), 3384 'sources': sources, 3385 'eclasses': self.retrieveEclasses(idpackage), 3386 'needed': self.retrieveNeeded(idpackage, extended = True), 3387 'needed_paths': self.retrieveNeededPaths(idpackage), 3388 'provide': self.retrieveProvide(idpackage), 3389 'conflicts': self.retrieveConflicts(idpackage), 3390 'licensedata': self.retrieveLicensedata(idpackage), 3391 'content': content, 3392 'dependencies': dict((x, y,) for x, y in \ 3393 self.retrieveDependencies(idpackage, extended = True)), 3394 'mirrorlinks': [[x,self.retrieveMirrorInfo(x)] for x in mirrornames], 3395 'signatures': self.retrieveSignatures(idpackage), 3396 'spm_phases': self.retrieveSpmPhases(idpackage), 3397 } 3398 3399 return data
3400
3401 - def fetchall2set(self, item):
3402 """ 3403 docstring_title 3404 3405 @param item: 3406 @type item: 3407 @return: 3408 @rtype: 3409 3410 """ 3411 mycontent = set() 3412 for x in item: 3413 mycontent |= set(x) 3414 return mycontent
3415
3416 - def fetchall2list(self, item):
3417 """ 3418 docstring_title 3419 3420 @param item: 3421 @type item: 3422 @return: 3423 @rtype: 3424 3425 """ 3426 content = [] 3427 for x in item: 3428 content += list(x) 3429 return content
3430
3431 - def fetchone2list(self, item):
3432 """ 3433 docstring_title 3434 3435 @param item: 3436 @type item: 3437 @return: 3438 @rtype: 3439 3440 """ 3441 return list(item)
3442
3443 - def fetchone2set(self, item):
3444 """ 3445 docstring_title 3446 3447 @param item: 3448 @type item: 3449 @return: 3450 @rtype: 3451 3452 """ 3453 return set(item)
3454
3455 - def clearCache(self, depends = False):
3456 """ 3457 docstring_title 3458 3459 @keyword depends: 3460 @type depends: 3461 @return: 3462 @rtype: 3463 3464 """ 3465 3466 self.live_cache.clear() 3467 def do_clear(name): 3468 """ 3469 docstring_title 3470 3471 @param name: 3472 @type name: 3473 @return: 3474 @rtype: 3475 3476 """ 3477 dump_path = os.path.join(etpConst['dumpstoragedir'], name) 3478 dump_dir = os.path.dirname(dump_path) 3479 if os.path.isdir(dump_dir): 3480 for item in os.listdir(dump_dir): 3481 try: os.remove(os.path.join(dump_dir, item)) 3482 except OSError: pass
3483 3484 do_clear("%s/%s/" % (self.dbMatchCacheKey, self.dbname,)) 3485 if depends: 3486 do_clear(etpCache['depends_tree']) 3487 do_clear(etpCache['dep_tree']) 3488 do_clear(etpCache['filter_satisfied_deps']) 3489
3490 - def retrieveRepositoryUpdatesDigest(self, repository):
3491 """ 3492 docstring_title 3493 3494 @param repository: 3495 @type repository: 3496 @return: 3497 @rtype: 3498 3499 """ 3500 if not self.doesTableExist("treeupdates"): 3501 return -1 3502 self.cursor.execute('SELECT digest FROM treeupdates WHERE repository = (?)', (repository,)) 3503 mydigest = self.cursor.fetchone() 3504 if mydigest: 3505 return mydigest[0] 3506 else: 3507 return -1
3508
3509 - def listAllTreeUpdatesActions(self, no_ids_repos = False):
3510 """ 3511 docstring_title 3512 3513 @keyword no_ids_repos: 3514 @type no_ids_repos: 3515 @return: 3516 @rtype: 3517 3518 """ 3519 if no_ids_repos: 3520 self.cursor.execute('SELECT command,branch,date FROM treeupdatesactions') 3521 else: 3522 self.cursor.execute('SELECT * FROM treeupdatesactions') 3523 return self.cursor.fetchall()
3524
3525 - def retrieveTreeUpdatesActions(self, repository, forbranch = None):
3526 """ 3527 docstring_title 3528 3529 @param repository: 3530 @type repository: 3531 @keyword forbranch: 3532 @type forbranch: 3533 @return: 3534 @rtype: 3535 3536 """ 3537 3538 if not self.doesTableExist("treeupdatesactions"): return [] 3539 if forbranch == None: forbranch = self.db_branch 3540 params = [repository] 3541 branch_string = '' 3542 if forbranch: 3543 branch_string = 'and branch = (?)' 3544 params.append(forbranch) 3545 3546 self.cursor.execute(""" 3547 SELECT command FROM treeupdatesactions WHERE 3548 repository = (?) %s order by date""" % (branch_string,), params) 3549 return self.fetchall2list(self.cursor.fetchall())
3550 3551 # mainly used to restore a previous table, used by reagent in --initialize
3552 - def bumpTreeUpdatesActions(self, updates):
3553 """ 3554 docstring_title 3555 3556 @param updates: 3557 @type updates: 3558 @return: 3559 @rtype: 3560 3561 """ 3562 with self.__write_mutex: 3563 self.cursor.execute('DELETE FROM treeupdatesactions') 3564 self.cursor.executemany('INSERT INTO treeupdatesactions VALUES (?,?,?,?,?)', updates) 3565 self.commitChanges()
3566
3567 - def removeTreeUpdatesActions(self, repository):
3568 """ 3569 docstring_title 3570 3571 @param repository: 3572 @type repository: 3573 @return: 3574 @rtype: 3575 3576 """ 3577 with self.__write_mutex: 3578 self.cursor.execute('DELETE FROM treeupdatesactions WHERE repository = (?)', (repository,)) 3579 self.commitChanges()
3580
3581 - def insertTreeUpdatesActions(self, updates, repository):
3582 """ 3583 docstring_title 3584 3585 @param updates: 3586 @type updates: 3587 @param repository: 3588 @type repository: 3589 @return: 3590 @rtype: 3591 3592 """ 3593 with self.__write_mutex: 3594 myupdates = [[repository]+list(x) for x in updates] 3595 self.cursor.executemany('INSERT INTO treeupdatesactions VALUES (NULL,?,?,?,?)', myupdates) 3596 self.commitChanges()
3597
3598 - def setRepositoryUpdatesDigest(self, repository, digest):
3599 """ 3600 docstring_title 3601 3602 @param repository: 3603 @type repository: 3604 @param digest: 3605 @type digest: 3606 @return: 3607 @rtype: 3608 3609 """ 3610 with self.__write_mutex: 3611 self.cursor.execute('DELETE FROM treeupdates where repository = (?)', (repository,)) # doing it for safety 3612 self.cursor.execute('INSERT INTO treeupdates VALUES (?,?)', (repository, digest,))
3613
3614 - def addRepositoryUpdatesActions(self, repository, actions, branch):
3615 """ 3616 docstring_title 3617 3618 @param repository: 3619 @type repository: 3620 @param actions: 3621 @type actions: 3622 @param branch: 3623 @type branch: 3624 @return: 3625 @rtype: 3626 3627 """ 3628 3629 mytime = str(self.entropyTools.get_current_unix_time()) 3630 with self.__write_mutex: 3631 myupdates = [ 3632 (repository, x, branch, mytime,) for x in actions \ 3633 if not self.doesTreeupdatesActionExist(repository, x, branch) 3634 ] 3635 self.cursor.executemany('INSERT INTO treeupdatesactions VALUES (NULL,?,?,?,?)', myupdates)
3636
3637 - def doesTreeupdatesActionExist(self, repository, command, branch):
3638 self.cursor.execute(""" 3639 SELECT * FROM treeupdatesactions 3640 WHERE repository = (?) and command = (?) and branch = (?)""", (repository, command, branch,)) 3641 result = self.cursor.fetchone() 3642 if result: 3643 return True 3644 return False
3645
3646 - def clearPackageSets(self):
3647 """ 3648 docstring_title 3649 3650 @return: 3651 @rtype: 3652 3653 """ 3654 self.cursor.execute('DELETE FROM packagesets')
3655
3656 - def insertPackageSets(self, sets_data):
3657 """ 3658 docstring_title 3659 3660 @param sets_data: 3661 @type sets_data: 3662 @return: 3663 @rtype: 3664 3665 """ 3666 3667 mysets = [] 3668 for setname in sorted(sets_data.keys()): 3669 for dependency in sorted(sets_data[setname]): 3670 try: 3671 mysets.append((unicode(setname), unicode(dependency),)) 3672 except (UnicodeDecodeError, UnicodeEncodeError,): 3673 continue 3674 3675 with self.__write_mutex: 3676 self.cursor.executemany('INSERT INTO packagesets VALUES (?,?)', mysets)
3677
3678 - def retrievePackageSets(self):
3679 """ 3680 docstring_title 3681 3682 @return: 3683 @rtype: 3684 3685 """ 3686 if not self.doesTableExist("packagesets"): return {} 3687 self.cursor.execute('SELECT setname,dependency FROM packagesets') 3688 data = self.cursor.fetchall() 3689 sets = {} 3690 for setname, dependency in data: 3691 if not sets.has_key(setname): 3692 sets[setname] = set() 3693 sets[setname].add(dependency) 3694 return sets
3695
3696 - def retrievePackageSet(self, setname):
3697 """ 3698 docstring_title 3699 3700 @param setname: 3701 @type setname: 3702 @return: 3703 @rtype: 3704 3705 """ 3706 self.cursor.execute('SELECT dependency FROM packagesets WHERE setname = (?)', (setname,)) 3707 return self.fetchall2set(self.cursor.fetchall())
3708
3709 - def retrieveSystemPackages(self):
3710 """ 3711 docstring_title 3712 3713 @return: 3714 @rtype: 3715 3716 """ 3717 self.cursor.execute('SELECT idpackage FROM systempackages') 3718 return self.fetchall2set(self.cursor.fetchall())
3719
3720 - def retrieveAtom(self, idpackage):
3721 """ 3722 docstring_title 3723 3724 @param idpackage: package indentifier 3725 @type idpackage: int 3726 @return: 3727 @rtype: 3728 3729 """ 3730 self.cursor.execute('SELECT atom FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 3731 atom = self.cursor.fetchone() 3732 if atom: return atom[0]
3733
3734 - def retrieveBranch(self, idpackage):
3735 """ 3736 docstring_title 3737 3738 @param idpackage: package indentifier 3739 @type idpackage: int 3740 @return: 3741 @rtype: 3742 3743 """ 3744 self.cursor.execute('SELECT branch FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 3745 br = self.cursor.fetchone() 3746 if br: return br[0]
3747
3748 - def retrieveTrigger(self, idpackage, get_unicode = False):
3749 """ 3750 docstring_title 3751 3752 @param idpackage: package indentifier 3753 @type idpackage: int 3754 @keyword get_unicode: 3755 @type get_unicode: 3756 @return: 3757 @rtype: 3758 3759 """ 3760 self.cursor.execute('SELECT data FROM triggers WHERE idpackage = (?)', (idpackage,)) 3761 trigger = self.cursor.fetchone() 3762 if not trigger: 3763 return '' # FIXME backward compatibility with <=0.52.x 3764 if not get_unicode: 3765 return trigger[0] 3766 return unicode(trigger[0], 'raw_unicode_escape')
3767
3768 - def retrieveDownloadURL(self, idpackage):
3769 """ 3770 docstring_title 3771 3772 @param idpackage: package indentifier 3773 @type idpackage: int 3774 @return: 3775 @rtype: 3776 3777 """ 3778 self.cursor.execute('SELECT download FROM extrainfo WHERE idpackage = (?)', (idpackage,)) 3779 download = self.cursor.fetchone() 3780 if download: return download[0]
3781
3782 - def retrieveDescription(self, idpackage):
3783 """ 3784 docstring_title 3785 3786 @param idpackage: package indentifier 3787 @type idpackage: int 3788 @return: 3789 @rtype: 3790 3791 """ 3792 self.cursor.execute('SELECT description FROM extrainfo WHERE idpackage = (?)', (idpackage,)) 3793 description = self.cursor.fetchone() 3794 if description: return description[0]
3795
3796 - def retrieveHomepage(self, idpackage):
3797 """ 3798 docstring_title 3799 3800 @param idpackage: package indentifier 3801 @type idpackage: int 3802 @return: 3803 @rtype: 3804 3805 """ 3806 self.cursor.execute('SELECT homepage FROM extrainfo WHERE idpackage = (?)', (idpackage,)) 3807 home = self.cursor.fetchone() 3808 if home: return home[0]
3809
3810 - def retrieveCounter(self, idpackage):
3811 self.cursor.execute(""" 3812 SELECT counters.counter FROM counters,baseinfo 3813 WHERE counters.idpackage = (?) AND 3814 baseinfo.idpackage = counters.idpackage AND 3815 baseinfo.branch = counters.branch""", (idpackage,)) 3816 mycounter = self.cursor.fetchone() 3817 if mycounter: return mycounter[0] 3818 return -1
3819
3820 - def retrieveMessages(self, idpackage):
3821 """ 3822 docstring_title 3823 3824 @param idpackage: package indentifier 3825 @type idpackage: int 3826 @return: 3827 @rtype: 3828 3829 """ 3830 self.cursor.execute('SELECT message FROM messages WHERE idpackage = (?)', (idpackage,)) 3831 return self.fetchall2list(self.cursor.fetchall())
3832 3833 # in bytes
3834 - def retrieveSize(self, idpackage):
3835 """ 3836 docstring_title 3837 3838 @param idpackage: package indentifier 3839 @type idpackage: int 3840 @return: 3841 @rtype: 3842 3843 """ 3844 self.cursor.execute('SELECT size FROM extrainfo WHERE idpackage = (?)', (idpackage,)) 3845 size = self.cursor.fetchone() 3846 if size: return size[0]
3847 3848 # in bytes
3849 - def retrieveOnDiskSize(self, idpackage):
3850 """ 3851 docstring_title 3852 3853 @param idpackage: package indentifier 3854 @type idpackage: int 3855 @return: 3856 @rtype: 3857 3858 """ 3859 self.cursor.execute('SELECT size FROM sizes WHERE idpackage = (?)', (idpackage,)) 3860 size = self.cursor.fetchone() # do not use [0]! 3861 if not size: size = 0 3862 else: size = size[0] 3863 return size
3864
3865 - def retrieveDigest(self, idpackage):
3866 """ 3867 docstring_title 3868 3869 @param idpackage: package indentifier 3870 @type idpackage: int 3871 @return: 3872 @rtype: 3873 3874 """ 3875 self.cursor.execute('SELECT digest FROM extrainfo WHERE idpackage = (?)', (idpackage,)) 3876 digest = self.cursor.fetchone() 3877 if digest: return digest[0]
3878
3879 - def retrieveSignatures(self, idpackage):
3880 """ 3881 docstring_title 3882 3883 @param idpackage: package indentifier 3884 @type idpackage: int 3885 @return: 3886 @rtype: 3887 3888 """ 3889 mydict = { 3890 'sha1': None, 3891 'sha256': None, 3892 'sha512': None, 3893 } 3894 # FIXME: remove this check in future 3895 if self.doesTableExist('packagesignatures'): 3896 self.cursor.execute(""" 3897 SELECT sha1, sha256, sha512 FROM packagesignatures 3898 WHERE idpackage = (?)""", (idpackage,)) 3899 data = self.cursor.fetchone() 3900 if data: 3901 mydict['sha1'], mydict['sha256'], mydict['sha512'] = data 3902 return mydict
3903
3904 - def retrieveName(self, idpackage):
3905 """ 3906 docstring_title 3907 3908 @param idpackage: package indentifier 3909 @type idpackage: int 3910 @return: 3911 @rtype: 3912 3913 """ 3914 self.cursor.execute('SELECT name FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 3915 name = self.cursor.fetchone() 3916 if name: return name[0]
3917
3918 - def retrieveKeySlot(self, idpackage):
3919 """ 3920 docstring_title 3921 3922 @param idpackage: package indentifier 3923 @type idpackage: int 3924 3925 """ 3926 self.cursor.execute(""" 3927 SELECT categories.category || "/" || baseinfo.name,baseinfo.slot FROM baseinfo,categories 3928 WHERE baseinfo.idpackage = (?) and baseinfo.idcategory = categories.idcategory""", (idpackage,)) 3929 data = self.cursor.fetchone() 3930 return data
3931
3932 - def retrieveKeySlotAggregated(self, idpackage):
3933 """ 3934 docstring_title 3935 3936 @param idpackage: package indentifier 3937 @type idpackage: int 3938 3939 """ 3940 self.cursor.execute(""" 3941 SELECT categories.category || "/" || baseinfo.name || ":" || baseinfo.slot FROM baseinfo,categories 3942 WHERE baseinfo.idpackage = (?) and baseinfo.idcategory = categories.idcategory""", (idpackage,)) 3943 data = self.cursor.fetchone() 3944 if data: return data[0]
3945
3946 - def retrieveKeySlotTag(self, idpackage):
3947 """ 3948 docstring_title 3949 3950 @param idpackage: package indentifier 3951 @type idpackage: int 3952 3953 """ 3954 self.cursor.execute(""" 3955 SELECT categories.category || "/" || baseinfo.name,baseinfo.slot,baseinfo.versiontag FROM baseinfo,categories 3956 WHERE baseinfo.idpackage = (?) and baseinfo.idcategory = categories.idcategory""", (idpackage,)) 3957 data = self.cursor.fetchone() 3958 return data
3959
3960 - def retrieveVersion(self, idpackage):
3961 """ 3962 docstring_title 3963 3964 @param idpackage: package indentifier 3965 @type idpackage: int 3966 @return: 3967 @rtype: 3968 3969 """ 3970 self.cursor.execute('SELECT version FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 3971 ver = self.cursor.fetchone() 3972 if ver: return ver[0]
3973
3974 - def retrieveRevision(self, idpackage):
3975 """ 3976 docstring_title 3977 3978 @param idpackage: package indentifier 3979 @type idpackage: int 3980 @return: 3981 @rtype: 3982 3983 """ 3984 self.cursor.execute('SELECT revision FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 3985 rev = self.cursor.fetchone() 3986 if rev: return rev[0]
3987
3988 - def retrieveDateCreation(self, idpackage):
3989 """ 3990 docstring_title 3991 3992 @param idpackage: package indentifier 3993 @type idpackage: int 3994 @return: 3995 @rtype: 3996 3997 """ 3998 self.cursor.execute('SELECT datecreation FROM extrainfo WHERE idpackage = (?)', (idpackage,)) 3999 date = self.cursor.fetchone() 4000 if date: return date[0]
4001
4002 - def retrieveApi(self, idpackage):
4003 """ 4004 docstring_title 4005 4006 @param idpackage: package indentifier 4007 @type idpackage: int 4008 @return: 4009 @rtype: 4010 4011 """ 4012 self.cursor.execute('SELECT etpapi FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 4013 api = self.cursor.fetchone() 4014 if api: return api[0]
4015
4016 - def retrieveUseflags(self, idpackage):
4017 """ 4018 docstring_title 4019 4020 @param idpackage: package indentifier 4021 @type idpackage: int 4022 """ 4023 self.cursor.execute(""" 4024 SELECT flagname FROM useflags,useflagsreference 4025 WHERE useflags.idpackage = (?) AND 4026 useflags.idflag = useflagsreference.idflag""", (idpackage,)) 4027 return self.fetchall2set(self.cursor.fetchall())
4028
4029 - def retrieveEclasses(self, idpackage):
4030 """ 4031 docstring_title 4032 4033 @param idpackage: package indentifier 4034 @type idpackage: int 4035 """ 4036 self.cursor.execute(""" 4037 SELECT classname FROM eclasses,eclassesreference 4038 WHERE eclasses.idpackage = (?) AND 4039 eclasses.idclass = eclassesreference.idclass""", (idpackage,)) 4040 return self.fetchall2set(self.cursor.fetchall())
4041
4042 - def retrieveSpmPhases(self, idpackage):
4043 """ 4044 docstring_title 4045 4046 @param idpackage: 4047 @type idpackage: 4048 @return: 4049 @rtype: 4050 4051 """ 4052 # FIXME: remove this check in future: 4053 if not self.doesTableExist('packagespmphases'): 4054 return None 4055 self.cursor.execute(""" 4056 SELECT phases FROM packagespmphases 4057 WHERE idpackage = (?) 4058 """, (idpackage,)) 4059 rslt = self.cursor.fetchone() 4060 if rslt: return rslt[0]
4061
4062 - def retrieveNeededRaw(self, idpackage):
4063 """ 4064 docstring_title 4065 4066 @param idpackage: package indentifier 4067 @type idpackage: int 4068 """ 4069 self.cursor.execute(""" 4070 SELECT library FROM needed,neededreference 4071 WHERE needed.idpackage = (?) AND 4072 needed.idneeded = neededreference.idneeded""", (idpackage,)) 4073 return self.fetchall2set(self.cursor.fetchall())
4074
4075 - def retrieveNeeded(self, idpackage, extended = False, format = False):
4076 """ 4077 docstring_title 4078 4079 @param idpackage: package indentifier 4080 @type idpackage: int 4081 @keyword extended: 4082 @type extended: 4083 @keyword format: 4084 @type format: 4085 @return: 4086 @rtype: 4087 4088 """ 4089 4090 if extended: 4091 self.cursor.execute(""" 4092 SELECT library,elfclass FROM needed,neededreference 4093 WHERE needed.idpackage = (?) AND 4094 needed.idneeded = neededreference.idneeded order by library""", (idpackage,)) 4095 needed = self.cursor.fetchall() 4096 else: 4097 self.cursor.execute(""" 4098 SELECT library FROM needed,neededreference 4099 WHERE needed.idpackage = (?) AND 4100 needed.idneeded = neededreference.idneeded ORDER BY library""", (idpackage,)) 4101 needed = self.fetchall2list(self.cursor.fetchall()) 4102 4103 if extended and format: 4104 data = {} 4105 for lib, elfclass in needed: 4106 data[lib] = elfclass 4107 needed = data 4108 4109 return needed
4110
4111 - def retrieveNeededPaths(self, idpackage):
4112 """ 4113 docstring_title 4114 4115 @param idpackage: package indentifier 4116 @type idpackage: int 4117 @return: 4118 @rtype: 4119 4120 """ 4121 if not self.doesTableExist('neededlibrarypaths'): 4122 return {} 4123 self.cursor.execute(""" 4124 SELECT neededlibrarypaths.library, neededlibrarypaths.path, 4125 neededlibrarypaths.elfclass FROM 4126 neededlibrarypaths, neededreference, needed WHERE 4127 needed.idpackage = (?) AND needed.idneeded = neededreference.idneeded 4128 AND neededreference.library = neededlibrarypaths.library 4129 """, (idpackage,)) 4130 data = {} 4131 for lib, path, elfclass in self.cursor.fetchall(): 4132 obj = data.setdefault(lib, set()) 4133 obj.add((path, elfclass)) 4134 return data
4135
4136 - def retrieveNeededLibraryPaths(self, needed_library_name, elfclass):
4137 """ 4138 docstring_title 4139 4140 @param needed_library_name: 4141 @type needed_library_name: 4142 @param elfclass: 4143 @type elfclass: 4144 @return: 4145 @rtype: 4146 4147 """ 4148 if not self.doesTableExist('neededlibrarypaths'): 4149 return set() 4150 self.cursor.execute(""" 4151 SELECT path FROM neededlibrarypaths, neededreference, needed 4152 WHERE neededlibrarypaths.library = (?) AND 4153 neededlibrarypaths.elfclass = (?) AND 4154 neededreference.library = neededlibrarypaths.library AND 4155 needed.elfclass = neededlibrarypaths.elfclass AND 4156 needed.idneeded = neededreference.idneeded 4157 """, (needed_library_name, elfclass,)) 4158 return self.fetchall2set(self.cursor.fetchall())
4159
4160 - def retrieveNeededLibraryIdpackages(self):
4161 """ 4162 docstring_title 4163 4164 @return: 4165 @rtype: 4166 4167 """ 4168 if not self.doesTableExist('neededlibraryidpackages'): 4169 return [] 4170 self.cursor.execute('SELECT idpackage, library, elfclass FROM neededlibraryidpackages') 4171 return self.cursor.fetchall()
4172
4173 - def clearNeededLibraryIdpackages(self):
4174 """ 4175 docstring_title 4176 4177 @return: 4178 @rtype: 4179 4180 """ 4181 if not self.doesTableExist('neededlibraryidpackages'): 4182 return 4183 self.cursor.execute('DELETE FROM neededlibraryidpackages')
4184
4185 - def setNeededLibraryIdpackages(self, library_map):
4186 """ 4187 docstring_title 4188 4189 @param library_map: 4190 @type library_map: 4191 @return: 4192 @rtype: 4193 4194 """ 4195 if not self.doesTableExist('neededlibraryidpackages'): 4196 return 4197 self.cursor.executemany('INSERT INTO neededlibraryidpackages VALUES (?,?,?)', library_map)
4198
4199 - def retrieveConflicts(self, idpackage):
4200 """ 4201 docstring_title 4202 4203 @param idpackage: package indentifier 4204 @type idpackage: int 4205 @return: 4206 @rtype: 4207 4208 """ 4209 self.cursor.execute('SELECT conflict FROM conflicts WHERE idpackage = (?)', (idpackage,)) 4210 return self.fetchall2set(self.cursor.fetchall())
4211
4212 - def retrieveProvide(self, idpackage):
4213 """ 4214 docstring_title 4215 4216 @param idpackage: package indentifier 4217 @type idpackage: int 4218 @return: 4219 @rtype: 4220 4221 """ 4222 self.cursor.execute('SELECT atom FROM provide WHERE idpackage = (?)', (idpackage,)) 4223 return self.fetchall2set(self.cursor.fetchall())
4224
4225 - def retrieveDependenciesList(self, idpackage):
4226 self.cursor.execute(""" 4227 SELECT dependenciesreference.dependency FROM dependencies,dependenciesreference 4228 WHERE dependencies.idpackage = (?) AND 4229 dependencies.iddependency = dependenciesreference.iddependency 4230 UNION SELECT "!" || conflict FROM conflicts 4231 WHERE idpackage = (?)""", (idpackage, idpackage,)) 4232 return self.fetchall2set(self.cursor.fetchall())
4233
4234 - def retrievePostDependencies(self, idpackage, extended = False):
4235 """ 4236 docstring_title 4237 4238 @param idpackage: package indentifier 4239 @type idpackage: int 4240 @keyword extended: 4241 @type extended: 4242 @return: 4243 @rtype: 4244 4245 """ 4246 return self.retrieveDependencies(idpackage, extended = extended, deptype = etpConst['spm']['pdepend_id'])
4247
4248 - def retrieveManualDependencies(self, idpackage, extended = False):
4249 """ 4250 docstring_title 4251 4252 @param idpackage: package indentifier 4253 @type idpackage: int 4254 @keyword extended: 4255 @type extended: 4256 @return: 4257 @rtype: 4258 4259 """ 4260 return self.retrieveDependencies(idpackage, extended = extended, deptype = etpConst['spm']['mdepend_id'])
4261
4262 - def retrieveDependencies(self, idpackage, extended = False, deptype = None, 4263 exclude_deptypes = None):
4264 4265 """ 4266 docstring_title 4267 4268 @param idpackage: package indentifier 4269 @type idpackage: int 4270 """ 4271 4272 searchdata = [idpackage] 4273 4274 depstring = '' 4275 if deptype != None: 4276 depstring = ' and dependencies.type = (?)' 4277 searchdata.append(deptype) 4278 4279 excluded_deptypes_query = "" 4280 if exclude_deptypes != None: 4281 for dep_type in exclude_deptypes: 4282 excluded_deptypes_query += " AND dependencies.type != %s" % ( 4283 dep_type,) 4284 4285 if extended: 4286 self.cursor.execute(""" 4287 SELECT dependenciesreference.dependency,dependencies.type 4288 FROM dependencies,dependenciesreference 4289 WHERE dependencies.idpackage = (?) AND 4290 dependencies.iddependency = dependenciesreference.iddependency %s %s""" % ( 4291 depstring,excluded_deptypes_query,), searchdata) 4292 deps = self.cursor.fetchall() 4293 else: 4294 self.cursor.execute(""" 4295 SELECT dependenciesreference.dependency 4296 FROM dependencies,dependenciesreference 4297 WHERE dependencies.idpackage = (?) AND 4298 dependencies.iddependency = dependenciesreference.iddependency %s %s""" % ( 4299 depstring,excluded_deptypes_query,), searchdata) 4300 deps = self.fetchall2set(self.cursor.fetchall()) 4301 4302 return deps
4303
4304 - def retrieveIdDependencies(self, idpackage):
4305 """ 4306 docstring_title 4307 4308 @param idpackage: package indentifier 4309 @type idpackage: int 4310 @return: 4311 @rtype: 4312 4313 """ 4314 self.cursor.execute('SELECT iddependency FROM dependencies WHERE idpackage = (?)', (idpackage,)) 4315 return self.fetchall2set(self.cursor.fetchall())
4316
4317 - def retrieveDependencyFromIddependency(self, iddependency):
4318 """ 4319 docstring_title 4320 4321 @param iddependency: 4322 @type iddependency: 4323 @return: 4324 @rtype: 4325 4326 """ 4327 self.cursor.execute('SELECT dependency FROM dependenciesreference WHERE iddependency = (?)', (iddependency,)) 4328 dep = self.cursor.fetchone() 4329 if dep: dep = dep[0] 4330 return dep
4331
4332 - def retrieveKeywords(self, idpackage):
4333 """ 4334 docstring_title 4335 4336 @param idpackage: package indentifier 4337 @type idpackage: int 4338 """ 4339 self.cursor.execute(""" 4340 SELECT keywordname FROM keywords,keywordsreference 4341 WHERE keywords.idpackage = (?) AND 4342 keywords.idkeyword = keywordsreference.idkeyword""", (idpackage,)) 4343 return self.fetchall2set(self.cursor.fetchall())
4344
4345 - def retrieveProtect(self, idpackage):
4346 """ 4347 docstring_title 4348 4349 @param idpackage: package indentifier 4350 @type idpackage: int 4351 """ 4352 self.cursor.execute(""" 4353 SELECT protect FROM configprotect,configprotectreference 4354 WHERE configprotect.idpackage = (?) AND 4355 configprotect.idprotect = configprotectreference.idprotect""", (idpackage,)) 4356 protect = self.cursor.fetchone() 4357 if not protect: protect = '' 4358 else: protect = protect[0] 4359 return protect
4360
4361 - def retrieveProtectMask(self, idpackage):
4362 """ 4363 docstring_title 4364 4365 @param idpackage: package indentifier 4366 @type idpackage: int 4367 """ 4368 self.cursor.execute(""" 4369 SELECT protect FROM configprotectmask,configprotectreference 4370 WHERE idpackage = (?) AND 4371 configprotectmask.idprotect = configprotectreference.idprotect""", (idpackage,)) 4372 protect = self.cursor.fetchone() 4373 if not protect: protect = '' 4374 else: protect = protect[0] 4375 return protect
4376
4377 - def retrieveSources(self, idpackage, extended = False):
4378 """ 4379 docstring_title 4380 4381 @param idpackage: package indentifier 4382 @type idpackage: int 4383 """ 4384 self.cursor.execute(""" 4385 SELECT sourcesreference.source FROM sources,sourcesreference 4386 WHERE idpackage = (?) AND 4387 sources.idsource = sourcesreference.idsource""", (idpackage,)) 4388 sources = self.fetchall2set(self.cursor.fetchall()) 4389 if not extended: 4390 return sources 4391 4392 source_data = {} 4393 mirror_str = "mirror://" 4394 for source in sources: 4395 source_data[source] = set() 4396 if source.startswith(mirror_str): 4397 mirrorname = source.split("/")[2] 4398 mirror_url = source.split("/", 3)[3:][0] 4399 source_data[source] |= set([os.path.join(url, mirror_url) for url in self.retrieveMirrorInfo(mirrorname)]) 4400 else: 4401 source_data[source].add(source) 4402 4403 return source_data
4404
4405 - def retrieveAutomergefiles(self, idpackage, get_dict = False):
4406 """ 4407 docstring_title 4408 4409 @param idpackage: package indentifier 4410 @type idpackage: int 4411 @keyword get_dict: 4412 @type get_dict: 4413 @return: 4414 @rtype: 4415 4416 """ 4417 if not self.doesTableExist('automergefiles'): 4418 self.createAutomergefilesTable() 4419 # like portage does 4420 self.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 4421 self.cursor.execute('SELECT configfile, md5 FROM automergefiles WHERE idpackage = (?)', (idpackage,)) 4422 data = self.cursor.fetchall() 4423 if get_dict: 4424 data = dict(((x, y,) for x, y in data)) 4425 return data
4426
4427 - def retrieveContent(self, idpackage, extended = False, contentType = None, 4428 formatted = False, insert_formatted = False, order_by = ''):
4429 4430 """ 4431 docstring_title 4432 4433 @param idpackage: package indentifier 4434 @type idpackage: int 4435 """ 4436 4437 extstring = '' 4438 if extended: 4439 extstring = ",type" 4440 extstring_idpackage = '' 4441 if insert_formatted: 4442 extstring_idpackage = 'idpackage,' 4443 4444 searchkeywords = [idpackage] 4445 contentstring = '' 4446 if contentType: 4447 searchkeywords.append(contentType) 4448 contentstring = ' and type = (?)' 4449 4450 order_by_string = '' 4451 if order_by: 4452 order_by_string = ' order by %s' % (order_by,) 4453 4454 did_try = False 4455 while 1: 4456 try: 4457 4458 self.cursor.execute('SELECT %s file%s FROM content WHERE idpackage = (?) %s%s' % ( 4459 extstring_idpackage, extstring, contentstring, order_by_string,), 4460 searchkeywords) 4461 4462 if extended and insert_formatted: 4463 fl = self.cursor.fetchall() 4464 elif extended and formatted: 4465 fl = {} 4466 items = self.cursor.fetchone() 4467 while items: 4468 fl[items[0]] = items[1] 4469 items = self.cursor.fetchone() 4470 elif extended: 4471 fl = self.cursor.fetchall() 4472 else: 4473 if order_by: 4474 fl = self.fetchall2list(self.cursor.fetchall()) 4475 else: 4476 fl = self.fetchall2set(self.cursor.fetchall()) 4477 break 4478 except (self.dbapi2.OperationalError,): 4479 if did_try: 4480 raise 4481 did_try = True 4482 # XXX support for old entropy db entries, which were 4483 # not inserted in utf-8 4484 self.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 4485 continue 4486 return fl
4487
4488 - def retrieveChangelog(self, idpackage):
4489 """ 4490 docstring_title 4491 4492 @param idpackage: package indentifier 4493 @type idpackage: int 4494 @return: 4495 @rtype: 4496 4497 """ 4498 if not self.doesTableExist('packagechangelogs'): 4499 return None 4500 self.cursor.execute(""" 4501 SELECT packagechangelogs.changelog FROM packagechangelogs,baseinfo,categories 4502 WHERE baseinfo.idpackage = (?) AND 4503 baseinfo.idcategory = categories.idcategory AND 4504 packagechangelogs.name = baseinfo.name AND 4505 packagechangelogs.category = categories.category""", (idpackage,)) 4506 changelog = self.cursor.fetchone() 4507 if changelog: 4508 changelog = changelog[0] 4509 try: 4510 return unicode(changelog, 'raw_unicode_escape') 4511 except UnicodeDecodeError: 4512 return unicode(changelog, 'utf-8')
4513
4514 - def retrieveChangelogByKey(self, category, name):
4515 """ 4516 docstring_title 4517 4518 @param category: 4519 @type category: 4520 @param name: 4521 @type name: 4522 @return: 4523 @rtype: 4524 4525 """ 4526 if not self.doesTableExist('packagechangelogs'): 4527 return None 4528 self.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 4529 self.cursor.execute('SELECT changelog FROM packagechangelogs WHERE category = (?) AND name = (?)', (category, name,)) 4530 changelog = self.cursor.fetchone() 4531 if changelog: return unicode(changelog[0], 'raw_unicode_escape')
4532
4533 - def retrieveSlot(self, idpackage):
4534 """ 4535 docstring_title 4536 4537 @param idpackage: package indentifier 4538 @type idpackage: int 4539 @return: 4540 @rtype: 4541 4542 """ 4543 self.cursor.execute('SELECT slot FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 4544 slot = self.cursor.fetchone() 4545 if slot: return slot[0]
4546
4547 - def retrieveVersionTag(self, idpackage):
4548 """ 4549 docstring_title 4550 4551 @param idpackage: package indentifier 4552 @type idpackage: int 4553 @return: 4554 @rtype: 4555 4556 """ 4557 self.cursor.execute('SELECT versiontag FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 4558 vtag = self.cursor.fetchone() 4559 if vtag: return vtag[0]
4560
4561 - def retrieveMirrorInfo(self, mirrorname):
4562 """ 4563 docstring_title 4564 4565 @param mirrorname: 4566 @type mirrorname: 4567 @return: 4568 @rtype: 4569 4570 """ 4571 self.cursor.execute('SELECT mirrorlink FROM mirrorlinks WHERE mirrorname = (?)', (mirrorname,)) 4572 mirrorlist = self.fetchall2set(self.cursor.fetchall()) 4573 return mirrorlist
4574
4575 - def retrieveCategory(self, idpackage):
4576 self.cursor.execute(""" 4577 SELECT category FROM baseinfo,categories 4578 WHERE baseinfo.idpackage = (?) AND 4579 baseinfo.idcategory = categories.idcategory""", (idpackage,)) 4580 cat = self.cursor.fetchone() 4581 if cat: return cat[0]
4582
4583 - def retrieveCategoryDescription(self, category):
4584 """ 4585 docstring_title 4586 4587 @param category: 4588 @type category: 4589 @return: 4590 @rtype: 4591 4592 """ 4593 data = {} 4594 self.cursor.execute('SELECT description,locale FROM categoriesdescription WHERE category = (?)', (category,)) 4595 description_data = self.cursor.fetchall() 4596 for description, locale in description_data: 4597 data[locale] = description 4598 return data
4599
4600 - def retrieveLicensedata(self, idpackage):
4601 """ 4602 docstring_title 4603 4604 @param idpackage: package indentifier 4605 @type idpackage: int 4606 @return: 4607 @rtype: 4608 4609 """ 4610 4611 # insert license information 4612 licenses = self.retrieveLicense(idpackage) 4613 if licenses == None: 4614 return {} 4615 licenses = licenses.split() 4616 licdata = {} 4617 for licname in licenses: 4618 licname = licname.strip() 4619 if not self.entropyTools.is_valid_string(licname): 4620 continue 4621 4622 self.cursor.execute('SELECT text FROM licensedata WHERE licensename = (?)', (licname,)) 4623 lictext = self.cursor.fetchone() 4624 if lictext != None: 4625 lictext = lictext[0] 4626 try: 4627 licdata[licname] = unicode(lictext, 'raw_unicode_escape') 4628 except UnicodeDecodeError: 4629 licdata[licname] = unicode(lictext, 'utf-8') 4630 4631 return licdata
4632
4633 - def retrieveLicensedataKeys(self, idpackage):
4634 """ 4635 docstring_title 4636 4637 @param idpackage: package indentifier 4638 @type idpackage: int 4639 @return: 4640 @rtype: 4641 4642 """ 4643 4644 licenses = self.retrieveLicense(idpackage) 4645 if licenses == None: 4646 return set() 4647 licenses = licenses.split() 4648 licdata = set() 4649 for licname in licenses: 4650 licname = licname.strip() 4651 if not self.entropyTools.is_valid_string(licname): 4652 continue 4653 self.cursor.execute('SELECT licensename FROM licensedata WHERE licensename = (?)', (licname,)) 4654 licidentifier = self.cursor.fetchone() 4655 if licidentifier: 4656 licdata.add(licidentifier[0]) 4657 4658 return licdata
4659
4660 - def retrieveLicenseText(self, license_name):
4661 """ 4662 docstring_title 4663 4664 @param license_name: 4665 @type license_name: 4666 @return: 4667 @rtype: 4668 4669 """ 4670 4671 self.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 4672 4673 self.cursor.execute('SELECT text FROM licensedata WHERE licensename = (?)', (license_name,)) 4674 text = self.cursor.fetchone() 4675 if not text: 4676 return None 4677 return str(text[0])
4678
4679 - def retrieveLicense(self, idpackage):
4680 """ 4681 docstring_title 4682 4683 @param idpackage: package indentifier 4684 @type idpackage: int 4685 @return: 4686 @rtype: 4687 4688 """ 4689 self.cursor.execute(""" 4690 SELECT license FROM baseinfo,licenses 4691 WHERE baseinfo.idpackage = (?) AND 4692 baseinfo.idlicense = licenses.idlicense""", (idpackage,)) 4693 licname = self.cursor.fetchone() 4694 if licname: return licname[0]
4695
4696 - def retrieveCompileFlags(self, idpackage):
4697 """ 4698 docstring_title 4699 4700 @param idpackage: package indentifier 4701 @type idpackage: int 4702 @return: 4703 @rtype: 4704 4705 """ 4706 self.cursor.execute(""" 4707 SELECT chost,cflags,cxxflags FROM flags,extrainfo 4708 WHERE extrainfo.idpackage = (?) AND 4709 extrainfo.idflags = flags.idflags""", (idpackage,)) 4710 flags = self.cursor.fetchone() 4711 if not flags: 4712 flags = ("N/A", "N/A", "N/A",) 4713 return flags
4714
4715 - def retrieveDepends(self, idpackage, atoms = False, key_slot = False, 4716 exclude_deptypes = None):
4717 """ 4718 docstring_title 4719 4720 @param idpackage: package indentifier 4721 @type idpackage: int 4722 @return: 4723 @rtype: 4724 4725 """ 4726 4727 # WARNING: never remove this, otherwise equo.db 4728 # (client database) dependstable will be always broken (trust me) 4729 # sanity check on the table 4730 if not self.isDependsTableSane(): # is empty, need generation 4731 self.regenerateDependsTable(output = False) 4732 4733 excluded_deptypes_query = "" 4734 if exclude_deptypes != None: 4735 for dep_type in exclude_deptypes: 4736 excluded_deptypes_query += " AND dependencies.type != %s" % ( 4737 dep_type,) 4738 4739 if atoms: 4740 self.cursor.execute(""" 4741 SELECT baseinfo.atom FROM dependstable,dependencies,baseinfo 4742 WHERE dependstable.idpackage = (?) AND 4743 dependstable.iddependency = dependencies.iddependency AND 4744 baseinfo.idpackage = dependencies.idpackage %s""" % ( 4745 excluded_deptypes_query,), (idpackage,)) 4746 result = self.fetchall2set(self.cursor.fetchall()) 4747 elif key_slot: 4748 self.cursor.execute(""" 4749 SELECT categories.category || "/" || baseinfo.name,baseinfo.slot 4750 FROM baseinfo,categories,dependstable,dependencies 4751 WHERE dependstable.idpackage = (?) AND 4752 dependstable.iddependency = dependencies.iddependency AND 4753 baseinfo.idpackage = dependencies.idpackage AND 4754 categories.idcategory = baseinfo.idcategory %s""" % ( 4755 excluded_deptypes_query,), (idpackage,)) 4756 result = self.cursor.fetchall() 4757 else: 4758 self.cursor.execute(""" 4759 SELECT dependencies.idpackage FROM dependstable,dependencies 4760 WHERE dependstable.idpackage = (?) AND 4761 dependstable.iddependency = dependencies.iddependency %s""" % ( 4762 excluded_deptypes_query,), (idpackage,)) 4763 result = self.fetchall2set(self.cursor.fetchall()) 4764 4765 return result
4766
4767 - def retrieveUnusedIdpackages(self):
4768 """ 4769 docstring_title 4770 4771 @return: 4772 @rtype: 4773 4774 """ 4775 4776 # WARNING: never remove this, otherwise equo.db (client database) 4777 # dependstable will be always broken (trust me) 4778 # sanity check on the table 4779 if not self.isDependsTableSane(): # is empty, need generation 4780 self.regenerateDependsTable(output = False) 4781 4782 self.cursor.execute(""" 4783 SELECT idpackage FROM baseinfo 4784 WHERE idpackage NOT IN (SELECT idpackage FROM dependstable) ORDER BY atom 4785 """) 4786 return self.fetchall2list(self.cursor.fetchall())
4787
4788 - def isPackageAvailable(self, pkgatom):
4789 """ 4790 docstring_title 4791 4792 @param pkgatom: 4793 @type pkgatom: 4794 @return: 4795 @rtype: 4796 4797 """ 4798 # You must provide the full atom to this function 4799 # WARNING: this function does not support branches 4800 pkgatom = self.entropyTools.remove_package_operators(pkgatom) 4801 self.cursor.execute('SELECT idpackage FROM baseinfo WHERE atom = (?)', (pkgatom,)) 4802 result = self.cursor.fetchone() 4803 if result: return result[0] 4804 return -1
4805
4806 - def isIDPackageAvailable(self, idpackage):
4807 """ 4808 docstring_title 4809 4810 @param idpackage: package indentifier 4811 @type idpackage: int 4812 @return: 4813 @rtype: 4814 4815 """ 4816 self.cursor.execute('SELECT idpackage FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 4817 result = self.cursor.fetchone() 4818 if not result: 4819 return False 4820 return True
4821
4822 - def areIDPackagesAvailable(self, idpackages):
4823 """ 4824 docstring_title 4825 4826 @param idpackages: list of package indentifiers 4827 @type idpackages: list 4828 @return: 4829 @rtype: 4830 4831 """ 4832 sql = 'SELECT count(idpackage) FROM baseinfo WHERE idpackage IN (%s)' % (','.join([str(x) for x in set(idpackages)]),) 4833 self.cursor.execute(sql) 4834 count = self.cursor.fetchone()[0] 4835 if count != len(idpackages): 4836 return False 4837 return True
4838
4839 - def isCategoryAvailable(self, category):
4840 """ 4841 docstring_title 4842 4843 @param category: 4844 @type category: 4845 @return: 4846 @rtype: 4847 4848 """ 4849 self.cursor.execute('SELECT idcategory FROM categories WHERE category = (?)', (category,)) 4850 result = self.cursor.fetchone() 4851 if result: return result[0] 4852 return -1
4853
4854 - def isProtectAvailable(self, protect):
4855 """ 4856 docstring_title 4857 4858 @param protect: 4859 @type protect: 4860 @return: 4861 @rtype: 4862 4863 """ 4864 self.cursor.execute('SELECT idprotect FROM configprotectreference WHERE protect = (?)', (protect,)) 4865 result = self.cursor.fetchone() 4866 if result: return result[0] 4867 return -1
4868
4869 - def isFileAvailable(self, myfile, get_id = False):
4870 """ 4871 docstring_title 4872 4873 @param myfile: 4874 @type myfile: 4875 @keyword get_id: 4876 @type get_id: 4877 @return: 4878 @rtype: 4879 4880 """ 4881 self.cursor.execute('SELECT idpackage FROM content WHERE file = (?)', (myfile,)) 4882 result = self.cursor.fetchall() 4883 if get_id: 4884 return self.fetchall2set(result) 4885 elif result: 4886 return True 4887 return False
4888
4889 - def resolveNeeded(self, needed, elfclass = -1, extended = False):
4890 """ 4891 docstring_title 4892 4893 @param needed: 4894 @type needed: 4895 @keyword elfclass: 4896 @type elfclass: 4897 @keyword extended: 4898 @type extended: 4899 @return: 4900 @rtype: 4901 4902 """ 4903 4904 args = [needed] 4905 elfclass_txt = '' 4906 4907 if extended: 4908 if elfclass != -1: 4909 elfclass_txt = ' AND neededlibraryidpackages.elfclass = (?)' 4910 args.append(elfclass) 4911 self.cursor.execute(""" 4912 SELECT neededlibraryidpackages.idpackage, 4913 neededlibrarypaths.path 4914 FROM neededlibraryidpackages, neededlibrarypaths 4915 WHERE neededlibraryidpackages.library = (?) AND 4916 neededlibraryidpackages.library = neededlibrarypaths.library AND 4917 neededlibraryidpackages.elfclass = neededlibrarypaths.elfclass 4918 """ + elfclass_txt, args) 4919 return self.cursor.fetchall() 4920 else: 4921 if elfclass != -1: 4922 elfclass_txt = ' AND elfclass = (?)' 4923 args.append(elfclass) 4924 self.cursor.execute(""" 4925 SELECT idpackage FROM neededlibraryidpackages 4926 WHERE library = (?) 4927 """ + elfclass_txt, args) 4928 return self.fetchall2set(self.cursor.fetchall())
4929
4930 - def isSourceAvailable(self, source):
4931 """ 4932 docstring_title 4933 4934 @param source: 4935 @type source: 4936 @return: 4937 @rtype: 4938 4939 """ 4940 self.cursor.execute('SELECT idsource FROM sourcesreference WHERE source = (?)', (source,)) 4941 result = self.cursor.fetchone() 4942 if result: return result[0] 4943 return -1
4944
4945 - def isDependencyAvailable(self, dependency):
4946 """ 4947 docstring_title 4948 4949 @param dependency: 4950 @type dependency: 4951 @return: 4952 @rtype: 4953 4954 """ 4955 self.cursor.execute('SELECT iddependency FROM dependenciesreference WHERE dependency = (?)', (dependency,)) 4956 result = self.cursor.fetchone() 4957 if result: return result[0] 4958 return -1
4959
4960 - def isKeywordAvailable(self, keyword):
4961 """ 4962 docstring_title 4963 4964 @param keyword: 4965 @type keyword: 4966 @return: 4967 @rtype: 4968 4969 """ 4970 self.cursor.execute('SELECT idkeyword FROM keywordsreference WHERE keywordname = (?)', (keyword,)) 4971 result = self.cursor.fetchone() 4972 if result: return result[0] 4973 return -1
4974
4975 - def isUseflagAvailable(self, useflag):
4976 """ 4977 docstring_title 4978 4979 @param useflag: 4980 @type useflag: 4981 @return: 4982 @rtype: 4983 4984 """ 4985 self.cursor.execute('SELECT idflag FROM useflagsreference WHERE flagname = (?)', (useflag,)) 4986 result = self.cursor.fetchone() 4987 if result: return result[0] 4988 return -1
4989
4990 - def isEclassAvailable(self, eclass):
4991 """ 4992 docstring_title 4993 4994 @param eclass: 4995 @type eclass: 4996 @return: 4997 @rtype: 4998 4999 """ 5000 self.cursor.execute('SELECT idclass FROM eclassesreference WHERE classname = (?)', (eclass,)) 5001 result = self.cursor.fetchone() 5002 if result: return result[0] 5003 return -1
5004
5005 - def isNeededAvailable(self, needed):
5006 """ 5007 docstring_title 5008 5009 @param needed: 5010 @type needed: 5011 @return: 5012 @rtype: 5013 5014 """ 5015 self.cursor.execute('SELECT idneeded FROM neededreference WHERE library = (?)', (needed,)) 5016 result = self.cursor.fetchone() 5017 if result: return result[0] 5018 return -1
5019
5020 - def isCounterAvailable(self, counter, branch = None, branch_operator = "="):
5021 """ 5022 docstring_title 5023 5024 @param counter: 5025 @type counter: 5026 @keyword branch: 5027 @type branch: 5028 @keyword branch_operator: 5029 @type branch_operator: 5030 @return: 5031 @rtype: 5032 5033 """ 5034 params = [counter] 5035 branch_string = '' 5036 if branch: 5037 branch_string = ' and branch '+branch_operator+' (?)' 5038 params = [counter, branch] 5039 5040 self.cursor.execute('SELECT counter FROM counters WHERE counter = (?)'+branch_string, params) 5041 result = self.cursor.fetchone() 5042 if result: return True 5043 return False
5044
5045 - def isCounterTrashed(self, counter):
5046 """ 5047 docstring_title 5048 5049 @param counter: 5050 @type counter: 5051 @return: 5052 @rtype: 5053 5054 """ 5055 self.cursor.execute('SELECT counter FROM trashedcounters WHERE counter = (?)', (counter,)) 5056 result = self.cursor.fetchone() 5057 if result: return True 5058 return False
5059
5060 - def isLicensedataKeyAvailable(self, license_name):
5061 """ 5062 docstring_title 5063 5064 @param license_name: 5065 @type license_name: 5066 @return: 5067 @rtype: 5068 5069 """ 5070 self.cursor.execute('SELECT licensename FROM licensedata WHERE licensename = (?)', (license_name,)) 5071 result = self.cursor.fetchone() 5072 if not result: 5073 return False 5074 return True
5075
5076 - def isLicenseAccepted(self, license_name):
5077 """ 5078 docstring_title 5079 5080 @param license_name: 5081 @type license_name: 5082 @return: 5083 @rtype: 5084 5085 """ 5086 self.cursor.execute('SELECT licensename FROM licenses_accepted WHERE licensename = (?)', (license_name,)) 5087 result = self.cursor.fetchone() 5088 if not result: 5089 return False 5090 return True
5091
5092 - def acceptLicense(self, license_name):
5093 """ 5094 docstring_title 5095 5096 @param license_name: 5097 @type license_name: 5098 @return: 5099 @rtype: 5100 5101 """ 5102 if self.readOnly or (not self.entropyTools.is_user_in_entropy_group()): 5103 return 5104 if self.isLicenseAccepted(license_name): 5105 return 5106 with self.__write_mutex: 5107 self.cursor.execute('INSERT INTO licenses_accepted VALUES (?)', (license_name,)) 5108 self.commitChanges()
5109
5110 - def isLicenseAvailable(self, pkglicense):
5111 """ 5112 docstring_title 5113 5114 @param pkglicense: 5115 @type pkglicense: 5116 @return: 5117 @rtype: 5118 5119 """ 5120 if not self.entropyTools.is_valid_string(pkglicense): 5121 pkglicense = ' ' 5122 self.cursor.execute('SELECT idlicense FROM licenses WHERE license = (?)', (pkglicense,)) 5123 result = self.cursor.fetchone() 5124 if result: return result[0] 5125 return -1
5126
5127 - def isSystemPackage(self, idpackage):
5128 """ 5129 docstring_title 5130 5131 @param idpackage: 5132 @type idpackage: 5133 @return: 5134 @rtype: 5135 5136 """ 5137 self.cursor.execute('SELECT idpackage FROM systempackages WHERE idpackage = (?)', (idpackage,)) 5138 result = self.cursor.fetchone() 5139 if result: 5140 return True 5141 return False
5142
5143 - def isInjected(self, idpackage):
5144 """ 5145 docstring_title 5146 5147 @param idpackage: package indentifier 5148 @type idpackage: int 5149 @return: 5150 @rtype: 5151 5152 """ 5153 self.cursor.execute('SELECT idpackage FROM injected WHERE idpackage = (?)', (idpackage,)) 5154 result = self.cursor.fetchone() 5155 if result: 5156 return True 5157 return False
5158
5159 - def areCompileFlagsAvailable(self, chost, cflags, cxxflags):
5160 """ 5161 docstring_title 5162 5163 @param chost: 5164 @type chost: 5165 @param cflags: 5166 @type cflags: 5167 @param cxxflags: 5168 @type cxxflags: 5169 @return: 5170 @rtype: 5171 5172 """ 5173 5174 self.cursor.execute('SELECT idflags FROM flags WHERE chost = (?) AND cflags = (?) AND cxxflags = (?)', 5175 (chost, cflags, cxxflags,) 5176 ) 5177 result = self.cursor.fetchone() 5178 if result: return result[0] 5179 return -1
5180
5181 - def searchBelongs(self, file, like = False, branch = None, branch_operator = "="):
5182 """ 5183 docstring_title 5184 5185 @param file: 5186 @type file: 5187 @keyword like: 5188 @type like: 5189 @keyword branch: 5190 @type branch: 5191 @keyword branch_operator: 5192 @type branch_operator: 5193 @return: 5194 @rtype: 5195 5196 """ 5197 5198 branchstring = '' 5199 searchkeywords = [file] 5200 if branch: 5201 searchkeywords.append(branch) 5202 branchstring = ' and baseinfo.branch '+branch_operator+' (?)' 5203 5204 if like: 5205 self.cursor.execute(""" 5206 SELECT content.idpackage FROM content,baseinfo 5207 WHERE file LIKE (?) AND 5208 content.idpackage = baseinfo.idpackage %s""" % (branchstring,), searchkeywords) 5209 else: 5210 self.cursor.execute("""SELECT content.idpackage FROM content,baseinfo 5211 WHERE file = (?) AND 5212 content.idpackage = baseinfo.idpackage %s""" % (branchstring,), searchkeywords) 5213 5214 return self.fetchall2set(self.cursor.fetchall())
5215 5216 ''' search packages that uses the eclass provided '''
5217 - def searchEclassedPackages(self, eclass, atoms = False): # atoms = return atoms directly
5218 """ 5219 5220 """ 5221 if atoms: 5222 self.cursor.execute(""" 5223 SELECT baseinfo.atom,eclasses.idpackage FROM baseinfo,eclasses,eclassesreference 5224 WHERE eclassesreference.classname = (?) AND 5225 eclassesreference.idclass = eclasses.idclass AND 5226 eclasses.idpackage = baseinfo.idpackage""", (eclass,)) 5227 return self.cursor.fetchall() 5228 else: 5229 self.cursor.execute('SELECT idpackage FROM baseinfo WHERE versiontag = (?)', (eclass,)) 5230 return self.fetchall2set(self.cursor.fetchall()) 5231 5232 ''' search packages whose versiontag matches the one provided '''
5233 - def searchTaggedPackages(self, tag, atoms = False): # atoms = return atoms directly
5234 """ 5235 5236 """ 5237 if atoms: 5238 self.cursor.execute('SELECT atom,idpackage FROM baseinfo WHERE versiontag = (?)', (tag,)) 5239 return self.cursor.fetchall() 5240 else: 5241 self.cursor.execute('SELECT idpackage FROM baseinfo WHERE versiontag = (?)', (tag,)) 5242 return self.fetchall2set(self.cursor.fetchall()) 5243
5244 - def searchLicenses(self, mylicense, caseSensitive = False, atoms = False):
5245 """ 5246 docstring_title 5247 5248 @param mylicense: 5249 @type mylicense: 5250 @keyword caseSensitive: 5251 @type caseSensitive: 5252 @keyword atoms: 5253 @type atoms: 5254 @return: 5255 @rtype: 5256 5257 """ 5258 5259 if not self.entropyTools.is_valid_string(mylicense): 5260 return [] 5261 5262 request = "baseinfo.idpackage" 5263 if atoms: 5264 request = "baseinfo.atom,baseinfo.idpackage" 5265 5266 if caseSensitive: 5267 self.cursor.execute(""" 5268 SELECT %s FROM baseinfo,licenses 5269 WHERE licenses.license LIKE (?) AND 5270 licenses.idlicense = baseinfo.idlicense""" % (request,), ("%"+mylicense+"%",)) 5271 else: 5272 self.cursor.execute(""" 5273 SELECT %s FROM baseinfo,licenses 5274 WHERE LOWER(licenses.license) LIKE (?) AND 5275 licenses.idlicense = baseinfo.idlicense""" % (request,), ("%"+mylicense+"%".lower(),)) 5276 if atoms: 5277 return self.cursor.fetchall() 5278 return self.fetchall2set(self.cursor.fetchall())
5279 5280 ''' search packages whose slot matches the one provided '''
5281 - def searchSlottedPackages(self, slot, atoms = False):
5282 # atoms = return atoms directly 5283 """ 5284 5285 """ 5286 if atoms: 5287 self.cursor.execute('SELECT atom,idpackage FROM baseinfo WHERE slot = (?)', (slot,)) 5288 return self.cursor.fetchall() 5289 else: 5290 self.cursor.execute('SELECT idpackage FROM baseinfo WHERE slot = (?)', (slot,)) 5291 return self.fetchall2set(self.cursor.fetchall())
5292
5293 - def searchKeySlot(self, key, slot, branch = None):
5294 """ 5295 docstring_title 5296 5297 @param key: 5298 @type key: 5299 @param slot: 5300 @type slot: 5301 @keyword branch: 5302 @type branch: 5303 @return: 5304 @rtype: 5305 5306 """ 5307 5308 branchstring = '' 5309 cat, name = key.split("/") 5310 params = [cat, name, slot] 5311 if branch: 5312 params.append(branch) 5313 branchstring = 'and baseinfo.branch = (?)' 5314 5315 self.cursor.execute(""" 5316 SELECT idpackage FROM baseinfo,categories 5317 WHERE baseinfo.idcategory = categories.idcategory AND 5318 categories.category = (?) AND 5319 baseinfo.name = (?) AND 5320 baseinfo.slot = (?) %s""" % (branchstring,), params) 5321 return self.cursor.fetchall()
5322 5323 ''' search packages that need the specified library (in neededreference table) specified by keyword '''
5324 - def searchNeeded(self, keyword, like = False):
5325 """ 5326 docstring_title 5327 5328 @param keyword: 5329 @type keyword: 5330 @keyword like: 5331 @type like: 5332 @return: 5333 @rtype: 5334 5335 """ 5336 if like: 5337 self.cursor.execute(""" 5338 SELECT needed.idpackage FROM needed,neededreference 5339 WHERE library LIKE (?) AND 5340 needed.idneeded = neededreference.idneeded""", (keyword,)) 5341 else: 5342 self.cursor.execute(""" 5343 SELECT needed.idpackage FROM needed,neededreference 5344 WHERE library = (?) AND 5345 needed.idneeded = neededreference.idneeded""", (keyword,)) 5346 return self.fetchall2set(self.cursor.fetchall())
5347 5348 ''' search dependency string inside dependenciesreference table and retrieve iddependency '''
5349 - def searchDependency(self, dep, like = False, multi = False, strings = False):
5350 """ 5351 docstring_title 5352 5353 @param dep: 5354 @type dep: 5355 @keyword like: 5356 @type like: 5357 @keyword multi: 5358 @type multi: 5359 @keyword strings: 5360 @type strings: 5361 @return: 5362 @rtype: 5363 5364 """ 5365 sign = "=" 5366 if like: 5367 sign = "LIKE" 5368 dep = "%"+dep+"%" 5369 item = 'iddependency' 5370 if strings: 5371 item = 'dependency' 5372 self.cursor.execute('SELECT %s FROM dependenciesreference WHERE dependency %s (?)' % (item, sign,), (dep,)) 5373 if multi: 5374 return self.fetchall2set(self.cursor.fetchall()) 5375 else: 5376 iddep = self.cursor.fetchone() 5377 if iddep: 5378 iddep = iddep[0] 5379 else: 5380 iddep = -1 5381 return iddep
5382 5383 ''' search iddependency inside dependencies table and retrieve idpackages '''
5384 - def searchIdpackageFromIddependency(self, iddep):
5385 """ 5386 docstring_title 5387 5388 @param iddep: 5389 @type iddep: 5390 @return: 5391 @rtype: 5392 5393 """ 5394 self.cursor.execute('SELECT idpackage FROM dependencies WHERE iddependency = (?)', (iddep,)) 5395 return self.fetchall2set(self.cursor.fetchall())
5396
5397 - def searchSets(self, keyword):
5398 """ 5399 docstring_title 5400 5401 @param keyword: 5402 @type keyword: 5403 @return: 5404 @rtype: 5405 5406 """ 5407 self.cursor.execute('SELECT DISTINCT(setname) FROM packagesets WHERE setname LIKE (?)', ("%"+keyword+"%",)) 5408 return self.fetchall2set(self.cursor.fetchall())
5409
5410 - def searchSimilarPackages(self, mystring, atom = False):
5411 """ 5412 docstring_title 5413 5414 @param mystring: 5415 @type mystring: 5416 @keyword atom: 5417 @type atom: 5418 @return: 5419 @rtype: 5420 5421 """ 5422 s_item = 'name' 5423 if atom: s_item = 'atom' 5424 self.cursor.execute(""" 5425 SELECT idpackage FROM baseinfo 5426 WHERE soundex(%s) = soundex((?)) ORDER BY %s""" % (s_item, s_item,), (mystring,)) 5427 return self.fetchall2list(self.cursor.fetchall())
5428
5429 - def searchPackages(self, keyword, sensitive = False, slot = None, tag = None, branch = None, order_by = 'atom', just_id = False):
5430 """ 5431 docstring_title 5432 5433 @param keyword: 5434 @type keyword: 5435 @keyword sensitive: 5436 @type sensitive: 5437 @keyword slot: 5438 @type slot: 5439 @keyword tag: 5440 @type tag: 5441 @keyword branch: 5442 @type branch: 5443 @keyword order_by: 5444 @type order_by: 5445 @keyword just_id: 5446 @type just_id: 5447 @return: 5448 @rtype: 5449 5450 """ 5451 5452 searchkeywords = ["%"+keyword+"%"] 5453 slotstring = '' 5454 if slot: 5455 searchkeywords.append(slot) 5456 slotstring = ' and slot = (?)' 5457 tagstring = '' 5458 if tag: 5459 searchkeywords.append(tag) 5460 tagstring = ' and versiontag = (?)' 5461 branchstring = '' 5462 if branch: 5463 searchkeywords.append(branch) 5464 branchstring = ' and branch = (?)' 5465 order_by_string = '' 5466 if order_by in ("atom", "idpackage", "branch",): 5467 order_by_string = ' order by %s' % (order_by,) 5468 5469 search_elements = 'atom,idpackage,branch' 5470 if just_id: search_elements = 'idpackage' 5471 5472 if sensitive: 5473 self.cursor.execute(""" 5474 SELECT %s FROM baseinfo WHERE atom LIKE (?) %s %s %s %s""" % ( 5475 search_elements,slotstring,tagstring,branchstring,order_by_string,), 5476 searchkeywords 5477 ) 5478 else: 5479 self.cursor.execute(""" 5480 SELECT %s FROM baseinfo WHERE 5481 LOWER(atom) LIKE (?) %s %s %s %s""" % ( 5482 search_elements,slotstring,tagstring,branchstring,order_by_string,), 5483 searchkeywords 5484 ) 5485 if just_id: 5486 return self.fetchall2list(self.cursor.fetchall()) 5487 return self.cursor.fetchall()
5488
5489 - def searchProvide(self, keyword, slot = None, tag = None, branch = None, justid = False):
5490 """ 5491 docstring_title 5492 5493 @param keyword: 5494 @type keyword: 5495 @keyword slot: 5496 @type slot: 5497 @keyword tag: 5498 @type tag: 5499 @keyword branch: 5500 @type branch: 5501 @keyword justid: 5502 @type justid: 5503 @return: 5504 @rtype: 5505 5506 """ 5507 5508 slotstring = '' 5509 searchkeywords = [keyword] 5510 if slot: 5511 searchkeywords.append(slot) 5512 slotstring = ' and baseinfo.slot = (?)' 5513 tagstring = '' 5514 if tag: 5515 searchkeywords.append(tag) 5516 tagstring = ' and baseinfo.versiontag = (?)' 5517 branchstring = '' 5518 if branch: 5519 searchkeywords.append(branch) 5520 branchstring = ' and baseinfo.branch = (?)' 5521 atomstring = '' 5522 if not justid: 5523 atomstring = 'baseinfo.atom,' 5524 5525 self.cursor.execute(""" 5526 SELECT %s baseinfo.idpackage FROM baseinfo,provide 5527 WHERE provide.atom = (?) AND 5528 provide.idpackage = baseinfo.idpackage %s %s %s""" % ( 5529 atomstring,slotstring,tagstring,branchstring,), 5530 searchkeywords 5531 ) 5532 5533 if justid: 5534 results = self.fetchall2list(self.cursor.fetchall()) 5535 else: 5536 results = self.cursor.fetchall() 5537 return results
5538
5539 - def searchPackagesByDescription(self, keyword):
5540 self.cursor.execute(""" 5541 SELECT baseinfo.atom,baseinfo.idpackage FROM extrainfo,baseinfo 5542 WHERE LOWER(extrainfo.description) LIKE (?) AND 5543 baseinfo.idpackage = extrainfo.idpackage""", ("%"+keyword.lower()+"%",)) 5544 return self.cursor.fetchall()
5545
5546 - def searchPackagesByName(self, keyword, sensitive = False, branch = None, justid = False):
5547 """ 5548 docstring_title 5549 5550 @param keyword: 5551 @type keyword: 5552 @keyword sensitive: 5553 @type sensitive: 5554 @keyword branch: 5555 @type branch: 5556 @keyword justid: 5557 @type justid: 5558 @return: 5559 @rtype: 5560 5561 """ 5562 5563 if sensitive: 5564 searchkeywords = [keyword] 5565 else: 5566 searchkeywords = [keyword.lower()] 5567 branchstring = '' 5568 atomstring = '' 5569 if not justid: 5570 atomstring = 'atom,' 5571 if branch: 5572 searchkeywords.append(branch) 5573 branchstring = ' and branch = (?)' 5574 5575 if sensitive: 5576 self.cursor.execute(""" 5577 SELECT %s idpackage FROM baseinfo 5578 WHERE name = (?) %s""" % (atomstring, branchstring,), searchkeywords) 5579 else: 5580 self.cursor.execute(""" 5581 SELECT %s idpackage FROM baseinfo 5582 WHERE LOWER(name) = (?) %s""" % (atomstring, branchstring,), searchkeywords) 5583 5584 if justid: 5585 results = self.fetchall2list(self.cursor.fetchall()) 5586 else: 5587 results = self.cursor.fetchall() 5588 return results
5589 5590
5591 - def searchPackagesByCategory(self, keyword, like = False, branch = None):
5592 """ 5593 docstring_title 5594 5595 @param keyword: 5596 @type keyword: 5597 @keyword like: 5598 @type like: 5599 @keyword branch: 5600 @type branch: 5601 @return: 5602 @rtype: 5603 5604 """ 5605 5606 searchkeywords = [keyword] 5607 branchstring = '' 5608 if branch: 5609 searchkeywords.append(branch) 5610 branchstring = 'and branch = (?)' 5611 5612 if like: 5613 self.cursor.execute(""" 5614 SELECT baseinfo.atom,baseinfo.idpackage FROM baseinfo,categories 5615 WHERE categories.category LIKE (?) AND 5616 baseinfo.idcategory = categories.idcategory %s""" % (branchstring,), searchkeywords) 5617 else: 5618 self.cursor.execute(""" 5619 SELECT baseinfo.atom,baseinfo.idpackage FROM baseinfo,categories 5620 WHERE categories.category = (?) AND 5621 baseinfo.idcategory = categories.idcategory %s""" % (branchstring,), searchkeywords) 5622 5623 return self.cursor.fetchall()
5624
5625 - def searchPackagesByNameAndCategory(self, name, category, sensitive = False, branch = None, justid = False):
5626 """ 5627 docstring_title 5628 5629 @param name: 5630 @type name: 5631 @param category: 5632 @type category: 5633 @keyword sensitive: 5634 @type sensitive: 5635 @keyword branch: 5636 @type branch: 5637 @keyword justid: 5638 @type justid: 5639 @return: 5640 @rtype: 5641 5642 """ 5643 5644 myname = name 5645 mycat = category 5646 if not sensitive: 5647 myname = name.lower() 5648 mycat = category.lower() 5649 5650 searchkeywords = [myname, mycat] 5651 branchstring = '' 5652 if branch: 5653 searchkeywords.append(branch) 5654 branchstring = ' and branch = (?)' 5655 atomstring = '' 5656 if not justid: 5657 atomstring = 'atom,' 5658 5659 if sensitive: 5660 self.cursor.execute(""" 5661 SELECT %s idpackage FROM baseinfo 5662 WHERE name = (?) AND 5663 idcategory IN ( 5664 SELECT idcategory FROM categories 5665 WHERE category = (?) 5666 ) %s""" % (atomstring, branchstring,), searchkeywords) 5667 else: 5668 self.cursor.execute(""" 5669 SELECT %s idpackage FROM baseinfo 5670 WHERE LOWER(name) = (?) AND 5671 idcategory IN ( 5672 SELECT idcategory FROM categories 5673 WHERE LOWER(category) = (?) 5674 ) %s""" % (atomstring, branchstring,), searchkeywords) 5675 5676 if justid: 5677 results = self.fetchall2list(self.cursor.fetchall()) 5678 else: 5679 results = self.cursor.fetchall() 5680 return results
5681
5682 - def isPackageScopeAvailable(self, atom, slot, revision):
5683 """ 5684 docstring_title 5685 5686 @param atom: 5687 @type atom: 5688 @param slot: 5689 @type slot: 5690 @param revision: 5691 @type revision: 5692 @return: 5693 @rtype: 5694 5695 """ 5696 searchdata = (atom, slot, revision,) 5697 self.cursor.execute('SELECT idpackage FROM baseinfo where atom = (?) and slot = (?) and revision = (?)', searchdata) 5698 rslt = self.cursor.fetchone() 5699 idreason = 0 5700 idpackage = -1 5701 if rslt: 5702 # check if it's masked 5703 idpackage, idreason = self.idpackageValidator(rslt[0]) 5704 return idpackage, idreason
5705
5706 - def isBranchMigrationAvailable(self, repository, from_branch, to_branch):
5707 """ 5708 Returns whether branch migration metadata given by the provided key 5709 (repository, from_branch, to_branch,) is available. 5710 5711 @param repository: repository identifier 5712 @type repository: string 5713 @param from_branch: original branch 5714 @type from_branch: string 5715 @param to_branch: destination branch 5716 @type to_branch: string 5717 @return: tuple composed by (1)post migration script md5sum and 5718 (2)post upgrade script md5sum 5719 @rtype: tuple 5720 """ 5721 self.cursor.execute(""" 5722 SELECT post_migration_md5sum, post_upgrade_md5sum 5723 FROM entropy_branch_migration 5724 WHERE repository = (?) AND from_branch = (?) AND to_branch = (?) 5725 """, (repository, from_branch, to_branch,)) 5726 return self.cursor.fetchone()
5727
5728 - def listAllPackages(self, get_scope = False, order_by = None, branch = None, branch_operator = "="):
5729 """ 5730 docstring_title 5731 5732 @keyword get_scope: 5733 @type get_scope: 5734 @keyword order_by: 5735 @type order_by: 5736 @keyword branch: 5737 @type branch: 5738 @keyword branch_operator: 5739 @type branch_operator: 5740 @return: 5741 @rtype: 5742 5743 """ 5744 5745 branchstring = '' 5746 searchkeywords = [] 5747 if branch: 5748 searchkeywords = [branch] 5749 branchstring = ' where branch %s (?)' % (branch_operator,) 5750 5751 order_txt = '' 5752 if order_by: 5753 order_txt = ' order by %s' % (order_by,) 5754 if get_scope: 5755 self.cursor.execute('SELECT idpackage,atom,slot,revision FROM baseinfo'+order_txt+branchstring, searchkeywords) 5756 else: 5757 self.cursor.execute('SELECT atom,idpackage,branch FROM baseinfo'+order_txt+branchstring, searchkeywords) 5758 return self.cursor.fetchall()
5759
5760 - def listAllInjectedPackages(self, justFiles = False):
5761 """ 5762 docstring_title 5763 5764 @keyword justFiles: 5765 @type justFiles: 5766 @return: 5767 @rtype: 5768 5769 """ 5770 self.cursor.execute('SELECT idpackage FROM injected') 5771 injecteds = self.fetchall2set(self.cursor.fetchall()) 5772 results = set() 5773 # get download 5774 for injected in injecteds: 5775 download = self.retrieveDownloadURL(injected) 5776 if justFiles: 5777 results.add(download) 5778 else: 5779 results.add((download, injected)) 5780 return results
5781
5782 - def listAllCounters(self, onlycounters = False, branch = None, branch_operator = "="):
5783 """ 5784 docstring_title 5785 5786 @keyword onlycounters: 5787 @type onlycounters: 5788 @keyword branch: 5789 @type branch: 5790 @keyword branch_operator: 5791 @type branch_operator: 5792 @return: 5793 @rtype: 5794 5795 """ 5796 5797 branchstring = '' 5798 if branch: 5799 branchstring = ' WHERE branch '+branch_operator+' "'+str(branch)+'"' 5800 if onlycounters: 5801 self.cursor.execute('SELECT counter FROM counters'+branchstring) 5802 return self.fetchall2set(self.cursor.fetchall()) 5803 else: 5804 self.cursor.execute('SELECT counter,idpackage FROM counters'+branchstring) 5805 return self.cursor.fetchall()
5806
5807 - def listAllIdpackages(self, branch = None, branch_operator = "=", order_by = None):
5808 """ 5809 docstring_title 5810 5811 @keyword branch: 5812 @type branch: 5813 @keyword branch_operator: 5814 @type branch_operator: 5815 @keyword order_by: 5816 @type order_by: 5817 @return: 5818 @rtype: 5819 5820 """ 5821 5822 branchstring = '' 5823 orderbystring = '' 5824 searchkeywords = [] 5825 if branch: 5826 searchkeywords.append(branch) 5827 branchstring = ' where branch %s (?)' % (str(branch_operator),) 5828 if order_by: 5829 orderbystring = ' order by '+order_by 5830 5831 self.cursor.execute('SELECT idpackage FROM baseinfo'+branchstring+orderbystring, searchkeywords) 5832 5833 try: 5834 if order_by: 5835 results = self.fetchall2list(self.cursor.fetchall()) 5836 else: 5837 results = self.fetchall2set(self.cursor.fetchall()) 5838 return results 5839 except self.dbapi2.OperationalError: 5840 if order_by: 5841 return [] 5842 return set()
5843
5844 - def listAllDependencies(self, only_deps = False):
5845 """ 5846 docstring_title 5847 5848 @keyword only_deps: 5849 @type only_deps: 5850 @return: 5851 @rtype: 5852 5853 """ 5854 if only_deps: 5855 self.cursor.execute('SELECT dependency FROM dependenciesreference') 5856 return self.fetchall2set(self.cursor.fetchall()) 5857 else: 5858 self.cursor.execute('SELECT * FROM dependenciesreference') 5859 return self.cursor.fetchall()
5860
5861 - def listAllBranches(self):
5862 """ 5863 docstring_title 5864 5865 @return: 5866 @rtype: 5867 5868 """ 5869 5870 cache = self.live_cache.get('listAllBranches') 5871 if cache != None: 5872 return cache 5873 5874 self.cursor.execute('SELECT distinct branch FROM baseinfo') 5875 results = self.fetchall2set(self.cursor.fetchall()) 5876 5877 self.live_cache['listAllBranches'] = results.copy() 5878 return results
5879
5880 - def listIdPackagesInIdcategory(self, idcategory, order_by = 'atom'):
5881 """ 5882 docstring_title 5883 5884 @param idcategory: 5885 @type idcategory: 5886 @keyword order_by: 5887 @type order_by: 5888 @return: 5889 @rtype: 5890 5891 """ 5892 order_by_string = '' 5893 if order_by in ("atom", "name", "version",): 5894 order_by_string = ' ORDER BY %s' % (order_by,) 5895 self.cursor.execute('SELECT idpackage FROM baseinfo where idcategory = (?)'+order_by_string, (idcategory,)) 5896 return self.fetchall2set(self.cursor.fetchall())
5897
5898 - def listIdpackageDependencies(self, idpackage):
5899 self.cursor.execute(""" 5900 SELECT dependenciesreference.iddependency,dependenciesreference.dependency FROM dependenciesreference,dependencies 5901 WHERE dependencies.idpackage = (?) AND 5902 dependenciesreference.iddependency = dependencies.iddependency""", (idpackage,)) 5903 return set(self.cursor.fetchall())
5904
5905 - def listAllDownloads(self, do_sort = True, full_path = False):
5906 """ 5907 docstring_title 5908 5909 @keyword do_sort: 5910 @type do_sort: 5911 @keyword full_path: 5912 @type full_path: 5913 @return: 5914 @rtype: 5915 5916 """ 5917 5918 order_string = '' 5919 if do_sort: 5920 order_string = 'ORDER BY extrainfo.download' 5921 self.cursor.execute(""" 5922 SELECT extrainfo.download FROM baseinfo,extrainfo 5923 WHERE baseinfo.idpackage = extrainfo.idpackage %s""" % (order_string,)) 5924 5925 if do_sort: 5926 results = self.fetchall2list(self.cursor.fetchall()) 5927 else: 5928 results = self.fetchall2set(self.cursor.fetchall()) 5929 5930 if not full_path: 5931 results = [os.path.basename(x) for x in results] 5932 5933 return results
5934
5935 - def listAllFiles(self, clean = False, count = False):
5936 """ 5937 docstring_title 5938 5939 @keyword clean: 5940 @type clean: 5941 @keyword count: 5942 @type count: 5943 @return: 5944 @rtype: 5945 5946 """ 5947 self.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 5948 if count: 5949 self.cursor.execute('SELECT count(file) FROM content') 5950 else: 5951 self.cursor.execute('SELECT file FROM content') 5952 if count: 5953 return self.cursor.fetchone()[0] 5954 else: 5955 if clean: 5956 return self.fetchall2set(self.cursor.fetchall()) 5957 else: 5958 return self.fetchall2list(self.cursor.fetchall())
5959
5960 - def listAllCategories(self, order_by = ''):
5961 """ 5962 docstring_title 5963 5964 @keyword order_by: 5965 @type order_by: 5966 @return: 5967 @rtype: 5968 5969 """ 5970 order_by_string = '' 5971 if order_by: order_by_string = ' order by %s' % (order_by,) 5972 self.cursor.execute('SELECT idcategory,category FROM categories %s' % ( 5973 order_by_string,)) 5974 return self.cursor.fetchall()
5975
5976 - def listConfigProtectDirectories(self, mask = False):
5977 """ 5978 docstring_title 5979 5980 @keyword mask: 5981 @type mask: 5982 @return: 5983 @rtype: 5984 5985 """ 5986 mask_t = '' 5987 if mask: mask_t = 'mask' 5988 self.cursor.execute(""" 5989 SELECT DISTINCT(protect) FROM configprotectreference 5990 WHERE idprotect >= 1 AND 5991 idprotect <= (SELECT max(idprotect) FROM configprotect%s) 5992 ORDER BY protect""" % (mask_t,)) 5993 results = self.fetchall2set(self.cursor.fetchall()) 5994 dirs = set() 5995 for mystr in results: 5996 dirs |= set(map(unicode, mystr.split())) 5997 return sorted(list(dirs))
5998
5999 - def switchBranch(self, idpackage, tobranch):
6000 with self.__write_mutex: 6001 self.cursor.execute(""" 6002 UPDATE baseinfo SET branch = (?) 6003 WHERE idpackage = (?)""", (tobranch, idpackage,)) 6004 self.commitChanges() 6005 self.clearCache() 6006
6007 - def databaseStructureUpdates(self):
6008 """ 6009 docstring_title 6010 6011 @return: 6012 @rtype: 6013 6014 """ 6015 6016 old_readonly = self.readOnly 6017 self.readOnly = False 6018 6019 if not self.doesTableExist("licenses_accepted"): 6020 self.createLicensesAcceptedTable() 6021 6022 if not self.doesTableExist("installedtable"): 6023 self.createInstalledTable() 6024 6025 if not self.doesColumnInTableExist("installedtable", "source"): 6026 self.createInstalledTableSource() 6027 6028 if not self.doesTableExist('packagesets'): 6029 self.createPackagesetsTable() 6030 6031 if not self.doesTableExist('packagechangelogs'): 6032 self.createPackagechangelogsTable() 6033 6034 if not self.doesTableExist('automergefiles'): 6035 self.createAutomergefilesTable() 6036 6037 if not self.doesTableExist('packagesignatures'): 6038 self.createPackagesignaturesTable() 6039 6040 if not self.doesTableExist('packagespmphases'): 6041 self.createPackagespmphases() 6042 6043 if not self.doesTableExist('entropy_branch_migration'): 6044 self.createEntropyBranchMigrationTable() 6045 6046 if not self.doesTableExist('neededlibrarypaths'): 6047 self.createNeededlibrarypathsTable() 6048 if not self.doesColumnInTableExist("neededlibrarypaths", "elfclass"): 6049 self.createNeededlibrarypathsTable() 6050 6051 if not self.doesTableExist('neededlibraryidpackages'): 6052 self.createNeededlibraryidpackagesTable() 6053 elif not self.doesColumnInTableExist("neededlibraryidpackages", "elfclass"): 6054 self.createNeededlibraryidpackagesTable() 6055 6056 if not self.doesTableExist('dependstable'): 6057 self.createDependsTable() 6058 6059 self.readOnly = old_readonly 6060 self.connection.commit()
6061
6062 - def validateDatabase(self):
6063 """ 6064 docstring_title 6065 6066 @return: 6067 @rtype: 6068 6069 """ 6070 self.cursor.execute('select name from SQLITE_MASTER where type = (?) and name = (?)', ("table", "baseinfo")) 6071 rslt = self.cursor.fetchone() 6072 if rslt == None: 6073 mytxt = _("baseinfo table not found. Either does not exist or corrupted.") 6074 raise SystemDatabaseError("SystemDatabaseError: %s" % (mytxt,)) 6075 self.cursor.execute('select name from SQLITE_MASTER where type = (?) and name = (?)', ("table", "extrainfo")) 6076 rslt = self.cursor.fetchone() 6077 if rslt == None: 6078 mytxt = _("extrainfo table not found. Either does not exist or corrupted.") 6079 raise SystemDatabaseError("SystemDatabaseError: %s" % (mytxt,))
6080
6081 - def getIdpackagesDifferences(self, foreign_idpackages):
6082 """ 6083 docstring_title 6084 6085 @param foreign_idpackages: 6086 @type foreign_idpackages: 6087 @return: 6088 @rtype: 6089 6090 """ 6091 myids = self.listAllIdpackages() 6092 if isinstance(foreign_idpackages, (list, tuple,)): 6093 outids = set(foreign_idpackages) 6094 else: 6095 outids = foreign_idpackages 6096 added_ids = outids - myids 6097 removed_ids = myids - outids 6098 return added_ids, removed_ids
6099
6100 - def uniformBranch(self, branch):
6101 """ 6102 docstring_title 6103 6104 @param branch: 6105 @type branch: 6106 @return: 6107 @rtype: 6108 6109 """ 6110 with self.__write_mutex: 6111 self.cursor.execute('UPDATE baseinfo SET branch = (?)', (branch,)) 6112 self.commitChanges() 6113 self.clearCache()
6114
6115 - def alignDatabases(self, dbconn, force = False, output_header = " ", align_limit = 300):
6116 """ 6117 docstring_title 6118 6119 @param dbconn: 6120 @type dbconn: 6121 @keyword force: 6122 @type force: 6123 @keyword output_header: 6124 @type output_header: 6125 @keyword align_limit: 6126 @type align_limit: 6127 @return: 6128 @rtype: 6129 6130 """ 6131 6132 added_ids, removed_ids = self.getIdpackagesDifferences(dbconn.listAllIdpackages()) 6133 6134 if not force: 6135 if len(added_ids) > align_limit: # too much hassle 6136 return 0 6137 if len(removed_ids) > align_limit: # too much hassle 6138 return 0 6139 6140 if not added_ids and not removed_ids: 6141 return -1 6142 6143 mytxt = red("%s, %s ...") % (_("Syncing current database"), _("please wait"),) 6144 self.updateProgress( 6145 mytxt, 6146 importance = 1, 6147 type = "info", 6148 header = output_header, 6149 back = True 6150 ) 6151 maxcount = len(removed_ids) 6152 mycount = 0 6153 for idpackage in removed_ids: 6154 mycount += 1 6155 mytxt = "%s: %s" % (red(_("Removing entry")), blue(str(self.retrieveAtom(idpackage))),) 6156 self.updateProgress( 6157 mytxt, 6158 importance = 0, 6159 type = "info", 6160 header = output_header, 6161 back = True, 6162 count = (mycount, maxcount) 6163 ) 6164 self.removePackage(idpackage, do_cleanup = False, do_commit = False) 6165 6166 maxcount = len(added_ids) 6167 mycount = 0 6168 for idpackage in added_ids: 6169 mycount += 1 6170 mytxt = "%s: %s" % (red(_("Adding entry")), blue(str(dbconn.retrieveAtom(idpackage))),) 6171 self.updateProgress( 6172 mytxt, 6173 importance = 0, 6174 type = "info", 6175 header = output_header, 6176 back = True, 6177 count = (mycount, maxcount) 6178 ) 6179 mydata = dbconn.getPackageData(idpackage, get_content = True, content_insert_formatted = True) 6180 self.addPackage( 6181 mydata, 6182 revision = mydata['revision'], 6183 idpackage = idpackage, 6184 do_commit = False, 6185 formatted_content = True 6186 ) 6187 6188 # do some cleanups 6189 self.doCleanups() 6190 # clear caches 6191 self.clearCache() 6192 self.commitChanges() 6193 self.regenerateDependsTable(output = False) 6194 dbconn.clearCache() 6195 6196 # verify both checksums, if they don't match, bomb out 6197 mycheck = self.database_checksum(do_order = True, strict = False) 6198 outcheck = dbconn.database_checksum(do_order = True, strict = False) 6199 if mycheck == outcheck: 6200 return 1 6201 return 0
6202
6203 - def checkDatabaseApi(self):
6204 """ 6205 docstring_title 6206 6207 @return: 6208 @rtype: 6209 6210 """ 6211 6212 dbapi = self.getApi() 6213 if int(dbapi) > int(etpConst['etpapi']): 6214 self.updateProgress( 6215 red(_("Repository EAPI > Entropy EAPI. Please update Equo/Entropy as soon as possible !")), 6216 importance = 1, 6217 type = "warning", 6218 header = " * ! * ! * ! * " 6219 )
6220
6221 - def doDatabaseImport(self, dumpfile, dbfile):
6222 """ 6223 docstring_title 6224 6225 @param dumpfile: 6226 @type dumpfile: 6227 @param dbfile: 6228 @type dbfile: 6229 @return: 6230 @rtype: 6231 6232 """ 6233 import subprocess 6234 sqlite3_exec = "/usr/bin/sqlite3 %s < %s" % (dbfile, dumpfile,) 6235 retcode = subprocess.call(sqlite3_exec, shell = True) 6236 return retcode
6237
6238 - def doDatabaseExport(self, dumpfile, gentle_with_tables = True, 6239 exclude_tables = None):
6240 6241 """ 6242 6243 """ 6244 6245 if not exclude_tables: 6246 exclude_tables = [] 6247 6248 dumpfile.write("BEGIN TRANSACTION;\n") 6249 self.cursor.execute("SELECT name, type, sql FROM sqlite_master WHERE sql NOT NULL AND type=='table'") 6250 for name, x, sql in self.cursor.fetchall(): 6251 6252 self.updateProgress( 6253 red("%s " % (_("Exporting database table"),) )+"["+blue(str(name))+"]", 6254 importance = 0, 6255 type = "info", 6256 back = True, 6257 header = " " 6258 ) 6259 6260 if name == "sqlite_sequence": 6261 dumpfile.write("DELETE FROM sqlite_sequence;\n") 6262 elif name == "sqlite_stat1": 6263 dumpfile.write("ANALYZE sqlite_master;\n") 6264 elif name.startswith("sqlite_"): 6265 continue 6266 else: 6267 t_cmd = "CREATE TABLE" 6268 if sql.startswith(t_cmd) and gentle_with_tables: 6269 sql = "CREATE TABLE IF NOT EXISTS"+sql[len(t_cmd):] 6270 dumpfile.write("%s;\n" % sql) 6271 6272 if name in exclude_tables: 6273 continue 6274 6275 self.cursor.execute("PRAGMA table_info('%s')" % name) 6276 cols = [str(r[1]) for r in self.cursor.fetchall()] 6277 q = "SELECT 'INSERT INTO \"%(tbl_name)s\" VALUES(" 6278 q += ", ".join(["'||quote(" + x + ")||'" for x in cols]) 6279 q += ")' FROM '%(tbl_name)s'" 6280 self.cursor.execute(q % {'tbl_name': name}) 6281 self.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 6282 for row in self.cursor: 6283 dumpfile.write("%s;\n" % str(row[0].encode('raw_unicode_escape'))) 6284 6285 self.cursor.execute("SELECT name, type, sql FROM sqlite_master WHERE sql NOT NULL AND type!='table' AND type!='meta'") 6286 for name, x, sql in self.cursor.fetchall(): 6287 dumpfile.write("%s;\n" % sql) 6288 6289 dumpfile.write("COMMIT;\n") 6290 try: 6291 dumpfile.flush() 6292 except: 6293 pass 6294 self.updateProgress( 6295 red(_("Database Export completed.")), 6296 importance = 0, 6297 type = "info", 6298 header = " " 6299 )
6300 # remember to close the file 6301
6302 - def listAllTables(self):
6303 """ 6304 6305 """ 6306 self.cursor.execute(""" 6307 SELECT name FROM SQLITE_MASTER WHERE type = "table" 6308 """) 6309 return self.fetchall2list(self.cursor.fetchall())
6310
6311 - def doesTableExist(self, table):
6312 """ 6313 docstring_title 6314 6315 @param table: 6316 @type table: 6317 @return: 6318 @rtype: 6319 6320 """ 6321 self.cursor.execute('select name from SQLITE_MASTER where type = "table" and name = (?)', (table,)) 6322 rslt = self.cursor.fetchone() 6323 if rslt == None: 6324 return False 6325 return True
6326
6327 - def doesColumnInTableExist(self, table, column):
6328 """ 6329 docstring_title 6330 6331 @param table: 6332 @type table: 6333 @param column: 6334 @type column: 6335 @return: 6336 @rtype: 6337 6338 """ 6339 self.cursor.execute('PRAGMA table_info( %s )' % (table,)) 6340 rslt = (x[1] for x in self.cursor.fetchall()) 6341 if column in rslt: 6342 return True 6343 return False
6344
6345 - def database_checksum(self, do_order = False, strict = True, strings = False):
6346 """ 6347 docstring_title 6348 6349 @keyword do_order: 6350 @type do_order: 6351 @keyword strict: 6352 @type strict: 6353 @keyword strings: 6354 @type strings: 6355 @return: 6356 @rtype: 6357 6358 """ 6359 6360 c_tup = ("database_checksum", do_order, strict, strings,) 6361 cache = self.live_cache.get(c_tup) 6362 if cache != None: return cache 6363 6364 idpackage_order = '' 6365 category_order = '' 6366 license_order = '' 6367 flags_order = '' 6368 if do_order: 6369 idpackage_order = 'order by idpackage' 6370 category_order = 'order by category' 6371 license_order = 'order by license' 6372 flags_order = 'order by chost' 6373 6374 def do_update_md5(m, cursor): 6375 """ 6376 docstring_title 6377 6378 @param m: 6379 @type m: 6380 @param cursor: 6381 @type cursor: 6382 @return: 6383 @rtype: 6384 6385 """ 6386 mydata = cursor.fetchall() 6387 for record in mydata: 6388 for item in record: 6389 m.update(str(item))
6390 6391 if strings: 6392 import hashlib 6393 m = hashlib.md5() 6394 6395 self.cursor.execute(""" 6396 SELECT idpackage,atom,name,version,versiontag, 6397 revision,branch,slot,etpapi,trigger FROM 6398 baseinfo %s""" % (idpackage_order,)) 6399 if strings: 6400 do_update_md5(m, self.cursor) 6401 else: 6402 a_hash = hash(tuple(self.cursor.fetchall())) 6403 self.cursor.execute(""" 6404 SELECT idpackage,description,homepage, 6405 download,size,digest,datecreation FROM 6406 extrainfo %s""" % (idpackage_order,)) 6407 if strings: 6408 do_update_md5(m, self.cursor) 6409 else: 6410 b_hash = hash(tuple(self.cursor.fetchall())) 6411 self.cursor.execute('select category from categories %s' % (category_order,)) 6412 if strings: 6413 do_update_md5(m, self.cursor) 6414 else: 6415 c_hash = hash(tuple(self.cursor.fetchall())) 6416 d_hash = '0' 6417 e_hash = '0' 6418 if strict: 6419 self.cursor.execute('select * from licenses %s' % (license_order,)) 6420 if strings: 6421 do_update_md5(m, self.cursor) 6422 else: 6423 d_hash = hash(tuple(self.cursor.fetchall())) 6424 self.cursor.execute('select * from flags %s' % (flags_order,)) 6425 if strings: 6426 do_update_md5(m, self.cursor) 6427 else: 6428 e_hash = hash(tuple(self.cursor.fetchall())) 6429 6430 if strings: 6431 result = m.hexdigest() 6432 else: 6433 result = "%s:%s:%s:%s:%s" % (a_hash, b_hash, c_hash, d_hash, e_hash,) 6434 6435 self.live_cache[c_tup] = result[:] 6436 return result 6437 6438 6439 ######################################################## 6440 #### 6441 ## Client Database API / but also used by server part 6442 # 6443
6444 - def updateInstalledTableSource(self, idpackage, source):
6445 """ 6446 docstring_title 6447 6448 @param idpackage: 6449 @type idpackage: 6450 @param source: 6451 @type source: 6452 @return: 6453 @rtype: 6454 6455 """ 6456 with self.__write_mutex: 6457 self.cursor.execute(""" 6458 UPDATE installedtable SET source = (?) WHERE idpackage = (?) 6459 """, (source, idpackage,))
6460
6461 - def addPackageToInstalledTable(self, idpackage, repoid, source = 0):
6462 """ 6463 docstring_title 6464 6465 @param idpackage: 6466 @type idpackage: 6467 @param repoid: 6468 @type repoid: 6469 @keyword source: 6470 @type source: 6471 @return: 6472 @rtype: 6473 6474 """ 6475 with self.__write_mutex: 6476 self.cursor.execute('INSERT into installedtable VALUES (?,?,?)', 6477 (idpackage, repoid, source,))
6478 # self.commitChanges() 6479
6480 - def retrievePackageFromInstalledTable(self, idpackage):
6481 """ 6482 docstring_title 6483 6484 @param idpackage: 6485 @type idpackage: 6486 @return: 6487 @rtype: 6488 6489 """ 6490 with self.__write_mutex: 6491 try: 6492 self.cursor.execute(""" 6493 SELECT repositoryname FROM installedtable 6494 WHERE idpackage = (?)""", (idpackage,)) 6495 return self.cursor.fetchone()[0] 6496 except (self.dbapi2.OperationalError,TypeError,): 6497 return 'Not available'
6498
6499 - def removePackageFromInstalledTable(self, idpackage):
6500 """ 6501 docstring_title 6502 6503 @param idpackage: 6504 @type idpackage: 6505 @return: 6506 @rtype: 6507 6508 """ 6509 with self.__write_mutex: 6510 self.cursor.execute(""" 6511 DELETE FROM installedtable 6512 WHERE idpackage = (?)""", (idpackage,))
6513
6514 - def removePackageFromDependsTable(self, idpackage):
6515 """ 6516 docstring_title 6517 6518 @param idpackage: 6519 @type idpackage: 6520 @return: 6521 @rtype: 6522 6523 """ 6524 with self.__write_mutex: 6525 try: 6526 self.cursor.execute('DELETE FROM dependstable WHERE idpackage = (?)', (idpackage,)) 6527 return 0 6528 except (self.dbapi2.OperationalError,): 6529 return 1 # need reinit
6530
6531 - def createDependsTable(self):
6532 """ 6533 docstring_title 6534 6535 @return: 6536 @rtype: 6537 6538 """ 6539 with self.__write_mutex: 6540 self.cursor.executescript(""" 6541 CREATE TABLE IF NOT EXISTS dependstable ( iddependency INTEGER PRIMARY KEY, idpackage INTEGER ); 6542 INSERT INTO dependstable VALUES (-1,-1); 6543 """) 6544 if self.indexing: 6545 self.cursor.execute('CREATE INDEX IF NOT EXISTS dependsindex_idpackage ON dependstable ( idpackage )') 6546 self.commitChanges()
6547
6548 - def sanitizeDependsTable(self):
6549 """ 6550 docstring_title 6551 6552 @return: 6553 @rtype: 6554 6555 """ 6556 with self.__write_mutex: 6557 self.cursor.execute('DELETE FROM dependstable where iddependency = -1') 6558 self.commitChanges()
6559
6560 - def isDependsTableSane(self):
6561 """ 6562 docstring_title 6563 6564 @return: 6565 @rtype: 6566 6567 """ 6568 try: 6569 self.cursor.execute('SELECT iddependency FROM dependstable WHERE iddependency = -1') 6570 except (self.dbapi2.OperationalError,): 6571 return False # table does not exist, please regenerate and re-run 6572 status = self.cursor.fetchone() 6573 if status: return False 6574 6575 self.cursor.execute('select count(*) from dependstable') 6576 dependstable_count = self.cursor.fetchone() 6577 if dependstable_count < 2: 6578 return False 6579 return True
6580
6581 - def createXpakTable(self):
6582 """ 6583 docstring_title 6584 6585 @return: 6586 @rtype: 6587 6588 """ 6589 with self.__write_mutex: 6590 self.cursor.execute('CREATE TABLE xpakdata ( idpackage INTEGER PRIMARY KEY, data BLOB );') 6591 self.commitChanges()
6592
6593 - def storeXpakMetadata(self, idpackage, blob):
6594 """ 6595 docstring_title 6596 6597 @param idpackage: 6598 @type idpackage: 6599 @param blob: 6600 @type blob: 6601 @return: 6602 @rtype: 6603 6604 """ 6605 with self.__write_mutex: 6606 self.cursor.execute('INSERT into xpakdata VALUES (?,?)', (int(idpackage), buffer(blob),)) 6607 self.commitChanges()
6608
6609 - def retrieveXpakMetadata(self, idpackage):
6610 """ 6611 docstring_title 6612 6613 @param idpackage: 6614 @type idpackage: 6615 @return: 6616 @rtype: 6617 6618 """ 6619 try: 6620 self.cursor.execute('SELECT data from xpakdata where idpackage = (?)', (idpackage,)) 6621 mydata = self.cursor.fetchone() 6622 if not mydata: 6623 return "" 6624 return mydata[0] 6625 except: 6626 return ""
6627
6628 - def retrieveBranchMigration(self, to_branch):
6629 """ 6630 This method returns branch migration metadata stored in Entropy 6631 Client database (installed packages database). It is used to 6632 determine whether to run per-repository branch migration scripts. 6633 6634 @param to_branch: usually the current branch string 6635 @type to_branch: string 6636 @return: branch migration metadata contained in database 6637 @rtype: dict 6638 """ 6639 if not self.doesTableExist('entropy_branch_migration'): 6640 return None 6641 6642 self.cursor.execute(""" 6643 SELECT repository, from_branch, post_migration_md5sum, 6644 post_upgrade_md5sum FROM entropy_branch_migration WHERE to_branch = (?) 6645 """, (to_branch,)) 6646 6647 data = self.cursor.fetchall() 6648 meta = {} 6649 for repo, from_branch, post_migration_md5, post_upgrade_md5 in data: 6650 obj = meta.setdefault(repo, {}) 6651 obj[from_branch] = (post_migration_md5, post_upgrade_md5,) 6652 return meta
6653
6654 - def dropContent(self):
6655 """ 6656 docstring_title 6657 6658 @return: 6659 @rtype: 6660 6661 """ 6662 with self.__write_mutex: 6663 self.cursor.execute('DELETE FROM content')
6664
6665 - def dropAllIndexes(self):
6666 """ 6667 docstring_title 6668 6669 @return: 6670 @rtype: 6671 6672 """ 6673 self.cursor.execute('SELECT name FROM SQLITE_MASTER WHERE type = "index"') 6674 indexes = self.fetchall2set(self.cursor.fetchall()) 6675 with self.__write_mutex: 6676 for index in indexes: 6677 if not index.startswith("sqlite"): 6678 self.cursor.execute('DROP INDEX IF EXISTS %s' % (index,))
6679
6680 - def listAllIndexes(self, only_entropy = True):
6681 """ 6682 docstring_title 6683 6684 @keyword only_entropy: 6685 @type only_entropy: 6686 @return: 6687 @rtype: 6688 6689 """ 6690 self.cursor.execute('SELECT name FROM SQLITE_MASTER WHERE type = "index"') 6691 indexes = self.fetchall2set(self.cursor.fetchall()) 6692 if not only_entropy: 6693 return indexes 6694 myindexes = set() 6695 for index in indexes: 6696 if index.startswith("sqlite"): 6697 continue 6698 myindexes.add(index) 6699 return myindexes
6700 6701
6702 - def createAllIndexes(self):
6703 """ 6704 docstring_title 6705 6706 @return: 6707 @rtype: 6708 6709 """ 6710 self.createContentIndex() 6711 self.createBaseinfoIndex() 6712 self.createKeywordsIndex() 6713 self.createDependenciesIndex() 6714 self.createProvideIndex() 6715 self.createConflictsIndex() 6716 self.createExtrainfoIndex() 6717 self.createNeededIndex() 6718 self.createUseflagsIndex() 6719 self.createLicensedataIndex() 6720 self.createLicensesIndex() 6721 self.createConfigProtectReferenceIndex() 6722 self.createMessagesIndex() 6723 self.createSourcesIndex() 6724 self.createCountersIndex() 6725 self.createEclassesIndex() 6726 self.createCategoriesIndex() 6727 self.createCompileFlagsIndex() 6728 self.createPackagesetsIndex() 6729 self.createAutomergefilesIndex() 6730 self.createNeededlibrarypathsIndex() 6731 self.createNeededlibraryidpackagesIndex()
6732
6733 - def createPackagesetsIndex(self):
6734 """ 6735 docstring_title 6736 6737 @return: 6738 @rtype: 6739 6740 """ 6741 if self.indexing: 6742 with self.__write_mutex: 6743 try: 6744 self.cursor.execute('CREATE INDEX IF NOT EXISTS packagesetsindex ON packagesets ( setname )') 6745 self.commitChanges() 6746 except self.dbapi2.OperationalError: 6747 pass
6748
6749 - def createNeededlibraryidpackagesIndex(self):
6750 """ 6751 docstring_title 6752 6753 @return: 6754 @rtype: 6755 6756 """ 6757 if self.indexing: 6758 with self.__write_mutex: 6759 try: 6760 self.cursor.executescript(""" 6761 CREATE INDEX IF NOT EXISTS neededlibidpackages_library 6762 ON neededlibraryidpackages ( library ); 6763 CREATE INDEX IF NOT EXISTS neededlibidpackages_idpackage 6764 ON neededlibraryidpackages ( idpackage ); 6765 CREATE INDEX IF NOT EXISTS neededlibidpackages_lib_elf 6766 ON neededlibraryidpackages ( library, elfclass ); 6767 """) 6768 except self.dbapi2.OperationalError: 6769 pass
6770
6771 - def createNeededlibrarypathsIndex(self):
6772 """ 6773 docstring_title 6774 6775 @return: 6776 @rtype: 6777 6778 """ 6779 if self.indexing: 6780 with self.__write_mutex: 6781 try: 6782 self.cursor.executescript(""" 6783 CREATE INDEX IF NOT EXISTS neededlibpaths_library 6784 ON neededlibrarypaths ( library ); 6785 CREATE INDEX IF NOT EXISTS neededlibpaths_elf 6786 ON neededlibrarypaths ( elfclass ); 6787 CREATE INDEX IF NOT EXISTS neededlibpaths_path 6788 ON neededlibrarypaths ( path ); 6789 CREATE INDEX IF NOT EXISTS neededlibpaths_library_elf 6790 ON neededlibrarypaths ( library, elfclass ); 6791 """) 6792 except self.dbapi2.OperationalError: 6793 pass
6794
6795 - def createAutomergefilesIndex(self):
6796 """ 6797 docstring_title 6798 6799 @return: 6800 @rtype: 6801 6802 """ 6803 if self.indexing: 6804 with self.__write_mutex: 6805 try: 6806 self.cursor.executescript(""" 6807 CREATE INDEX IF NOT EXISTS automergefiles_idpackage 6808 ON automergefiles ( idpackage ); 6809 CREATE INDEX IF NOT EXISTS automergefiles_file_md5 6810 ON automergefiles ( configfile, md5 ); 6811 """) 6812 except self.dbapi2.OperationalError: 6813 pass
6814
6815 - def createNeededIndex(self):
6816 """ 6817 docstring_title 6818 6819 @return: 6820 @rtype: 6821 6822 """ 6823 if self.indexing: 6824 with self.__write_mutex: 6825 self.cursor.executescript(""" 6826 CREATE INDEX IF NOT EXISTS neededindex ON neededreference ( library ); 6827 CREATE INDEX IF NOT EXISTS neededindex_idneeded ON needed ( idneeded ); 6828 CREATE INDEX IF NOT EXISTS neededindex_idpackage ON needed ( idpackage ); 6829 CREATE INDEX IF NOT EXISTS neededindex_elfclass ON needed ( elfclass ); 6830 """)
6831
6832 - def createMessagesIndex(self):
6833 """ 6834 docstring_title 6835 6836 @return: 6837 @rtype: 6838 6839 """ 6840 if self.indexing: 6841 with self.__write_mutex: 6842 self.cursor.execute('CREATE INDEX IF NOT EXISTS messagesindex ON messages ( idpackage )')
6843
6844 - def createCompileFlagsIndex(self):
6845 """ 6846 docstring_title 6847 6848 @return: 6849 @rtype: 6850 6851 """ 6852 if self.indexing: 6853 with self.__write_mutex: 6854 self.cursor.execute('CREATE INDEX IF NOT EXISTS flagsindex ON flags ( chost,cflags,cxxflags )')
6855
6856 - def createUseflagsIndex(self):
6857 """ 6858 docstring_title 6859 6860 @return: 6861 @rtype: 6862 6863 """ 6864 if self.indexing: 6865 with self.__write_mutex: 6866 self.cursor.executescript(""" 6867 CREATE INDEX IF NOT EXISTS useflagsindex_useflags_idpackage ON useflags ( idpackage ); 6868 CREATE INDEX IF NOT EXISTS useflagsindex_useflags_idflag ON useflags ( idflag ); 6869 CREATE INDEX IF NOT EXISTS useflagsindex ON useflagsreference ( flagname ); 6870 """)
6871
6872 - def dropContentIndex(self, only_file = False):
6873 """ 6874 docstring_title 6875 6876 @keyword only_file: 6877 @type only_file: 6878 @return: 6879 @rtype: 6880 6881 """ 6882 with self.__write_mutex: 6883 self.cursor.execute("DROP INDEX IF EXISTS contentindex_file") 6884 if not only_file: 6885 self.cursor.executescript("DROP INDEX IF EXISTS contentindex_couple;")
6886
6887 - def createContentIndex(self):
6888 """ 6889 docstring_title 6890 6891 @return: 6892 @rtype: 6893 6894 """ 6895 if self.indexing: 6896 with self.__write_mutex: 6897 if self.doesTableExist("content"): 6898 self.cursor.executescript(""" 6899 CREATE INDEX IF NOT EXISTS contentindex_couple ON content ( idpackage ); 6900 CREATE INDEX IF NOT EXISTS contentindex_file ON content ( file ); 6901 """)
6902
6903 - def createConfigProtectReferenceIndex(self):
6904 """ 6905 docstring_title 6906 6907 @return: 6908 @rtype: 6909 6910 """ 6911 if self.indexing: 6912 with self.__write_mutex: 6913 self.cursor.execute('CREATE INDEX IF NOT EXISTS configprotectreferenceindex ON configprotectreference ( protect )')
6914
6915 - def createBaseinfoIndex(self):
6916 """ 6917 docstring_title 6918 6919 @return: 6920 @rtype: 6921 6922 """ 6923 if self.indexing: 6924 with self.__write_mutex: 6925 self.cursor.executescript(""" 6926 CREATE INDEX IF NOT EXISTS baseindex_atom ON baseinfo ( atom ); 6927 CREATE INDEX IF NOT EXISTS baseindex_branch_name ON baseinfo ( name,branch ); 6928 CREATE INDEX IF NOT EXISTS baseindex_branch_name_idcategory ON baseinfo ( name,idcategory,branch ); 6929 CREATE INDEX IF NOT EXISTS baseindex_idcategory ON baseinfo ( idcategory ); 6930 """)
6931
6932 - def createLicensedataIndex(self):
6933 """ 6934 docstring_title 6935 6936 @return: 6937 @rtype: 6938 6939 """ 6940 if self.indexing: 6941 with self.__write_mutex: 6942 self.cursor.execute('CREATE INDEX IF NOT EXISTS licensedataindex ON licensedata ( licensename )')
6943
6944 - def createLicensesIndex(self):
6945 """ 6946 docstring_title 6947 6948 @return: 6949 @rtype: 6950 6951 """ 6952 if self.indexing: 6953 with self.__write_mutex: 6954 self.cursor.execute('CREATE INDEX IF NOT EXISTS licensesindex ON licenses ( license )')
6955
6956 - def createCategoriesIndex(self):
6957 """ 6958 docstring_title 6959 6960 @return: 6961 @rtype: 6962 6963 """ 6964 if self.indexing: 6965 with self.__write_mutex: 6966 self.cursor.execute('CREATE INDEX IF NOT EXISTS categoriesindex_category ON categories ( category )')
6967
6968 - def createKeywordsIndex(self):
6969 """ 6970 docstring_title 6971 6972 @return: 6973 @rtype: 6974 6975 """ 6976 if self.indexing: 6977 with self.__write_mutex: 6978 self.cursor.executescript(""" 6979 CREATE INDEX IF NOT EXISTS keywordsreferenceindex ON keywordsreference ( keywordname ); 6980 CREATE INDEX IF NOT EXISTS keywordsindex_idpackage ON keywords ( idpackage ); 6981 CREATE INDEX IF NOT EXISTS keywordsindex_idkeyword ON keywords ( idkeyword ); 6982 """)
6983
6984 - def createDependenciesIndex(self):
6985 """ 6986 docstring_title 6987 6988 @return: 6989 @rtype: 6990 6991 """ 6992 if self.indexing: 6993 with self.__write_mutex: 6994 self.cursor.executescript(""" 6995 CREATE INDEX IF NOT EXISTS dependenciesindex_idpackage ON dependencies ( idpackage ); 6996 CREATE INDEX IF NOT EXISTS dependenciesindex_iddependency ON dependencies ( iddependency ); 6997 CREATE INDEX IF NOT EXISTS dependenciesreferenceindex_dependency ON dependenciesreference ( dependency ); 6998 """)
6999
7000 - def createCountersIndex(self):
7001 """ 7002 docstring_title 7003 7004 @return: 7005 @rtype: 7006 7007 """ 7008 if self.indexing: 7009 with self.__write_mutex: 7010 self.cursor.executescript(""" 7011 CREATE INDEX IF NOT EXISTS countersindex_idpackage ON counters ( idpackage ); 7012 CREATE INDEX IF NOT EXISTS countersindex_counter ON counters ( counter ); 7013 """)
7014
7015 - def createSourcesIndex(self):
7016 """ 7017 docstring_title 7018 7019 @return: 7020 @rtype: 7021 7022 """ 7023 if self.indexing: 7024 with self.__write_mutex: 7025 self.cursor.executescript(""" 7026 CREATE INDEX IF NOT EXISTS sourcesindex_idpackage ON sources ( idpackage ); 7027 CREATE INDEX IF NOT EXISTS sourcesindex_idsource ON sources ( idsource ); 7028 CREATE INDEX IF NOT EXISTS sourcesreferenceindex_source ON sourcesreference ( source ); 7029 """)
7030
7031 - def createProvideIndex(self):
7032 """ 7033 docstring_title 7034 7035 @return: 7036 @rtype: 7037 7038 """ 7039 if self.indexing: 7040 with self.__write_mutex: 7041 self.cursor.executescript(""" 7042 CREATE INDEX IF NOT EXISTS provideindex_idpackage ON provide ( idpackage ); 7043 CREATE INDEX IF NOT EXISTS provideindex_atom ON provide ( atom ); 7044 """)
7045
7046 - def createConflictsIndex(self):
7047 """ 7048 docstring_title 7049 7050 @return: 7051 @rtype: 7052 7053 """ 7054 if self.indexing: 7055 with self.__write_mutex: 7056 self.cursor.executescript(""" 7057 CREATE INDEX IF NOT EXISTS conflictsindex_idpackage ON conflicts ( idpackage ); 7058 CREATE INDEX IF NOT EXISTS conflictsindex_atom ON conflicts ( conflict ); 7059 """)
7060
7061 - def createExtrainfoIndex(self):
7062 """ 7063 docstring_title 7064 7065 @return: 7066 @rtype: 7067 7068 """ 7069 if self.indexing: 7070 with self.__write_mutex: 7071 self.cursor.execute('CREATE INDEX IF NOT EXISTS extrainfoindex ON extrainfo ( description )') 7072 self.cursor.execute('CREATE INDEX IF NOT EXISTS extrainfoindex_pkgindex ON extrainfo ( idpackage )')
7073
7074 - def createEclassesIndex(self):
7075 """ 7076 docstring_title 7077 7078 @return: 7079 @rtype: 7080 7081 """ 7082 if self.indexing: 7083 with self.__write_mutex: 7084 self.cursor.executescript(""" 7085 CREATE INDEX IF NOT EXISTS eclassesindex_idpackage ON eclasses ( idpackage ); 7086 CREATE INDEX IF NOT EXISTS eclassesindex_idclass ON eclasses ( idclass ); 7087 CREATE INDEX IF NOT EXISTS eclassesreferenceindex_classname ON eclassesreference ( classname ); 7088 """)
7089
7090 - def regenerateCountersTable(self, vdb_path, output = False):
7091 """ 7092 docstring_title 7093 7094 @param vdb_path: 7095 @type vdb_path: 7096 @keyword output: 7097 @type output: 7098 @return: 7099 @rtype: 7100 7101 """ 7102 7103 # this is necessary now, counters table should be empty 7104 self.cursor.execute("DELETE FROM counters;") 7105 # assign a counter to an idpackage 7106 myids = self.listAllIdpackages() 7107 counter_path = etpConst['spm']['xpak_entries']['counter'] 7108 for myid in myids: 7109 # get atom 7110 myatom = self.retrieveAtom(myid) 7111 mybranch = self.retrieveBranch(myid) 7112 myatom = self.entropyTools.remove_tag(myatom) 7113 myatomcounterpath = "%s%s/%s" % (vdb_path, myatom, counter_path,) 7114 if os.path.isfile(myatomcounterpath): 7115 try: 7116 with open(myatomcounterpath, "r") as f: 7117 counter = int(f.readline().strip()) 7118 except: 7119 if output: 7120 mytxt = "%s: %s: %s" % ( 7121 bold(_("ATTENTION")), 7122 red(_("cannot open Spm counter file for")), 7123 bold(myatom), 7124 ) 7125 self.updateProgress( 7126 mytxt, 7127 importance = 1, 7128 type = "warning" 7129 ) 7130 continue 7131 # insert id+counter 7132 with self.__write_mutex: 7133 try: 7134 self.cursor.execute( 7135 'INSERT into counters VALUES ' 7136 '(?,?,?)', ( counter, myid, mybranch ) 7137 ) 7138 except self.dbapi2.IntegrityError: 7139 if output: 7140 mytxt = "%s: %s: %s" % ( 7141 bold(_("ATTENTION")), 7142 red(_("counter for atom is duplicated, ignoring")), 7143 bold(myatom), 7144 ) 7145 self.updateProgress( 7146 mytxt, 7147 importance = 1, 7148 type = "warning" 7149 ) 7150 continue 7151 # don't trust counters, they might not be unique 7152 7153 self.commitChanges()
7154
7155 - def clearTreeupdatesEntries(self, repository):
7156 """ 7157 docstring_title 7158 7159 @param repository: 7160 @type repository: 7161 @return: 7162 @rtype: 7163 7164 """ 7165 if not self.doesTableExist("treeupdates"): 7166 self.createTreeupdatesTable() 7167 # treeupdates 7168 with self.__write_mutex: 7169 self.cursor.execute("DELETE FROM treeupdates WHERE repository = (?)", (repository,)) 7170 self.commitChanges()
7171
7172 - def resetTreeupdatesDigests(self):
7173 """ 7174 docstring_title 7175 7176 @return: 7177 @rtype: 7178 7179 """ 7180 with self.__write_mutex: 7181 self.cursor.execute('UPDATE treeupdates SET digest = "-1"') 7182 self.commitChanges()
7183
7184 - def migrateCountersTable(self):
7185 """ 7186 docstring_title 7187 7188 @return: 7189 @rtype: 7190 7191 """ 7192 with self.__write_mutex: 7193 self._migrateCountersTable()
7194
7195 - def _migrateCountersTable(self):
7196 self.cursor.executescript(""" 7197 DROP TABLE IF EXISTS counterstemp; 7198 CREATE TABLE counterstemp ( 7199 counter INTEGER, idpackage INTEGER, branch VARCHAR, 7200 PRIMARY KEY(idpackage,branch) 7201 ); 7202 INSERT INTO counterstemp (counter, idpackage, branch) 7203 SELECT counter, idpackage, branch FROM counters; 7204 DROP TABLE counters; 7205 ALTER TABLE counterstemp RENAME TO counters; 7206 """) 7207 self.commitChanges()
7208
7209 - def createNeededlibrarypathsTable(self):
7210 """ 7211 docstring_title 7212 7213 @return: 7214 @rtype: 7215 7216 """ 7217 with self.__write_mutex: 7218 self.cursor.executescript(""" 7219 DROP TABLE IF EXISTS neededlibrarypaths; 7220 CREATE TABLE neededlibrarypaths ( 7221 library VARCHAR, 7222 path VARCHAR, 7223 elfclass INTEGER, 7224 PRIMARY KEY(library, path, elfclass) 7225 ); 7226 """)
7227
7228 - def createNeededlibraryidpackagesTable(self):
7229 """ 7230 docstring_title 7231 7232 @return: 7233 @rtype: 7234 7235 """ 7236 with self.__write_mutex: 7237 self.cursor.executescript(""" 7238 DROP TABLE IF EXISTS neededlibraryidpackages; 7239 CREATE TABLE neededlibraryidpackages ( 7240 idpackage INTEGER, 7241 library VARCHAR, 7242 elfclass INTEGER 7243 ); 7244 """)
7245
7246 - def createInstalledTableSource(self):
7247 """ 7248 docstring_title 7249 7250 @return: 7251 @rtype: 7252 7253 """ 7254 with self.__write_mutex: 7255 self.cursor.execute('ALTER TABLE installedtable ADD source INTEGER;') 7256 self.cursor.execute(""" 7257 UPDATE installedtable SET source = (?) 7258 """, (etpConst['install_sources']['unknown'],))
7259
7260 - def createPackagechangelogsTable(self):
7261 """ 7262 docstring_title 7263 7264 @return: 7265 @rtype: 7266 7267 """ 7268 with self.__write_mutex: 7269 self.cursor.execute('CREATE TABLE packagechangelogs ( category VARCHAR, name VARCHAR, changelog BLOB, PRIMARY KEY (category, name));')
7270
7271 - def createAutomergefilesTable(self):
7272 """ 7273 docstring_title 7274 7275 @return: 7276 @rtype: 7277 7278 """ 7279 with self.__write_mutex: 7280 self.cursor.execute('CREATE TABLE automergefiles ( idpackage INTEGER, configfile VARCHAR, md5 VARCHAR );')
7281
7282 - def createPackagesignaturesTable(self):
7283 """ 7284 docstring_title 7285 7286 @return: 7287 @rtype: 7288 7289 """ 7290 with self.__write_mutex: 7291 self.cursor.execute('CREATE TABLE packagesignatures ( idpackage INTEGER PRIMARY KEY, sha1 VARCHAR, sha256 VARCHAR, sha512 VARCHAR );')
7292
7293 - def createPackagespmphases(self):
7294 """ 7295 docstring_title 7296 7297 @return: 7298 @rtype: 7299 7300 """ 7301 with self.__write_mutex: 7302 self.cursor.execute(""" 7303 CREATE TABLE packagespmphases ( 7304 idpackage INTEGER PRIMARY KEY, 7305 phases VARCHAR 7306 ); 7307 """)
7308
7309 - def createEntropyBranchMigrationTable(self):
7310 """ 7311 docstring_title 7312 7313 @return: 7314 @rtype: 7315 7316 """ 7317 with self.__write_mutex: 7318 self.cursor.execute(""" 7319 CREATE TABLE entropy_branch_migration ( 7320 repository VARCHAR, 7321 from_branch VARCHAR, 7322 to_branch VARCHAR, 7323 post_migration_md5sum VARCHAR, 7324 post_upgrade_md5sum VARCHAR, 7325 PRIMARY KEY (repository, from_branch, to_branch) 7326 ); 7327 """)
7328
7329 - def createPackagesetsTable(self):
7330 """ 7331 docstring_title 7332 7333 @return: 7334 @rtype: 7335 7336 """ 7337 with self.__write_mutex: 7338 self.cursor.execute('CREATE TABLE packagesets ( setname VARCHAR, dependency VARCHAR );')
7339
7340 - def createCategoriesdescriptionTable(self):
7341 """ 7342 docstring_title 7343 7344 @return: 7345 @rtype: 7346 7347 """ 7348 with self.__write_mutex: 7349 self.cursor.execute('CREATE TABLE categoriesdescription ( category VARCHAR, locale VARCHAR, description VARCHAR );')
7350
7351 - def createTreeupdatesTable(self):
7352 """ 7353 docstring_title 7354 7355 @return: 7356 @rtype: 7357 7358 """ 7359 with self.__write_mutex: 7360 self.cursor.execute('CREATE TABLE treeupdates ( repository VARCHAR PRIMARY KEY, digest VARCHAR );')
7361
7362 - def createLicensedataTable(self):
7363 """ 7364 docstring_title 7365 7366 @return: 7367 @rtype: 7368 7369 """ 7370 with self.__write_mutex: 7371 self.cursor.execute('CREATE TABLE licensedata ( licensename VARCHAR UNIQUE, text BLOB, compressed INTEGER );')
7372
7373 - def createLicensesAcceptedTable(self):
7374 """ 7375 docstring_title 7376 7377 @return: 7378 @rtype: 7379 7380 """ 7381 with self.__write_mutex: 7382 self.cursor.execute('CREATE TABLE licenses_accepted ( licensename VARCHAR UNIQUE );')
7383
7384 - def createInstalledTable(self):
7385 """ 7386 docstring_title 7387 7388 @return: 7389 @rtype: 7390 7391 """ 7392 with self.__write_mutex: 7393 self.cursor.execute('DROP TABLE IF EXISTS installedtable;') 7394 self.cursor.execute('CREATE TABLE installedtable ( idpackage INTEGER PRIMARY KEY, repositoryname VARCHAR, source INTEGER );')
7395
7396 - def addDependsRelationToDependsTable(self, iterable):
7397 """ 7398 docstring_title 7399 7400 @param iterable: 7401 @type iterable: 7402 @return: 7403 @rtype: 7404 7405 """ 7406 with self.__write_mutex: 7407 self.cursor.executemany('INSERT into dependstable VALUES (?,?)', iterable) 7408 if (self.entropyTools.is_user_in_entropy_group()) and \ 7409 (self.dbname.startswith(etpConst['serverdbid'])): 7410 # force commit even if readonly, this will allow to automagically fix dependstable server side 7411 self.connection.commit() # we don't care much about syncing the database since it's quite trivial
7412
7413 - def clearDependsTable(self):
7414 """ 7415 docstring_title 7416 7417 @return: 7418 @rtype: 7419 7420 """ 7421 if not self.doesTableExist("dependstable"): 7422 return 7423 self.cursor.executescript(""" 7424 DELETE FROM dependstable; 7425 INSERT INTO dependstable VALUES (-1,-1); 7426 """)
7427
7428 - def regenerateDependsTable(self, output = True):
7429 """ 7430 docstring_title 7431 7432 @keyword output: 7433 @type output: 7434 @return: 7435 @rtype: 7436 7437 """ 7438 7439 depends = self.listAllDependencies() 7440 count = 0 7441 total = len(depends) 7442 mydata = set() 7443 am = self.atomMatch 7444 up = self.updateProgress 7445 self.clearDependsTable() 7446 for iddep, atom in depends: 7447 count += 1 7448 7449 if output and ((count == 0) or (count % 150 == 0) or \ 7450 (count == total)): 7451 up( red("Resolving %s") % (atom,), importance = 0, 7452 type = "info", back = True, count = (count, total) 7453 ) 7454 7455 idpackage, rc = am(atom) 7456 if idpackage is -1: 7457 continue 7458 mydata.add((iddep, idpackage)) 7459 7460 if mydata: 7461 self.addDependsRelationToDependsTable(mydata) 7462 7463 # now validate dependstable 7464 self.sanitizeDependsTable()
7465
7466 - def regenerateLibrarypathsidpackageTable(self, output = True):
7467 """ 7468 docstring_title 7469 7470 @keyword output: 7471 @type output: 7472 @return: 7473 @rtype: 7474 7475 """ 7476 7477 if output: 7478 self.updateProgress( 7479 "%s ..." % ( 7480 purple(_("Resolving libraries, please wait")), 7481 ), 7482 importance = 0, type = "info", back = True 7483 ) 7484 self.cursor.executescript(""" 7485 DELETE FROM neededlibraryidpackages; 7486 INSERT INTO neededlibraryidpackages (idpackage, library, elfclass) 7487 SELECT 7488 baseinfo.idpackage as idpackage, 7489 neededreference.library as library, 7490 neededlibrarypaths.elfclass as elfclass 7491 FROM 7492 baseinfo, neededlibrarypaths, needed, neededreference, content 7493 WHERE 7494 neededreference.idneeded = needed.idneeded AND 7495 needed.idpackage = content.idpackage AND 7496 baseinfo.idpackage = needed.idpackage AND 7497 neededlibrarypaths.library = neededreference.library AND 7498 neededlibrarypaths.elfclass = needed.elfclass AND 7499 content.file = neededlibrarypaths.path 7500 GROUP BY idpackage, library; 7501 7502 """) 7503 if output: 7504 self.updateProgress( 7505 "%s" % ( 7506 purple(_("Libraries solved, all fine")), 7507 ), 7508 importance = 0, type = "info" 7509 )
7510
7511 - def moveCountersToBranch(self, to_branch, from_branch = None):
7512 """ 7513 docstring_title 7514 7515 @param to_branch: 7516 @type to_branch: 7517 @keyword from_branch: 7518 @type from_branch: 7519 @return: 7520 @rtype: 7521 7522 """ 7523 with self.__write_mutex: 7524 if from_branch is not None: 7525 self.cursor.execute('UPDATE counters SET branch = (?) WHERE branch = (?)', (to_branch, from_branch,)) 7526 else: 7527 self.cursor.execute('UPDATE counters SET branch = (?)', (to_branch,)) 7528 self.commitChanges() 7529 self.clearCache()
7530
7531 - def atomMatchFetchCache(self, *args):
7532 """ 7533 docstring_title 7534 7535 @param *args: 7536 @type *args: 7537 @return: 7538 @rtype: 7539 7540 """ 7541 if self.xcache: 7542 cached = self.dumpTools.loadobj("%s/%s/%s" % (self.dbMatchCacheKey, self.dbname, hash(tuple(args)),)) 7543 if cached != None: return cached
7544
7545 - def atomMatchStoreCache(self, *args, **kwargs):
7546 """ 7547 docstring_title 7548 7549 @param *args: 7550 @type *args: 7551 @param **kwargs: 7552 @type **kwargs: 7553 @return: 7554 @rtype: 7555 7556 """ 7557 if self.xcache: 7558 self.Cacher.push("%s/%s/%s" % ( 7559 self.dbMatchCacheKey,self.dbname,hash(tuple(args)),), 7560 kwargs.get('result') 7561 )
7562
7563 - def atomMatchValidateCache(self, cached_obj, multiMatch, extendedResults):
7564 """ 7565 docstring_title 7566 7567 @param cached_obj: 7568 @type cached_obj: 7569 @param multiMatch: 7570 @type multiMatch: 7571 @param extendedResults: 7572 @type extendedResults: 7573 @return: 7574 @rtype: 7575 7576 """ 7577 7578 # time wasted for a reason 7579 data, rc = cached_obj 7580 if rc != 0: return cached_obj 7581 7582 if (not extendedResults) and (not multiMatch): 7583 if not self.isIDPackageAvailable(data): return None 7584 elif extendedResults and (not multiMatch): 7585 # ((idpackage,0,version,versiontag,revision,),0) 7586 if not self.isIDPackageAvailable(data[0]): return None 7587 elif extendedResults and multiMatch: 7588 # (set([(idpackage,0,version,version_tag,revision) for x in dbpkginfo]),0) 7589 idpackages = set([x[0] for x in data]) 7590 if not self.areIDPackagesAvailable(idpackages): return None 7591 elif (not extendedResults) and multiMatch: 7592 # (set([x[0] for x in dbpkginfo]),0) 7593 idpackages = set(data) 7594 if not self.areIDPackagesAvailable(idpackages): return None 7595 7596 return cached_obj
7597
7598 - def _idpackageValidator_live(self, idpackage, reponame):
7599 """ 7600 docstring_title 7601 7602 @param idpackage: package indentifier 7603 @type idpackage: int 7604 @param reponame: 7605 @type reponame: 7606 @return: 7607 @rtype: 7608 7609 """ 7610 if (idpackage, reponame) in self.SystemSettings['live_packagemasking']['mask_matches']: 7611 # do not cache this 7612 return -1, self.SystemSettings['pkg_masking_reference']['user_live_mask'] 7613 elif (idpackage, reponame) in self.SystemSettings['live_packagemasking']['unmask_matches']: 7614 return idpackage, self.SystemSettings['pkg_masking_reference']['user_live_unmask']
7615
7616 - def _idpackageValidator_user_package_mask(self, idpackage, reponame, live):
7617 """ 7618 docstring_title 7619 7620 @param idpackage: package indentifier 7621 @type idpackage: int 7622 @param reponame: 7623 @type reponame: 7624 @param live: 7625 @type live: 7626 @return: 7627 @rtype: 7628 7629 """ 7630 # check if user package.mask needs it masked 7631 7632 mykw = "%smask_ids" % (reponame,) 7633 user_package_mask_ids = self.SystemSettings.get(mykw) 7634 if not isinstance(user_package_mask_ids, (list, set,)): 7635 user_package_mask_ids = set() 7636 for atom in self.SystemSettings['mask']: 7637 matches, r = self.atomMatch(atom, multiMatch = True, packagesFilter = False) 7638 if r != 0: 7639 continue 7640 user_package_mask_ids |= set(matches) 7641 self.SystemSettings[mykw] = user_package_mask_ids 7642 if idpackage in user_package_mask_ids: 7643 # sorry, masked 7644 myr = self.SystemSettings['pkg_masking_reference']['user_package_mask'] 7645 try: 7646 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 7647 validator_cache[(idpackage, reponame, live)] = -1, myr 7648 except KeyError: # system settings client plugin not found 7649 pass 7650 return -1, myr
7651
7652 - def _idpackageValidator_user_package_unmask(self, idpackage, reponame, live):
7653 """ 7654 docstring_title 7655 7656 @param idpackage: package indentifier 7657 @type idpackage: int 7658 @param reponame: 7659 @type reponame: 7660 @param live: 7661 @type live: 7662 @return: 7663 @rtype: 7664 7665 """ 7666 # see if we can unmask by just lookin into user package.unmask stuff -> self.SystemSettings['unmask'] 7667 mykw = "%sunmask_ids" % (reponame,) 7668 user_package_unmask_ids = self.SystemSettings.get(mykw) 7669 if not isinstance(user_package_unmask_ids, (list, set,)): 7670 user_package_unmask_ids = set() 7671 for atom in self.SystemSettings['unmask']: 7672 matches, r = self.atomMatch(atom, multiMatch = True, packagesFilter = False) 7673 if r != 0: 7674 continue 7675 user_package_unmask_ids |= set(matches) 7676 self.SystemSettings[mykw] = user_package_unmask_ids 7677 if idpackage in user_package_unmask_ids: 7678 myr = self.SystemSettings['pkg_masking_reference']['user_package_unmask'] 7679 try: 7680 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 7681 validator_cache[(idpackage, reponame, live)] = idpackage, myr 7682 except KeyError: # system settings client plugin not found 7683 pass 7684 return idpackage, myr
7685
7686 - def _idpackageValidator_packages_db_mask(self, idpackage, reponame, live):
7687 """ 7688 docstring_title 7689 7690 @param idpackage: package indentifier 7691 @type idpackage: int 7692 @param reponame: 7693 @type reponame: 7694 @param live: 7695 @type live: 7696 @return: 7697 @rtype: 7698 7699 """ 7700 # check if repository packages.db.mask needs it masked 7701 repos_mask = {} 7702 client_plg_id = etpConst['system_settings_plugins_ids']['client_plugin'] 7703 client_settings = self.SystemSettings.get(client_plg_id, {}) 7704 if client_settings: 7705 repos_mask = client_settings['repositories']['mask'] 7706 repomask = repos_mask.get(reponame) 7707 if isinstance(repomask, (list, set,)): 7708 # first, seek into generic masking, all branches 7709 mask_repo_id = "%s_ids@@:of:%s" % (reponame, reponame,) # avoid issues with repository names 7710 repomask_ids = repos_mask.get(mask_repo_id) 7711 if not isinstance(repomask_ids, set): 7712 repomask_ids = set() 7713 for atom in repomask: 7714 matches, r = self.atomMatch(atom, multiMatch = True, packagesFilter = False) 7715 if r != 0: 7716 continue 7717 repomask_ids |= set(matches) 7718 repos_mask[mask_repo_id] = repomask_ids 7719 if idpackage in repomask_ids: 7720 myr = self.SystemSettings['pkg_masking_reference']['repository_packages_db_mask'] 7721 try: 7722 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 7723 validator_cache[(idpackage, reponame, live)] = -1, myr 7724 except KeyError: # system settings client plugin not found 7725 pass 7726 return -1, myr
7727
7728 - def _idpackageValidator_package_license_mask(self, idpackage, reponame, live):
7729 """ 7730 docstring_title 7731 7732 @param idpackage: package indentifier 7733 @type idpackage: int 7734 @param reponame: 7735 @type reponame: 7736 @param live: 7737 @type live: 7738 @return: 7739 @rtype: 7740 7741 """ 7742 if self.SystemSettings['license_mask']: 7743 mylicenses = self.retrieveLicense(idpackage) 7744 mylicenses = mylicenses.strip().split() 7745 lic_mask = self.SystemSettings['license_mask'] 7746 for mylicense in mylicenses: 7747 if mylicense not in lic_mask: continue 7748 myr = self.SystemSettings['pkg_masking_reference']['user_license_mask'] 7749 try: 7750 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 7751 validator_cache[(idpackage, reponame, live)] = -1, myr 7752 except KeyError: # system settings client plugin not found 7753 pass 7754 return -1, myr
7755
7756 - def _idpackageValidator_keyword_mask(self, idpackage, reponame, live):
7757 """ 7758 docstring_title 7759 7760 @param idpackage: package indentifier 7761 @type idpackage: int 7762 @param reponame: 7763 @type reponame: 7764 @param live: 7765 @type live: 7766 @return: 7767 @rtype: 7768 7769 """ 7770 7771 mykeywords = self.retrieveKeywords(idpackage) 7772 # WORKAROUND for buggy entries 7773 if not mykeywords: mykeywords = [''] # ** is fine then 7774 # firstly, check if package keywords are in etpConst['keywords'] 7775 # (universal keywords have been merged from package.mask) 7776 for key in etpConst['keywords']: 7777 if key not in mykeywords: continue 7778 myr = self.SystemSettings['pkg_masking_reference']['system_keyword'] 7779 try: 7780 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 7781 validator_cache[(idpackage, reponame, live)] = idpackage, myr 7782 except KeyError: # system settings client plugin not found 7783 pass 7784 return idpackage, myr 7785 7786 # if we get here, it means we didn't find mykeywords in etpConst['keywords'] 7787 # we need to seek self.SystemSettings['keywords'] 7788 # seek in repository first 7789 if reponame in self.SystemSettings['keywords']['repositories']: 7790 for keyword in self.SystemSettings['keywords']['repositories'][reponame]: 7791 if keyword not in mykeywords: continue 7792 keyword_data = self.SystemSettings['keywords']['repositories'][reponame].get(keyword) 7793 if not keyword_data: continue 7794 if "*" in keyword_data: # all packages in this repo with keyword "keyword" are ok 7795 myr = self.SystemSettings['pkg_masking_reference']['user_repo_package_keywords_all'] 7796 try: 7797 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 7798 validator_cache[(idpackage, reponame, live)] = idpackage, myr 7799 except KeyError: # system settings client plugin not found 7800 pass 7801 return idpackage, myr 7802 kwd_key = "%s_ids" % (keyword,) 7803 keyword_data_ids = self.SystemSettings['keywords']['repositories'][reponame].get(kwd_key) 7804 if not isinstance(keyword_data_ids, set): 7805 keyword_data_ids = set() 7806 for atom in keyword_data: 7807 matches, r = self.atomMatch(atom, multiMatch = True, packagesFilter = False) 7808 if r != 0: 7809 continue 7810 keyword_data_ids |= matches 7811 self.SystemSettings['keywords']['repositories'][reponame][kwd_key] = keyword_data_ids 7812 if idpackage in keyword_data_ids: 7813 myr = self.SystemSettings['pkg_masking_reference']['user_repo_package_keywords'] 7814 try: 7815 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 7816 validator_cache[(idpackage, reponame, live)] = idpackage, myr 7817 except KeyError: # system settings client plugin not found 7818 pass 7819 return idpackage, myr 7820 7821 # if we get here, it means we didn't find a match in repositories 7822 # so we scan packages, last chance 7823 for keyword in self.SystemSettings['keywords']['packages']: 7824 # first of all check if keyword is in mykeywords 7825 if keyword not in mykeywords: continue 7826 keyword_data = self.SystemSettings['keywords']['packages'].get(keyword) 7827 if not keyword_data: continue 7828 kwd_key = "%s_ids" % (keyword,) 7829 keyword_data_ids = self.SystemSettings['keywords']['packages'].get(reponame+kwd_key) 7830 if not isinstance(keyword_data_ids, (list, set,)): 7831 keyword_data_ids = set() 7832 for atom in keyword_data: 7833 # match atom 7834 matches, r = self.atomMatch(atom, multiMatch = True, packagesFilter = False) 7835 if r != 0: 7836 continue 7837 keyword_data_ids |= matches 7838 self.SystemSettings['keywords']['packages'][reponame+kwd_key] = keyword_data_ids 7839 if idpackage in keyword_data_ids: 7840 # valid! 7841 myr = self.SystemSettings['pkg_masking_reference']['user_package_keywords'] 7842 try: 7843 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 7844 validator_cache[(idpackage, reponame, live)] = idpackage, myr 7845 except KeyError: # system settings client plugin not found 7846 pass 7847 return idpackage, myr
7848 7849 7850 7851 # function that validate one atom by reading keywords settings 7852 # validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache']
7853 - def idpackageValidator(self, idpackage, live = True):
7854 """ 7855 docstring_title 7856 7857 @param idpackage: package indentifier 7858 @type idpackage: int 7859 @keyword live: 7860 @type live: 7861 @return: 7862 @rtype: 7863 7864 """ 7865 7866 if self.dbname == etpConst['clientdbid']: 7867 return idpackage, 0 7868 elif self.dbname.startswith(etpConst['serverdbid']): 7869 return idpackage, 0 7870 7871 reponame = self.dbname[len(etpConst['dbnamerepoprefix']):] 7872 try: 7873 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 7874 cached = validator_cache.get((idpackage, reponame, live)) 7875 if cached != None: 7876 return cached 7877 # avoid memleaks 7878 if len(validator_cache) > 10000: 7879 validator_cache.clear() 7880 except KeyError: # plugin does not exist 7881 pass 7882 7883 if live: 7884 data = self._idpackageValidator_live(idpackage, reponame) 7885 if data: return data 7886 7887 data = self._idpackageValidator_user_package_mask(idpackage, reponame, live) 7888 if data: return data 7889 7890 data = self._idpackageValidator_user_package_unmask(idpackage, reponame, live) 7891 if data: return data 7892 7893 data = self._idpackageValidator_packages_db_mask(idpackage, reponame, live) 7894 if data: return data 7895 7896 data = self._idpackageValidator_package_license_mask(idpackage, reponame, live) 7897 if data: return data 7898 7899 data = self._idpackageValidator_keyword_mask(idpackage, reponame, live) 7900 if data: return data 7901 7902 # holy crap, can't validate 7903 myr = self.SystemSettings['pkg_masking_reference']['completely_masked'] 7904 validator_cache[(idpackage, reponame, live)] = -1, myr 7905 return -1, myr
7906 7907 # packages filter used by atomMatch, input must me foundIDs, a list like this: 7908 # [608,1867]
7909 - def packagesFilter(self, results):
7910 """ 7911 docstring_title 7912 7913 @param results: 7914 @type results: 7915 @return: 7916 @rtype: 7917 7918 """ 7919 # keywordsFilter ONLY FILTERS results if 7920 # self.dbname.startswith(etpConst['dbnamerepoprefix']) => repository database is open 7921 if not self.dbname.startswith(etpConst['dbnamerepoprefix']): 7922 return results 7923 7924 newresults = set() 7925 for idpackage in results: 7926 idpackage, reason = self.idpackageValidator(idpackage) 7927 if idpackage is -1: continue 7928 newresults.add(idpackage) 7929 return newresults
7930
7931 - def __filterSlot(self, idpackage, slot):
7932 if slot == None: 7933 return idpackage 7934 dbslot = self.retrieveSlot(idpackage) 7935 if str(dbslot) == str(slot): 7936 return idpackage
7937
7938 - def __filterTag(self, idpackage, tag, operators):
7939 if tag == None: 7940 return idpackage 7941 dbtag = self.retrieveVersionTag(idpackage) 7942 compare = cmp(tag, dbtag) 7943 if not operators or operators == "=": 7944 if compare == 0: 7945 return idpackage 7946 else: 7947 return self.__do_operator_compare(idpackage, operators, compare)
7948
7949 - def __filterUse(self, idpackage, use):
7950 if not use: 7951 return idpackage 7952 pkguse = self.retrieveUseflags(idpackage) 7953 disabled = set([x[1:] for x in use if x.startswith("-")]) 7954 enabled = set([x for x in use if not x.startswith("-")]) 7955 enabled_not_satisfied = enabled - pkguse 7956 # check enabled 7957 if enabled_not_satisfied: 7958 return None 7959 # check disabled 7960 disabled_not_satisfied = disabled - pkguse 7961 if len(disabled_not_satisfied) != len(disabled): 7962 return None 7963 return idpackage
7964
7965 - def __do_operator_compare(self, token, operators, compare):
7966 if operators == ">" and compare is -1: 7967 return token 7968 elif operators == ">=" and compare < 1: 7969 return token 7970 elif operators == "<" and compare == 1: 7971 return token 7972 elif operators == "<=" and compare > -1: 7973 return token
7974
7975 - def __filterSlotTagUse(self, foundIDs, slot, tag, use, operators):
7976 7977 def myfilter(idpackage): 7978 7979 idpackage = self.__filterSlot(idpackage, slot) 7980 if not idpackage: 7981 return False 7982 7983 idpackage = self.__filterUse(idpackage, use) 7984 if not idpackage: 7985 return False 7986 7987 idpackage = self.__filterTag(idpackage, tag, operators) 7988 if not idpackage: 7989 return False 7990 7991 return True
7992 7993 return set(filter(myfilter, foundIDs)) 7994
7995 - def atomMatch(self, atom, caseSensitive = True, matchSlot = None, multiMatch = False, 7996 matchBranches = (), matchTag = None, matchUse = (), packagesFilter = True, 7997 matchRevision = None, extendedResults = False, useCache = True ):
7998 7999 """ 8000 8001 @description: matches the user chosen package name+ver, if possibile, in a single repository 8002 @input atom: string, atom to match 8003 @input caseSensitive: bool, should the atom be parsed case sensitive? 8004 @input matchSlot: string, match atoms with the provided slot 8005 @input multiMatch: bool, return all the available atoms 8006 @input matchBranches: tuple or list, match packages only in the specified branches 8007 @input matchTag: match packages only for the specified tag 8008 @input matchUse: match packages only if it owns the specified use flags 8009 @input packagesFilter: enable/disable package.mask/.keywords/.unmask filter 8010 @output: the package id, if found, otherwise -1 plus the status, 0 = ok, 1 = error 8011 8012 """ 8013 8014 if not atom: 8015 return -1, 1 8016 8017 if useCache: 8018 cached = self.atomMatchFetchCache( 8019 atom, caseSensitive, matchSlot, 8020 multiMatch, matchBranches, matchTag, 8021 matchUse, packagesFilter, matchRevision, 8022 extendedResults 8023 ) 8024 if isinstance(cached, tuple): 8025 try: 8026 cached = self.atomMatchValidateCache(cached, multiMatch, extendedResults) 8027 except (TypeError, ValueError, IndexError, KeyError,): 8028 cached = None 8029 if isinstance(cached, tuple): 8030 return cached 8031 8032 atomTag = self.entropyTools.dep_gettag(atom) 8033 try: 8034 atomUse = self.entropyTools.dep_getusedeps(atom) 8035 except InvalidAtom: 8036 atomUse = () 8037 atomSlot = self.entropyTools.dep_getslot(atom) 8038 atomRev = self.entropyTools.dep_get_entropy_revision(atom) 8039 if isinstance(atomRev, (int, long,)): 8040 if atomRev < 0: atomRev = None 8041 8042 # use match 8043 scan_atom = self.entropyTools.remove_usedeps(atom) 8044 if (not matchUse) and (atomUse): 8045 matchUse = atomUse 8046 8047 # tag match 8048 scan_atom = self.entropyTools.remove_tag(scan_atom) 8049 if (matchTag == None) and (atomTag != None): 8050 matchTag = atomTag 8051 8052 # slot match 8053 scan_atom = self.entropyTools.remove_slot(scan_atom) 8054 if (matchSlot == None) and (atomSlot != None): 8055 matchSlot = atomSlot 8056 8057 # revision match 8058 scan_atom = self.entropyTools.remove_entropy_revision(scan_atom) 8059 if (matchRevision == None) and (atomRev != None): 8060 matchRevision = atomRev 8061 8062 branch_list = () 8063 direction = '' 8064 justname = True 8065 pkgkey = '' 8066 strippedAtom = '' 8067 foundIDs = [] 8068 dbpkginfo = set() 8069 8070 if scan_atom: 8071 8072 while 1: 8073 pkgversion = '' 8074 # check for direction 8075 strippedAtom = self.entropyTools.dep_getcpv(scan_atom) 8076 if scan_atom[-1] == "*": 8077 strippedAtom += "*" 8078 direction = scan_atom[0:len(scan_atom)-len(strippedAtom)] 8079 8080 justname = self.entropyTools.isjustname(strippedAtom) 8081 pkgkey = strippedAtom 8082 if justname == 0: 8083 # get version 8084 data = self.entropyTools.catpkgsplit(strippedAtom) 8085 if data == None: break # badly formatted 8086 pkgversion = data[2]+"-"+data[3] 8087 pkgkey = self.entropyTools.dep_getkey(strippedAtom) 8088 8089 splitkey = pkgkey.split("/") 8090 if (len(splitkey) == 2): 8091 pkgname = splitkey[1] 8092 pkgcat = splitkey[0] 8093 else: 8094 pkgname = splitkey[0] 8095 pkgcat = "null" 8096 8097 branch_list = (self.db_branch,) 8098 if matchBranches: 8099 # force to tuple for security 8100 branch_list = tuple(matchBranches) 8101 break 8102 8103 8104 if branch_list: 8105 # IDs found in the database that match our search 8106 foundIDs = self.__generate_found_ids_match(branch_list, pkgkey, pkgname, pkgcat, caseSensitive, multiMatch) 8107 8108 ### FILTERING 8109 # filter slot and tag 8110 if foundIDs: 8111 foundIDs = self.__filterSlotTagUse(foundIDs, matchSlot, matchTag, matchUse, direction) 8112 if packagesFilter: 8113 foundIDs = self.packagesFilter(foundIDs) 8114 ### END FILTERING 8115 8116 if foundIDs: 8117 dbpkginfo = self.__handle_found_ids_match(foundIDs, direction, matchTag, matchRevision, justname, strippedAtom, pkgversion) 8118 8119 if not dbpkginfo: 8120 if extendedResults: 8121 if multiMatch: 8122 x = set() 8123 else: 8124 x = (-1, 1, None, None, None,) 8125 self.atomMatchStoreCache( 8126 atom, caseSensitive, matchSlot, 8127 multiMatch, matchBranches, matchTag, 8128 matchUse, packagesFilter, matchRevision, 8129 extendedResults, result = (x, 1) 8130 ) 8131 return x, 1 8132 else: 8133 if multiMatch: 8134 x = set() 8135 else: 8136 x = -1 8137 self.atomMatchStoreCache( 8138 atom, caseSensitive, matchSlot, 8139 multiMatch, matchBranches, matchTag, 8140 matchUse, packagesFilter, matchRevision, 8141 extendedResults, result = (x, 1) 8142 ) 8143 return x, 1 8144 8145 if multiMatch: 8146 if extendedResults: 8147 x = set([(x[0], 0, x[1], self.retrieveVersionTag(x[0]), self.retrieveRevision(x[0])) for x in dbpkginfo]) 8148 self.atomMatchStoreCache( 8149 atom, caseSensitive, matchSlot, 8150 multiMatch, matchBranches, matchTag, 8151 matchUse, packagesFilter, matchRevision, 8152 extendedResults, result = (x, 0) 8153 ) 8154 return x, 0 8155 else: 8156 x = set([x[0] for x in dbpkginfo]) 8157 self.atomMatchStoreCache( 8158 atom, caseSensitive, matchSlot, 8159 multiMatch, matchBranches, matchTag, 8160 matchUse, packagesFilter, matchRevision, 8161 extendedResults, result = (x, 0) 8162 ) 8163 return x, 0 8164 8165 if len(dbpkginfo) == 1: 8166 x = dbpkginfo.pop() 8167 if extendedResults: 8168 x = (x[0], 0, x[1], self.retrieveVersionTag(x[0]), self.retrieveRevision(x[0])) 8169 self.atomMatchStoreCache( 8170 atom, caseSensitive, matchSlot, 8171 multiMatch, matchBranches, matchTag, 8172 matchUse, packagesFilter, matchRevision, 8173 extendedResults, result = (x, 0) 8174 ) 8175 return x, 0 8176 else: 8177 self.atomMatchStoreCache( 8178 atom, caseSensitive, matchSlot, 8179 multiMatch, matchBranches, matchTag, 8180 matchUse, packagesFilter, matchRevision, 8181 extendedResults, result = (x[0], 0) 8182 ) 8183 return x[0], 0 8184 8185 dbpkginfo = list(dbpkginfo) 8186 pkgdata = {} 8187 versions = set() 8188 for x in dbpkginfo: 8189 info_tuple = (x[1], self.retrieveVersionTag(x[0]), self.retrieveRevision(x[0])) 8190 versions.add(info_tuple) 8191 pkgdata[info_tuple] = x[0] 8192 newer = self.entropyTools.get_entropy_newer_version(list(versions))[0] 8193 x = pkgdata[newer] 8194 if extendedResults: 8195 x = (x, 0, newer[0], newer[1], newer[2]) 8196 self.atomMatchStoreCache( 8197 atom, caseSensitive, matchSlot, 8198 multiMatch, matchBranches, matchTag, 8199 matchUse, packagesFilter, matchRevision, 8200 extendedResults, result = (x, 0) 8201 ) 8202 return x, 0 8203 else: 8204 self.atomMatchStoreCache( 8205 atom, caseSensitive, matchSlot, 8206 multiMatch, matchBranches, matchTag, 8207 matchUse, packagesFilter, matchRevision, 8208 extendedResults, result = (x, 0) 8209 ) 8210 return x, 0
8211
8212 - def __generate_found_ids_match(self, branch_list, pkgkey, pkgname, pkgcat, caseSensitive, multiMatch):
8213 foundIDs = set() 8214 for idx in branch_list: 8215 8216 if pkgcat == "null": 8217 results = self.searchPackagesByName( 8218 pkgname, sensitive = caseSensitive, 8219 branch = idx, justid = True 8220 ) 8221 else: 8222 results = self.searchPackagesByNameAndCategory( 8223 name = pkgname, category = pkgcat, branch = idx, 8224 sensitive = caseSensitive, justid = True 8225 ) 8226 8227 mypkgcat = pkgcat 8228 mypkgname = pkgname 8229 virtual = False 8230 # if it's a PROVIDE, search with searchProvide 8231 # there's no package with that name 8232 if (not results) and (mypkgcat == "virtual"): 8233 virtuals = self.searchProvide(pkgkey, branch = idx, justid = True) 8234 if virtuals: 8235 virtual = True 8236 mypkgname = self.retrieveName(virtuals[0]) 8237 mypkgcat = self.retrieveCategory(virtuals[0]) 8238 results = virtuals 8239 8240 # now validate 8241 if not results: 8242 continue # search into a stabler branch 8243 8244 elif (len(results) > 1): 8245 8246 # if it's because category differs, it's a problem 8247 foundCat = None 8248 cats = set() 8249 for idpackage in results: 8250 cat = self.retrieveCategory(idpackage) 8251 cats.add(cat) 8252 if (cat == mypkgcat) or ((not virtual) and (mypkgcat == "virtual") and (cat == mypkgcat)): 8253 # in case of virtual packages only (that they're not stored as provide) 8254 foundCat = cat 8255 8256 # if we found something at least... 8257 if (not foundCat) and (len(cats) == 1) and (mypkgcat in ("virtual", "null")): 8258 foundCat = sorted(cats)[0] 8259 8260 if not foundCat: 8261 # got the issue 8262 continue 8263 8264 # we can use foundCat 8265 mypkgcat = foundCat 8266 8267 # we need to search using the category 8268 if (not multiMatch) and (pkgcat == "null" or virtual): 8269 # we searched by name, we need to search using category 8270 results = self.searchPackagesByNameAndCategory( 8271 name = mypkgname, category = mypkgcat, 8272 branch = idx, sensitive = caseSensitive, justid = True 8273 ) 8274 8275 # validate again 8276 if not results: 8277 continue # search into another branch 8278 8279 # if we get here, we have found the needed IDs 8280 foundIDs |= set(results) 8281 break 8282 8283 else: 8284 8285 idpackage = results[0] 8286 # if mypkgcat is virtual, we can force 8287 if (mypkgcat == "virtual") and (not virtual): 8288 # in case of virtual packages only (that they're not stored as provide) 8289 mypkgcat = self.retrieveCategory(idpackage) 8290 8291 # check if category matches 8292 if mypkgcat != "null": 8293 foundCat = self.retrieveCategory(idpackage) 8294 if mypkgcat == foundCat: 8295 foundIDs.add(idpackage) 8296 continue 8297 foundIDs.add(idpackage) 8298 break 8299 8300 return foundIDs
8301 8302
8303 - def __handle_found_ids_match(self, foundIDs, direction, matchTag, matchRevision, justname, strippedAtom, pkgversion):
8304 8305 dbpkginfo = set() 8306 # now we have to handle direction 8307 if ((direction) or ((not direction) and (not justname)) or ((not direction) and (not justname) and strippedAtom.endswith("*"))) and foundIDs: 8308 8309 if (not justname) and \ 8310 ((direction == "~") or (direction == "=") or \ 8311 (direction == '' and not justname) or (direction == '' and not justname and strippedAtom.endswith("*"))): 8312 # any revision within the version specified OR the specified version 8313 8314 if (direction == '' and not justname): 8315 direction = "=" 8316 8317 # remove gentoo revision (-r0 if none) 8318 if (direction == "="): 8319 if (pkgversion.split("-")[-1] == "r0"): 8320 pkgversion = self.entropyTools.remove_revision(pkgversion) 8321 if (direction == "~"): 8322 pkgrevision = self.entropyTools.dep_get_portage_revision(pkgversion) 8323 pkgversion = self.entropyTools.remove_revision(pkgversion) 8324 8325 for idpackage in foundIDs: 8326 8327 dbver = self.retrieveVersion(idpackage) 8328 if (direction == "~"): 8329 myrev = self.entropyTools.dep_get_portage_revision(dbver) 8330 myver = self.entropyTools.remove_revision(dbver) 8331 if myver == pkgversion and pkgrevision <= myrev: 8332 # found 8333 dbpkginfo.add((idpackage, dbver)) 8334 else: 8335 # media-libs/test-1.2* support 8336 if pkgversion[-1] == "*": 8337 if dbver.startswith(pkgversion[:-1]): 8338 dbpkginfo.add((idpackage, dbver)) 8339 elif (matchRevision != None) and (pkgversion == dbver): 8340 dbrev = self.retrieveRevision(idpackage) 8341 if dbrev == matchRevision: 8342 dbpkginfo.add((idpackage, dbver)) 8343 elif (pkgversion == dbver) and (matchRevision == None): 8344 dbpkginfo.add((idpackage, dbver)) 8345 8346 elif (direction.find(">") != -1) or (direction.find("<") != -1): 8347 8348 if not justname: 8349 8350 # remove revision (-r0 if none) 8351 if pkgversion.endswith("r0"): 8352 # remove 8353 self.entropyTools.remove_revision(pkgversion) 8354 8355 for idpackage in foundIDs: 8356 8357 revcmp = 0 8358 tagcmp = 0 8359 if matchRevision != None: 8360 dbrev = self.retrieveRevision(idpackage) 8361 revcmp = cmp(matchRevision, dbrev) 8362 if matchTag != None: 8363 dbtag = self.retrieveVersionTag(idpackage) 8364 tagcmp = cmp(matchTag, dbtag) 8365 dbver = self.retrieveVersion(idpackage) 8366 pkgcmp = self.entropyTools.compare_versions(pkgversion, dbver) 8367 if pkgcmp == None: 8368 import warnings 8369 warnings.warn("WARNING, invalid version string stored in %s: %s <-> %s" % (self.dbname, pkgversion, dbver,)) 8370 continue 8371 if direction == ">": 8372 if pkgcmp < 0: 8373 dbpkginfo.add((idpackage, dbver)) 8374 elif (matchRevision != None) and pkgcmp <= 0 and revcmp < 0: 8375 dbpkginfo.add((idpackage, dbver)) 8376 elif (matchTag != None) and tagcmp < 0: 8377 dbpkginfo.add((idpackage, dbver)) 8378 elif direction == "<": 8379 if pkgcmp > 0: 8380 dbpkginfo.add((idpackage, dbver)) 8381 elif (matchRevision != None) and pkgcmp >= 0 and revcmp > 0: 8382 dbpkginfo.add((idpackage, dbver)) 8383 elif (matchTag != None) and tagcmp > 0: 8384 dbpkginfo.add((idpackage, dbver)) 8385 elif direction == ">=": 8386 if (matchRevision != None) and pkgcmp <= 0: 8387 if pkgcmp == 0: 8388 if revcmp <= 0: 8389 dbpkginfo.add((idpackage, dbver)) 8390 else: 8391 dbpkginfo.add((idpackage, dbver)) 8392 elif pkgcmp <= 0 and matchRevision == None: 8393 dbpkginfo.add((idpackage, dbver)) 8394 elif (matchTag != None) and tagcmp <= 0: 8395 dbpkginfo.add((idpackage, dbver)) 8396 elif direction == "<=": 8397 if (matchRevision != None) and pkgcmp >= 0: 8398 if pkgcmp == 0: 8399 if revcmp >= 0: 8400 dbpkginfo.add((idpackage, dbver)) 8401 else: 8402 dbpkginfo.add((idpackage, dbver)) 8403 elif pkgcmp >= 0 and matchRevision == None: 8404 dbpkginfo.add((idpackage, dbver)) 8405 elif (matchTag != None) and tagcmp >= 0: 8406 dbpkginfo.add((idpackage, dbver)) 8407 8408 else: # just the key 8409 8410 dbpkginfo = set([(x, self.retrieveVersion(x),) for x in foundIDs]) 8411 8412 return dbpkginfo
8413