Package entropy :: Module db

Source Code for Module entropy.db

   1  # -*- coding: utf-8 -*- 
   2  """ 
   3      # DESCRIPTION: 
   4      # Entropy Object Oriented Interface 
   5   
   6      Copyright (C) 2007-2009 Fabio Erculiani 
   7   
   8      This program is free software; you can redistribute it and/or modify 
   9      it under the terms of the GNU General Public License as published by 
  10      the Free Software Foundation; either version 2 of the License, or 
  11      (at your option) any later version. 
  12   
  13      This program is distributed in the hope that it will be useful, 
  14      but WITHOUT ANY WARRANTY; without even the implied warranty of 
  15      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  16      GNU General Public License for more details. 
  17   
  18      You should have received a copy of the GNU General Public License 
  19      along with this program; if not, write to the Free Software 
  20      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  21  """ 
  22   
  23  from __future__ import with_statement 
  24  import os 
  25  import shutil 
  26  import subprocess 
  27  from entropy.const import etpConst, etpCache 
  28  from entropy.exceptions import IncorrectParameter, InvalidAtom, \ 
  29      SystemDatabaseError, OperationNotPermitted 
  30  from entropy.i18n import _ 
  31  from entropy.output import brown, bold, red, blue, purple, darkred, darkgreen, \ 
  32      TextInterface 
  33  from entropy.cache import EntropyCacher 
  34  from entropy.core import Singleton, SystemSettings 
  35   
  36  try: # try with sqlite3 from python 2.5 - default one 
  37      from sqlite3 import dbapi2 
  38  except ImportError: # fallback to pysqlite 
  39      try: 
  40          from pysqlite2 import dbapi2 
  41      except ImportError, e: 
  42          raise SystemError( 
  43              "%s. %s: %s" % ( 
  44                  _("Entropy needs Python compiled with sqlite3 support"), 
  45                  _("Error"), 
  46                  e, 
  47              ) 
  48          ) 
  49   
50 -class Status(Singleton):
51
52 - def init_singleton(self):
53 self.__data = {}
54
55 - def __create_if_necessary(self, db):
56 if db not in self.__data: 57 self.__data[db] = {} 58 self.__data[db]['tainted'] = False 59 self.__data[db]['bumped'] = False 60 self.__data[db]['unlock_msg'] = False
61
62 - def set_unlock_msg(self, db):
63 self.__create_if_necessary(db) 64 self.__data[db]['unlock_msg'] = True
65
66 - def unset_unlock_msg(self, db):
67 self.__create_if_necessary(db) 68 self.__data[db]['unlock_msg'] = False
69
70 - def set_tainted(self, db):
71 self.__create_if_necessary(db) 72 self.__data[db]['tainted'] = True
73
74 - def unset_tainted(self, db):
75 self.__create_if_necessary(db) 76 self.__data[db]['tainted'] = False
77
78 - def set_bumped(self, db):
79 self.__create_if_necessary(db) 80 self.__data[db]['bumped'] = True
81
82 - def unset_bumped(self, db):
83 self.__create_if_necessary(db) 84 self.__data[db]['bumped'] = False
85
86 - def is_tainted(self, db):
87 self.__create_if_necessary(db) 88 return self.__data[db]['tainted']
89
90 - def is_bumped(self, db):
91 self.__create_if_necessary(db) 92 return self.__data[db]['bumped']
93
94 - def is_unlock_msg(self, db):
95 self.__create_if_necessary(db) 96 return self.__data[db]['unlock_msg']
97 98
99 -class Schema:
100
101 - def get_init(self):
102 return """ 103 CREATE TABLE baseinfo ( 104 idpackage INTEGER PRIMARY KEY AUTOINCREMENT, 105 atom VARCHAR, 106 idcategory INTEGER, 107 name VARCHAR, 108 version VARCHAR, 109 versiontag VARCHAR, 110 revision INTEGER, 111 branch VARCHAR, 112 slot VARCHAR, 113 idlicense INTEGER, 114 etpapi INTEGER, 115 trigger INTEGER 116 ); 117 118 CREATE TABLE extrainfo ( 119 idpackage INTEGER PRIMARY KEY, 120 description VARCHAR, 121 homepage VARCHAR, 122 download VARCHAR, 123 size VARCHAR, 124 idflags INTEGER, 125 digest VARCHAR, 126 datecreation VARCHAR 127 ); 128 129 CREATE TABLE content ( 130 idpackage INTEGER, 131 file VARCHAR, 132 type VARCHAR 133 ); 134 135 CREATE TABLE provide ( 136 idpackage INTEGER, 137 atom VARCHAR 138 ); 139 140 CREATE TABLE dependencies ( 141 idpackage INTEGER, 142 iddependency INTEGER, 143 type INTEGER 144 ); 145 146 CREATE TABLE dependenciesreference ( 147 iddependency INTEGER PRIMARY KEY AUTOINCREMENT, 148 dependency VARCHAR 149 ); 150 151 CREATE TABLE dependstable ( 152 iddependency INTEGER PRIMARY KEY, 153 idpackage INTEGER 154 ); 155 156 CREATE TABLE conflicts ( 157 idpackage INTEGER, 158 conflict VARCHAR 159 ); 160 161 CREATE TABLE mirrorlinks ( 162 mirrorname VARCHAR, 163 mirrorlink VARCHAR 164 ); 165 166 CREATE TABLE sources ( 167 idpackage INTEGER, 168 idsource INTEGER 169 ); 170 171 CREATE TABLE sourcesreference ( 172 idsource INTEGER PRIMARY KEY AUTOINCREMENT, 173 source VARCHAR 174 ); 175 176 CREATE TABLE useflags ( 177 idpackage INTEGER, 178 idflag INTEGER 179 ); 180 181 CREATE TABLE useflagsreference ( 182 idflag INTEGER PRIMARY KEY AUTOINCREMENT, 183 flagname VARCHAR 184 ); 185 186 CREATE TABLE keywords ( 187 idpackage INTEGER, 188 idkeyword INTEGER 189 ); 190 191 CREATE TABLE keywordsreference ( 192 idkeyword INTEGER PRIMARY KEY AUTOINCREMENT, 193 keywordname VARCHAR 194 ); 195 196 CREATE TABLE categories ( 197 idcategory INTEGER PRIMARY KEY AUTOINCREMENT, 198 category VARCHAR 199 ); 200 201 CREATE TABLE licenses ( 202 idlicense INTEGER PRIMARY KEY AUTOINCREMENT, 203 license VARCHAR 204 ); 205 206 CREATE TABLE flags ( 207 idflags INTEGER PRIMARY KEY AUTOINCREMENT, 208 chost VARCHAR, 209 cflags VARCHAR, 210 cxxflags VARCHAR 211 ); 212 213 CREATE TABLE configprotect ( 214 idpackage INTEGER PRIMARY KEY, 215 idprotect INTEGER 216 ); 217 218 CREATE TABLE configprotectmask ( 219 idpackage INTEGER PRIMARY KEY, 220 idprotect INTEGER 221 ); 222 223 CREATE TABLE configprotectreference ( 224 idprotect INTEGER PRIMARY KEY AUTOINCREMENT, 225 protect VARCHAR 226 ); 227 228 CREATE TABLE systempackages ( 229 idpackage INTEGER PRIMARY KEY 230 ); 231 232 CREATE TABLE injected ( 233 idpackage INTEGER PRIMARY KEY 234 ); 235 236 CREATE TABLE installedtable ( 237 idpackage INTEGER PRIMARY KEY, 238 repositoryname VARCHAR, 239 source INTEGER 240 ); 241 242 CREATE TABLE sizes ( 243 idpackage INTEGER PRIMARY KEY, 244 size INTEGER 245 ); 246 247 CREATE TABLE messages ( 248 idpackage INTEGER, 249 message VARCHAR 250 ); 251 252 CREATE TABLE counters ( 253 counter INTEGER, 254 idpackage INTEGER, 255 branch VARCHAR, 256 PRIMARY KEY(idpackage,branch) 257 ); 258 259 CREATE TABLE trashedcounters ( 260 counter INTEGER 261 ); 262 263 CREATE TABLE eclasses ( 264 idpackage INTEGER, 265 idclass INTEGER 266 ); 267 268 CREATE TABLE eclassesreference ( 269 idclass INTEGER PRIMARY KEY AUTOINCREMENT, 270 classname VARCHAR 271 ); 272 273 CREATE TABLE needed ( 274 idpackage INTEGER, 275 idneeded INTEGER, 276 elfclass INTEGER 277 ); 278 279 CREATE TABLE neededreference ( 280 idneeded INTEGER PRIMARY KEY AUTOINCREMENT, 281 library VARCHAR 282 ); 283 284 CREATE TABLE neededlibrarypaths ( 285 library VARCHAR, 286 path VARCHAR 287 ); 288 289 CREATE TABLE neededlibraryidpackages ( 290 idpackage INTEGER, 291 library VARCHAR, 292 elfclass INTEGER 293 ); 294 295 CREATE TABLE treeupdates ( 296 repository VARCHAR PRIMARY KEY, 297 digest VARCHAR 298 ); 299 300 CREATE TABLE treeupdatesactions ( 301 idupdate INTEGER PRIMARY KEY AUTOINCREMENT, 302 repository VARCHAR, 303 command VARCHAR, 304 branch VARCHAR, 305 date VARCHAR 306 ); 307 308 CREATE TABLE licensedata ( 309 licensename VARCHAR UNIQUE, 310 text BLOB, 311 compressed INTEGER 312 ); 313 314 CREATE TABLE licenses_accepted ( 315 licensename VARCHAR UNIQUE 316 ); 317 318 CREATE TABLE triggers ( 319 idpackage INTEGER PRIMARY KEY, 320 data BLOB 321 ); 322 323 CREATE TABLE entropy_misc_counters ( 324 idtype INTEGER PRIMARY KEY, 325 counter INTEGER 326 ); 327 328 CREATE TABLE categoriesdescription ( 329 category VARCHAR, 330 locale VARCHAR, 331 description VARCHAR 332 ); 333 334 CREATE TABLE packagesets ( 335 setname VARCHAR, 336 dependency VARCHAR 337 ); 338 339 CREATE TABLE packagechangelogs ( 340 category VARCHAR, 341 name VARCHAR, 342 changelog BLOB, 343 PRIMARY KEY (category, name) 344 ); 345 346 CREATE TABLE automergefiles ( 347 idpackage INTEGER, 348 configfile VARCHAR, 349 md5 VARCHAR 350 ); 351 352 CREATE TABLE packagesignatures ( 353 idpackage INTEGER PRIMARY KEY, 354 sha1 VARCHAR, 355 sha256 VARCHAR, 356 sha512 VARCHAR 357 ); 358 359 CREATE TABLE packagespmphases ( 360 idpackage INTEGER PRIMARY KEY, 361 phases VARCHAR 362 ); 363 364 """
365
366 -class LocalRepository:
367 368 import entropy.tools as entropyTools 369 import entropy.dump as dumpTools 370 import threading
371 - def __init__(self, readOnly = False, noUpload = False, dbFile = None, 372 clientDatabase = False, xcache = False, dbname = etpConst['serverdbid'], 373 indexing = True, OutputInterface = None, ServiceInterface = None, 374 skipChecks = False, useBranch = None, lockRemote = True):
375 376 self.SystemSettings = SystemSettings() 377 self.srv_sys_settings_plugin = \ 378 etpConst['system_settings_plugins_ids']['server_plugin'] 379 self.dbMatchCacheKey = etpCache['dbMatch'] 380 self.dbname = dbname 381 self.lockRemote = lockRemote 382 self.client_settings_plugin_id = etpConst['system_settings_plugins_ids']['client_plugin'] 383 self.db_branch = self.SystemSettings['repositories']['branch'] 384 if self.dbname == etpConst['clientdbid']: 385 self.db_branch = None 386 if useBranch != None: self.db_branch = useBranch 387 388 if OutputInterface == None: 389 OutputInterface = TextInterface() 390 391 if dbFile == None: 392 raise IncorrectParameter("IncorrectParameter: %s" % ( 393 _("valid database path needed"),) ) 394 395 self.Cacher = EntropyCacher() 396 self.__write_mutex = self.threading.Lock() 397 self.dbapi2 = dbapi2 398 # setup output interface 399 self.OutputInterface = OutputInterface 400 self.updateProgress = self.OutputInterface.updateProgress 401 self.askQuestion = self.OutputInterface.askQuestion 402 # setup service interface 403 self.ServiceInterface = ServiceInterface 404 self.readOnly = readOnly 405 self.noUpload = noUpload 406 self.clientDatabase = clientDatabase 407 self.xcache = xcache 408 self.indexing = indexing 409 self.skipChecks = skipChecks 410 if not self.skipChecks: 411 if not self.entropyTools.is_user_in_entropy_group(): 412 # forcing since we won't have write access to db 413 self.indexing = False 414 # live systems don't like wasting RAM 415 if self.entropyTools.islive(): 416 self.indexing = False 417 self.dbFile = dbFile 418 self.dbclosed = True 419 self.server_repo = None 420 421 if not self.clientDatabase: 422 self.server_repo = self.dbname[len(etpConst['serverdbid']):] 423 self.create_dbstatus_data() 424 425 if not self.skipChecks: 426 # no caching for non root and server connections 427 if (self.dbname.startswith(etpConst['serverdbid'])) or \ 428 (not self.entropyTools.is_user_in_entropy_group()): 429 self.xcache = False 430 self.live_cache = {} 431 432 # create connection 433 self.connection = self.dbapi2.connect(dbFile, timeout=300.0, 434 check_same_thread = False) 435 self.cursor = self.connection.cursor() 436 437 if not self.skipChecks: 438 if os.access(self.dbFile, os.W_OK) and \ 439 self.doesTableExist('baseinfo') and \ 440 self.doesTableExist('extrainfo'): 441 442 if self.entropyTools.islive() and etpConst['systemroot']: 443 self.databaseStructureUpdates() 444 else: 445 self.databaseStructureUpdates() 446 447 # now we can set this to False 448 self.dbclosed = False
449
450 - def setCacheSize(self, size):
451 self.cursor.execute('PRAGMA cache_size = '+str(size))
452
453 - def setDefaultCacheSize(self, size):
454 self.cursor.execute('PRAGMA default_cache_size = '+str(size))
455 456
457 - def __del__(self):
458 if not self.dbclosed: 459 self.closeDB()
460
461 - def create_dbstatus_data(self):
462 taint_file = self.ServiceInterface.get_local_database_taint_file( 463 self.server_repo) 464 if os.path.isfile(taint_file): 465 dbs = Status() 466 dbs.set_tainted(self.dbFile) 467 dbs.set_bumped(self.dbFile)
468
469 - def closeDB(self):
470 471 self.dbclosed = True 472 473 # if the class is opened readOnly, close and forget 474 if self.readOnly: 475 self.cursor.close() 476 self.connection.close() 477 return 478 479 if self.clientDatabase: 480 if self.dbname == etpConst['clientdbid']: 481 try: 482 self.doCleanups() 483 except self.dbapi2.Error: 484 pass 485 self.commitChanges() 486 self.cursor.close() 487 self.connection.close() 488 return 489 490 sts = Status() 491 if not sts.is_tainted(self.dbFile): 492 # we can unlock it, no changes were made 493 self.ServiceInterface.MirrorsService.lock_mirrors(False, 494 repo = self.server_repo) 495 elif not sts.is_unlock_msg(self.dbFile): 496 u_msg = _("Mirrors have not been unlocked. Remember to sync them.") 497 self.updateProgress( 498 darkgreen(u_msg), 499 importance = 1, 500 type = "info", 501 header = brown(" * ") 502 ) 503 sts.set_unlock_msg(self.dbFile) # avoid spamming 504 505 self.commitChanges() 506 self.cursor.close() 507 self.connection.close()
508
509 - def vacuum(self):
510 self.cursor.execute("vacuum")
511
512 - def commitChanges(self):
513 514 if self.readOnly: 515 return 516 517 try: 518 self.connection.commit() 519 except self.dbapi2.Error: 520 pass 521 522 if not self.clientDatabase: 523 self.taintDatabase() 524 dbs = Status() 525 if (dbs.is_tainted(self.dbFile)) and \ 526 (not dbs.is_bumped(self.dbFile)): 527 # bump revision, setting DatabaseBump causes 528 # the session to just bump once 529 dbs.set_bumped(self.dbFile) 530 self.revisionBump()
531
532 - def taintDatabase(self):
533 # if it's equo to open it, this should be avoided 534 if self.clientDatabase: 535 return 536 # taint the database status 537 taint_file = self.ServiceInterface.get_local_database_taint_file( 538 repo = self.server_repo) 539 f = open(taint_file, "w") 540 f.write(etpConst['currentarch']+" database tainted\n") 541 f.flush() 542 f.close() 543 Status().set_tainted(self.dbFile)
544
545 - def untaintDatabase(self):
546 # if it's equo to open it, this should be avoided 547 if self.clientDatabase: 548 return 549 Status().unset_tainted(self.dbFile) 550 # untaint the database status 551 taint_file = self.ServiceInterface.get_local_database_taint_file( 552 repo = self.server_repo) 553 if os.path.isfile(taint_file): 554 os.remove(taint_file)
555
556 - def revisionBump(self):
557 revision_file = self.ServiceInterface.get_local_database_revision_file( 558 repo = self.server_repo) 559 if not os.path.isfile(revision_file): 560 revision = 1 561 else: 562 f = open(revision_file, "r") 563 revision = int(f.readline().strip()) 564 revision += 1 565 f.close() 566 f = open(revision_file, "w") 567 f.write(str(revision)+"\n") 568 f.flush() 569 f.close()
570
571 - def isDatabaseTainted(self):
572 taint_file = self.ServiceInterface.get_local_database_taint_file( 573 repo = self.server_repo) 574 if os.path.isfile(taint_file): 575 return True 576 return False
577 578 # never use this unless you know what you're doing
579 - def initializeDatabase(self):
580 self.checkReadOnly() 581 my = Schema() 582 for table in self.listAllTables(): 583 try: 584 self.cursor.execute("DROP TABLE %s" % (table,)) 585 except self.dbapi2.OperationalError: 586 # skip tables that can't be dropped 587 continue 588 self.cursor.executescript(my.get_init()) 589 self.databaseStructureUpdates() 590 # set cache size 591 self.setCacheSize(8192) 592 self.setDefaultCacheSize(8192) 593 self.commitChanges()
594
595 - def checkReadOnly(self):
596 if self.readOnly: 597 raise OperationNotPermitted("OperationNotPermitted: %s." % ( 598 _("can't do that on a readonly database"), 599 ) 600 )
601 602 # check for /usr/portage/profiles/updates changes
603 - def serverUpdatePackagesData(self):
604 605 etpConst['server_treeupdatescalled'].add(self.server_repo) 606 607 repo_updates_file = self.ServiceInterface.get_local_database_treeupdates_file(self.server_repo) 608 doRescan = False 609 610 stored_digest = self.retrieveRepositoryUpdatesDigest(self.server_repo) 611 if stored_digest == -1: 612 doRescan = True 613 614 # check portage files for changes if doRescan is still false 615 portage_dirs_digest = "0" 616 if not doRescan: 617 618 treeupdates_dict = self.ServiceInterface.repository_treeupdate_digests 619 620 if treeupdates_dict.has_key(self.server_repo): 621 portage_dirs_digest = treeupdates_dict.get(self.server_repo) 622 else: 623 624 spm = self.ServiceInterface.SpmService 625 # grab portdir 626 updates_dir = etpConst['systemroot'] + \ 627 spm.get_spm_setting("PORTDIR") + "/profiles/updates" 628 if os.path.isdir(updates_dir): 629 # get checksum 630 mdigest = self.entropyTools.md5sum_directory(updates_dir, 631 get_obj = True) 632 # also checksum etpConst['etpdatabaseupdatefile'] 633 if os.path.isfile(repo_updates_file): 634 f = open(repo_updates_file) 635 block = f.read(1024) 636 while block: 637 mdigest.update(block) 638 block = f.read(1024) 639 f.close() 640 portage_dirs_digest = mdigest.hexdigest() 641 treeupdates_dict[self.server_repo] = portage_dirs_digest 642 del updates_dir 643 644 if doRescan or (str(stored_digest) != str(portage_dirs_digest)): 645 646 # force parameters 647 self.readOnly = False 648 self.noUpload = True 649 650 # reset database tables 651 self.clearTreeupdatesEntries(self.server_repo) 652 653 spm = self.ServiceInterface.SpmService 654 updates_dir = etpConst['systemroot'] + \ 655 spm.get_spm_setting("PORTDIR") + "/profiles/updates" 656 update_files = self.entropyTools.sort_update_files( 657 os.listdir(updates_dir)) 658 update_files = [os.path.join(updates_dir, x) for x in update_files] 659 # now load actions from files 660 update_actions = [] 661 for update_file in update_files: 662 f = open(update_file, "r") 663 mycontent = f.readlines() 664 f.close() 665 lines = [x.strip() for x in mycontent if x.strip()] 666 update_actions.extend(lines) 667 668 # add entropy packages.db.repo_updates content 669 if os.path.isfile(repo_updates_file): 670 f = open(repo_updates_file, "r") 671 mycontent = f.readlines() 672 f.close() 673 lines = [x.strip() for x in mycontent if x.strip() and \ 674 not x.strip().startswith("#")] 675 update_actions.extend(lines) 676 # now filter the required actions 677 update_actions = self.filterTreeUpdatesActions(update_actions) 678 if update_actions: 679 680 mytxt = "%s: %s. %s %s" % ( 681 bold(_("ATTENTION")), 682 red(_("forcing package updates")), 683 red(_("Syncing with")), 684 blue(updates_dir), 685 ) 686 self.updateProgress( 687 mytxt, 688 importance = 1, 689 type = "info", 690 header = brown(" * ") 691 ) 692 # lock database 693 if self.lockRemote: 694 self.ServiceInterface.do_server_repository_sync_lock( 695 self.server_repo, self.noUpload) 696 # now run queue 697 try: 698 self.runTreeUpdatesActions(update_actions) 699 except: 700 # destroy digest 701 self.setRepositoryUpdatesDigest(self.server_repo, "-1") 702 raise 703 704 # store new actions 705 self.addRepositoryUpdatesActions( 706 self.server_repo, update_actions, self.db_branch) 707 708 # store new digest into database 709 self.setRepositoryUpdatesDigest( 710 self.server_repo, portage_dirs_digest) 711 self.commitChanges()
712
713 - def clientUpdatePackagesData(self, clientDbconn, force = False):
714 715 if clientDbconn == None: 716 return 717 718 repository = self.dbname[len(etpConst['dbnamerepoprefix']):] 719 etpConst['client_treeupdatescalled'].add(repository) 720 721 doRescan = False 722 shell_rescan = os.getenv("ETP_TREEUPDATES_RESCAN") 723 if shell_rescan: doRescan = True 724 725 # check database digest 726 stored_digest = self.retrieveRepositoryUpdatesDigest(repository) 727 if stored_digest == -1: 728 doRescan = True 729 730 # check stored value in client database 731 client_digest = "0" 732 if not doRescan: 733 client_digest = clientDbconn.retrieveRepositoryUpdatesDigest( 734 repository) 735 736 if doRescan or (str(stored_digest) != str(client_digest)) or force: 737 738 # reset database tables 739 clientDbconn.clearTreeupdatesEntries(repository) 740 741 # load updates 742 update_actions = self.retrieveTreeUpdatesActions(repository) 743 # now filter the required actions 744 update_actions = clientDbconn.filterTreeUpdatesActions( 745 update_actions) 746 747 if update_actions: 748 749 mytxt = "%s: %s. %s %s" % ( 750 bold(_("ATTENTION")), 751 red(_("forcing packages metadata update")), 752 red(_("Updating system database using repository id")), 753 blue(repository), 754 ) 755 self.updateProgress( 756 mytxt, 757 importance = 1, 758 type = "info", 759 header = darkred(" * ") 760 ) 761 # run stuff 762 clientDbconn.runTreeUpdatesActions(update_actions) 763 764 # store new digest into database 765 clientDbconn.setRepositoryUpdatesDigest(repository, stored_digest) 766 # store new actions 767 clientDbconn.addRepositoryUpdatesActions(etpConst['clientdbid'], 768 update_actions, self.SystemSettings['repositories']['branch']) 769 clientDbconn.commitChanges() 770 # clear client cache 771 clientDbconn.clearCache() 772 return True
773 774 # this functions will filter either data from /usr/portage/profiles/updates/* 775 # or repository database returning only the needed actions
776 - def filterTreeUpdatesActions(self, actions):
777 new_actions = [] 778 for action in actions: 779 780 if action in new_actions: # skip dupies 781 continue 782 783 doaction = action.split() 784 if doaction[0] == "slotmove": 785 786 # slot move 787 atom = doaction[1] 788 from_slot = doaction[2] 789 to_slot = doaction[3] 790 atom_key = self.entropyTools.dep_getkey(atom) 791 category = atom_key.split("/")[0] 792 matches = self.atomMatch(atom, matchSlot = from_slot, 793 multiMatch = True) 794 found = False 795 # found atoms, check category 796 for idpackage in matches[0]: 797 myslot = self.retrieveSlot(idpackage) 798 mycategory = self.retrieveCategory(idpackage) 799 if mycategory == category: 800 if (myslot != to_slot) and \ 801 (action not in new_actions): 802 new_actions.append(action) 803 found = True 804 break 805 if found: 806 continue 807 # if we get here it means found == False 808 # search into dependencies 809 dep_atoms = self.searchDependency(atom_key, like = True, 810 multi = True, strings = True) 811 dep_atoms = [x for x in dep_atoms if x.endswith(":"+from_slot) \ 812 and self.entropyTools.dep_getkey(x) == atom_key] 813 if dep_atoms: 814 new_actions.append(action) 815 816 elif doaction[0] == "move": 817 atom = doaction[1] # usually a key 818 atom_key = self.entropyTools.dep_getkey(atom) 819 category = atom_key.split("/")[0] 820 matches = self.atomMatch(atom, multiMatch = True) 821 found = False 822 for idpackage in matches[0]: 823 mycategory = self.retrieveCategory(idpackage) 824 if (mycategory == category) and (action \ 825 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 \ 836 self.entropyTools.dep_getkey(x) == atom_key] 837 if dep_atoms: 838 new_actions.append(action) 839 return new_actions
840 841 # this is the place to add extra actions support
842 - def runTreeUpdatesActions(self, actions):
843 844 mytxt = "%s: %s, %s." % ( 845 bold(_("SPM")), 846 blue(_("Running fixpackages")), 847 red(_("it could take a while")), 848 ) 849 self.updateProgress( 850 mytxt, 851 importance = 1, 852 type = "warning", 853 header = darkred(" * ") 854 ) 855 if self.clientDatabase: 856 try: 857 spm = self.ServiceInterface.Spm() 858 spm.run_fixpackages() 859 except: 860 pass 861 else: 862 self.ServiceInterface.SpmService.run_fixpackages() 863 864 spm_moves = set() 865 quickpkg_atoms = set() 866 for action in actions: 867 command = action.split() 868 mytxt = "%s: %s: %s." % ( 869 bold(_("ENTROPY")), 870 red(_("action")), 871 blue(action), 872 ) 873 self.updateProgress( 874 mytxt, 875 importance = 1, 876 type = "warning", 877 header = darkred(" * ") 878 ) 879 if command[0] == "move": 880 spm_moves.add(action) 881 quickpkg_atoms |= self.runTreeUpdatesMoveAction(command[1:], 882 quickpkg_atoms) 883 elif command[0] == "slotmove": 884 quickpkg_atoms |= self.runTreeUpdatesSlotmoveAction(command[1:], 885 quickpkg_atoms) 886 887 mytxt = "%s: %s." % ( 888 bold(_("ENTROPY")), 889 blue(_("package move actions complete")), 890 ) 891 self.updateProgress( 892 mytxt, 893 importance = 1, 894 type = "info", 895 header = purple(" @@ ") 896 ) 897 898 if quickpkg_atoms and not self.clientDatabase: 899 # quickpkg package and packages owning it as a dependency 900 try: 901 self.runTreeUpdatesQuickpkgAction(quickpkg_atoms) 902 except: 903 self.entropyTools.print_traceback() 904 mytxt = "%s: %s: %s, %s." % ( 905 bold(_("WARNING")), 906 red(_("Cannot complete quickpkg for atoms")), 907 blue(str(list(quickpkg_atoms))), 908 _("do it manually"), 909 ) 910 self.updateProgress( 911 mytxt, 912 importance = 1, 913 type = "warning", 914 header = darkred(" * ") 915 ) 916 self.commitChanges() 917 918 if spm_moves: 919 try: 920 self.doTreeupdatesSpmCleanup(spm_moves) 921 except Exception, e: 922 mytxt = "%s: %s: %s, %s." % ( 923 bold(_("WARNING")), 924 red(_("Cannot run SPM cleanup, error")), 925 Exception, 926 e, 927 ) 928 self.entropyTools.print_traceback() 929 930 mytxt = "%s: %s." % ( 931 bold(_("ENTROPY")), 932 blue(_("package moves completed successfully")), 933 ) 934 self.updateProgress( 935 mytxt, 936 importance = 1, 937 type = "info", 938 header = brown(" @@ ") 939 ) 940 941 # discard cache 942 self.clearCache()
943 944 945 # -- move action: 946 # 1) move package key to the new name: category + name + atom 947 # 2) update all the dependencies in dependenciesreference to the new key 948 # 3) run fixpackages which will update /var/db/pkg files 949 # 4) automatically run quickpkg() to build the new binary and 950 # tainted binaries owning tainted iddependency and taint database
951 - def runTreeUpdatesMoveAction(self, move_command, quickpkg_queue):
952 953 dep_from = move_command[0] 954 key_from = self.entropyTools.dep_getkey(dep_from) 955 key_to = move_command[1] 956 cat_to = key_to.split("/")[0] 957 name_to = key_to.split("/")[1] 958 matches = self.atomMatch(dep_from, multiMatch = True) 959 iddependencies = set() 960 961 for idpackage in matches[0]: 962 963 slot = self.retrieveSlot(idpackage) 964 old_atom = self.retrieveAtom(idpackage) 965 new_atom = old_atom.replace(key_from, key_to) 966 967 ### UPDATE DATABASE 968 # update category 969 self.setCategory(idpackage, cat_to) 970 # update name 971 self.setName(idpackage, name_to) 972 # update atom 973 self.setAtom(idpackage, new_atom) 974 975 # look for packages we need to quickpkg again 976 # note: quickpkg_queue is simply ignored if self.clientDatabase 977 quickpkg_queue.add(key_to+":"+str(slot)) 978 979 if not self.clientDatabase: 980 981 # check for injection and warn the developer 982 injected = self.isInjected(idpackage) 983 if injected: 984 mytxt = "%s: %s %s. %s !!! %s." % ( 985 bold(_("INJECT")), 986 blue(str(new_atom)), 987 red(_("has been injected")), 988 red(_("quickpkg manually to update embedded db")), 989 red(_("Repository database updated anyway")), 990 ) 991 self.updateProgress( 992 mytxt, 993 importance = 1, 994 type = "warning", 995 header = darkred(" * ") 996 ) 997 998 iddeps = self.searchDependency(key_from, like = True, multi = True) 999 for iddep in iddeps: 1000 # update string 1001 mydep = self.retrieveDependencyFromIddependency(iddep) 1002 mydep_key = self.entropyTools.dep_getkey(mydep) 1003 # avoid changing wrong atoms -> dev-python/qscintilla-python would 1004 # become x11-libs/qscintilla if we don't do this check 1005 if mydep_key != key_from: 1006 continue 1007 mydep = mydep.replace(key_from, key_to) 1008 # now update 1009 # dependstable on server is always re-generated 1010 self.setDependency(iddep, mydep) 1011 # we have to repackage also package owning this iddep 1012 iddependencies |= self.searchIdpackageFromIddependency(iddep) 1013 1014 self.commitChanges() 1015 quickpkg_queue = list(quickpkg_queue) 1016 for x in range(len(quickpkg_queue)): 1017 myatom = quickpkg_queue[x] 1018 myatom = myatom.replace(key_from, key_to) 1019 quickpkg_queue[x] = myatom 1020 quickpkg_queue = set(quickpkg_queue) 1021 for idpackage_owner in iddependencies: 1022 myatom = self.retrieveAtom(idpackage_owner) 1023 myatom = myatom.replace(key_from, key_to) 1024 quickpkg_queue.add(myatom) 1025 return quickpkg_queue
1026 1027 1028 # -- slotmove action: 1029 # 1) move package slot 1030 # 2) update all the dependencies in dependenciesreference owning 1031 # same matched atom + slot 1032 # 3) run fixpackages which will update /var/db/pkg files 1033 # 4) automatically run quickpkg() to build the new 1034 # binary and tainted binaries owning tainted iddependency 1035 # and taint database
1036 - def runTreeUpdatesSlotmoveAction(self, slotmove_command, quickpkg_queue):
1037 1038 atom = slotmove_command[0] 1039 atomkey = self.entropyTools.dep_getkey(atom) 1040 slot_from = slotmove_command[1] 1041 slot_to = slotmove_command[2] 1042 matches = self.atomMatch(atom, multiMatch = True) 1043 iddependencies = set() 1044 1045 matched_idpackages = matches[0] 1046 for idpackage in matched_idpackages: 1047 1048 ### UPDATE DATABASE 1049 # update slot 1050 self.setSlot(idpackage, slot_to) 1051 1052 # look for packages we need to quickpkg again 1053 # note: quickpkg_queue is simply ignored if self.clientDatabase 1054 quickpkg_queue.add(atom+":"+str(slot_to)) 1055 1056 if not self.clientDatabase: 1057 1058 # check for injection and warn the developer 1059 injected = self.isInjected(idpackage) 1060 if injected: 1061 mytxt = "%s: %s %s. %s !!! %s." % ( 1062 bold(_("INJECT")), 1063 blue(str(atom)), 1064 red(_("has been injected")), 1065 red(_("quickpkg manually to update embedded db")), 1066 red(_("Repository database updated anyway")), 1067 ) 1068 self.updateProgress( 1069 mytxt, 1070 importance = 1, 1071 type = "warning", 1072 header = darkred(" * ") 1073 ) 1074 1075 # only if we've found VALID matches ! 1076 iddeps = self.searchDependency(atomkey, like = True, multi = True) 1077 for iddep in iddeps: 1078 # update string 1079 mydep = self.retrieveDependencyFromIddependency(iddep) 1080 mydep_key = self.entropyTools.dep_getkey(mydep) 1081 if mydep_key != atomkey: 1082 continue 1083 if not mydep.endswith(":"+slot_from): # probably slotted dep 1084 continue 1085 mydep_match = self.atomMatch(mydep) 1086 if mydep_match not in matched_idpackages: 1087 continue 1088 mydep = mydep.replace(":"+slot_from, ":"+slot_to) 1089 # now update 1090 # dependstable on server is always re-generated 1091 self.setDependency(iddep, mydep) 1092 # we have to repackage also package owning this iddep 1093 iddependencies |= self.searchIdpackageFromIddependency(iddep) 1094 1095 self.commitChanges() 1096 for idpackage_owner in iddependencies: 1097 myatom = self.retrieveAtom(idpackage_owner) 1098 quickpkg_queue.add(myatom) 1099 return quickpkg_queue
1100
1101 - def runTreeUpdatesQuickpkgAction(self, atoms):
1102 1103 self.commitChanges() 1104 1105 package_paths = set() 1106 runatoms = set() 1107 for myatom in atoms: 1108 mymatch = self.atomMatch(myatom) 1109 if mymatch[0] == -1: 1110 continue 1111 myatom = self.retrieveAtom(mymatch[0]) 1112 runatoms.add(myatom) 1113 1114 for myatom in runatoms: 1115 self.updateProgress( 1116 red("%s: " % (_("repackaging"),) )+blue(myatom), 1117 importance = 1, 1118 type = "warning", 1119 header = blue(" # ") 1120 ) 1121 mydest = self.ServiceInterface.get_local_store_directory( 1122 repo = self.server_repo) 1123 try: 1124 mypath = self.ServiceInterface.quickpkg(myatom, mydest) 1125 except: 1126 # remove broken bin before raising 1127 mypath = os.path.join(mydest, 1128 os.path.basename(myatom)+etpConst['packagesext']) 1129 if os.path.isfile(mypath): 1130 os.remove(mypath) 1131 self.entropyTools.print_traceback() 1132 mytxt = "%s: %s: %s, %s." % ( 1133 bold(_("WARNING")), 1134 red(_("Cannot complete quickpkg for atom")), 1135 blue(myatom), 1136 _("do it manually"), 1137 ) 1138 self.updateProgress( 1139 mytxt, 1140 importance = 1, 1141 type = "warning", 1142 header = darkred(" * ") 1143 ) 1144 continue 1145 package_paths.add(mypath) 1146 packages_data = [(x, False,) for x in package_paths] 1147 idpackages = self.ServiceInterface.add_packages_to_repository( 1148 packages_data, repo = self.server_repo) 1149 1150 if not idpackages: 1151 1152 mytxt = "%s: %s. %s." % ( 1153 bold(_("ATTENTION")), 1154 red(_("runTreeUpdatesQuickpkgAction did not run properly")), 1155 red(_("Please update packages manually")), 1156 ) 1157 self.updateProgress( 1158 mytxt, 1159 importance = 1, 1160 type = "warning", 1161 header = darkred(" * ") 1162 )
1163
1164 - def doTreeupdatesSpmCleanup(self, spm_moves):
1165 1166 # now erase Spm entries if necessary 1167 for action in spm_moves: 1168 command = action.split() 1169 if len(command) < 2: 1170 continue 1171 key = command[1] 1172 name = key.split("/")[1] 1173 if self.clientDatabase: 1174 try: 1175 spm = self.ServiceInterface.Spm() 1176 except: 1177 continue 1178 else: 1179 spm = self.ServiceInterface.SpmService 1180 vdb_path = spm.get_vdb_path() 1181 pkg_path = os.path.join(vdb_path, key.split("/")[0]) 1182 try: 1183 mydirs = [os.path.join(pkg_path, x) for x in \ 1184 os.listdir(pkg_path) if x.startswith(name)] 1185 except OSError: # no dir, no party! 1186 continue 1187 mydirs = [x for x in mydirs if os.path.isdir(x)] 1188 # now move these dirs 1189 for mydir in mydirs: 1190 to_path = os.path.join(etpConst['packagestmpdir'], 1191 os.path.basename(mydir)) 1192 mytxt = "%s: %s '%s' %s '%s'" % ( 1193 bold(_("SPM")), 1194 red(_("Moving old entry")), 1195 blue(mydir), 1196 red(_("to")), 1197 blue(to_path), 1198 ) 1199 self.updateProgress( 1200 mytxt, 1201 importance = 1, 1202 type = "warning", 1203 header = darkred(" * ") 1204 ) 1205 if os.path.isdir(to_path): 1206 shutil.rmtree(to_path, True) 1207 try: 1208 os.rmdir(to_path) 1209 except OSError: 1210 pass 1211 shutil.move(mydir, to_path)
1212 1213
1214 - def handlePackage(self, etpData, forcedRevision = -1, 1215 formattedContent = False):
1216 1217 self.checkReadOnly() 1218 1219 if self.clientDatabase: 1220 return self.addPackage(etpData, revision = forcedRevision, 1221 formatted_content = formattedContent) 1222 1223 # build atom string, server side 1224 pkgatom = self.entropyTools.create_package_atom_string( 1225 etpData['category'], etpData['name'], etpData['version'], 1226 etpData['versiontag']) 1227 foundid = self.isPackageAvailable(pkgatom) 1228 if foundid < 0: # same atom doesn't exist in any branch 1229 return self.addPackage(etpData, revision = forcedRevision, 1230 formatted_content = formattedContent) 1231 1232 idpackage = self.getIDPackage(pkgatom) 1233 curRevision = forcedRevision 1234 if forcedRevision == -1: 1235 curRevision = 0 1236 if idpackage != -1: 1237 curRevision = self.retrieveRevision(idpackage) 1238 1239 # remove old package atom, we do it here because othersie 1240 if idpackage != -1: 1241 # injected packages wouldn't be removed by addPackages 1242 self.removePackage(idpackage) 1243 if forcedRevision == -1: curRevision += 1 1244 1245 # add the new one 1246 return self.addPackage(etpData, revision = curRevision, 1247 formatted_content = formattedContent)
1248
1249 - def retrieve_packages_to_remove(self, name, category, slot, injected):
1250 1251 removelist = set() 1252 1253 # support for expiration-based packages handling, also internally 1254 # called Fat Scope. 1255 filter_similar = False 1256 srv_ss_plg = etpConst['system_settings_plugins_ids']['server_plugin'] 1257 srv_ss_fs_plg = \ 1258 etpConst['system_settings_plugins_ids']['server_plugin_fatscope'] 1259 1260 if not self.clientDatabase: # server-side db 1261 srv_plug_settings = self.SystemSettings.get(srv_ss_plg) 1262 if srv_plug_settings != None: 1263 if srv_plug_settings['server']['exp_based_scope']: 1264 # in case support is enabled, return an empty set 1265 filter_similar = True 1266 1267 searchsimilar = self.searchPackagesByNameAndCategory( 1268 name = name, 1269 category = category, 1270 sensitive = True 1271 ) 1272 if filter_similar: 1273 # filter out packages in the same scope that are allowed to stay 1274 idpkgs = self.SystemSettings[srv_ss_fs_plg]['repos'].get( 1275 self.server_repo) 1276 if idpkgs: 1277 if -1 in idpkgs: 1278 del searchsimilar[:] 1279 else: 1280 searchsimilar = [x for x in searchsimilar if x[1] \ 1281 not in idpkgs] 1282 1283 if not injected: 1284 # read: if package has been injected, we'll skip 1285 # the removal of packages in the same slot, 1286 # usually used server side btw 1287 for atom, idpackage in searchsimilar: 1288 # get the package slot 1289 myslot = self.retrieveSlot(idpackage) 1290 # we merely ignore packages with 1291 # negative counters, since they're the injected ones 1292 if self.isInjected(idpackage): continue 1293 if slot == myslot: 1294 # remove! 1295 removelist.add(idpackage) 1296 1297 return removelist
1298
1299 - def addPackage(self, etpData, revision = -1, idpackage = None, 1300 do_remove = True, do_commit = True, formatted_content = False):
1301 1302 self.checkReadOnly() 1303 1304 if revision == -1: 1305 try: 1306 revision = int(etpData['revision']) 1307 except (KeyError, ValueError): 1308 etpData['revision'] = 0 # revision not specified 1309 revision = 0 1310 elif not etpData.has_key('revision'): 1311 etpData['revision'] = revision 1312 1313 manual_deps = set() 1314 if do_remove: 1315 removelist = self.retrieve_packages_to_remove( 1316 etpData['name'], 1317 etpData['category'], 1318 etpData['slot'], 1319 etpData['injected'] 1320 ) 1321 for r_idpackage in removelist: 1322 manual_deps |= self.retrieveManualDependencies(r_idpackage) 1323 self.removePackage(r_idpackage, do_cleanup = False, 1324 do_commit = False) 1325 1326 # create new category if it doesn't exist 1327 catid = self.isCategoryAvailable(etpData['category']) 1328 if catid == -1: catid = self.addCategory(etpData['category']) 1329 1330 # create new license if it doesn't exist 1331 licid = self.isLicenseAvailable(etpData['license']) 1332 if licid == -1: licid = self.addLicense(etpData['license']) 1333 1334 idprotect = self.isProtectAvailable(etpData['config_protect']) 1335 if idprotect == -1: idprotect = self.addProtect( 1336 etpData['config_protect']) 1337 1338 idprotect_mask = self.isProtectAvailable( 1339 etpData['config_protect_mask']) 1340 if idprotect_mask == -1: idprotect_mask = self.addProtect( 1341 etpData['config_protect_mask']) 1342 1343 idflags = self.areCompileFlagsAvailable( 1344 etpData['chost'],etpData['cflags'],etpData['cxxflags']) 1345 if idflags == -1: idflags = self.addCompileFlags( 1346 etpData['chost'],etpData['cflags'],etpData['cxxflags']) 1347 1348 1349 trigger = 0 1350 if etpData['trigger']: 1351 trigger = 1 1352 1353 # baseinfo 1354 pkgatom = self.entropyTools.create_package_atom_string( 1355 etpData['category'], etpData['name'], etpData['version'], 1356 etpData['versiontag']) 1357 # add atom metadatum 1358 etpData['atom'] = pkgatom 1359 1360 mybaseinfo_data = (pkgatom, catid, etpData['name'], etpData['version'], 1361 etpData['versiontag'], revision, etpData['branch'], etpData['slot'], 1362 licid, etpData['etpapi'], trigger,) 1363 1364 myidpackage_string = 'NULL' 1365 if isinstance(idpackage, int): 1366 manual_deps |= self.retrieveManualDependencies(idpackage) 1367 # does it exist? 1368 self.removePackage(idpackage, do_cleanup = False, 1369 do_commit = False, do_rss = False) 1370 myidpackage_string = '?' 1371 mybaseinfo_data = (idpackage,)+mybaseinfo_data 1372 else: 1373 idpackage = None 1374 1375 # merge old manual dependencies 1376 for manual_dep in manual_deps: 1377 if manual_dep in etpData['dependencies']: continue 1378 etpData['dependencies'][manual_dep] = etpConst['spm']['mdepend_id'] 1379 1380 with self.__write_mutex: 1381 1382 self.cursor.execute(""" 1383 INSERT into baseinfo VALUES (%s,?,?,?,?,?,?,?,?,?,?,?)""" % ( 1384 myidpackage_string,), mybaseinfo_data) 1385 if idpackage == None: 1386 idpackage = self.cursor.lastrowid 1387 1388 # extrainfo 1389 self.cursor.execute( 1390 'INSERT into extrainfo VALUES (?,?,?,?,?,?,?,?)', 1391 ( idpackage, 1392 etpData['description'], 1393 etpData['homepage'], 1394 etpData['download'], 1395 etpData['size'], 1396 idflags, 1397 etpData['digest'], 1398 etpData['datecreation'], 1399 ) 1400 ) 1401 ### other information iserted below are not as critical as these above 1402 1403 # tables using a select 1404 self.insertEclasses(idpackage, etpData['eclasses']) 1405 self.insertNeeded(idpackage, etpData['needed']) 1406 self.insertDependencies(idpackage, etpData['dependencies']) 1407 self.insertSources(idpackage, etpData['sources']) 1408 self.insertUseflags(idpackage, etpData['useflags']) 1409 self.insertKeywords(idpackage, etpData['keywords']) 1410 self.insertLicenses(etpData['licensedata']) 1411 self.insertMirrors(etpData['mirrorlinks']) 1412 # package ChangeLog 1413 if etpData.get('changelog'): 1414 self.insertChangelog(etpData['category'], etpData['name'], 1415 etpData['changelog']) 1416 # package signatures 1417 if etpData.get('signatures'): 1418 self.insertSignatures(idpackage, etpData['signatures']) 1419 # needed libraries paths 1420 if etpData.get('needed_paths'): 1421 for lib in sorted(etpData['needed_paths']): 1422 self.insertNeededPaths(lib, etpData['needed_paths'][lib]) 1423 1424 # spm phases 1425 if etpData.get('spm_phases') != None: 1426 self.insertSpmPhases(idpackage, etpData['spm_phases']) 1427 1428 # not depending on other tables == no select done 1429 self.insertContent(idpackage, etpData['content'], 1430 already_formatted = formatted_content) 1431 etpData['counter'] = int(etpData['counter']) # cast to integer 1432 etpData['counter'] = self.insertPortageCounter( 1433 idpackage, 1434 etpData['counter'], 1435 etpData['branch'], 1436 etpData['injected'] 1437 ) 1438 self.insertOnDiskSize(idpackage, etpData['disksize']) 1439 if etpData['trigger']: 1440 self.insertTrigger(idpackage, etpData['trigger']) 1441 self.insertConflicts(idpackage, etpData['conflicts']) 1442 self.insertProvide(idpackage, etpData['provide']) 1443 self.insertMessages(idpackage, etpData['messages']) 1444 self.insertConfigProtect(idpackage, idprotect) 1445 self.insertConfigProtect(idpackage, idprotect_mask, mask = True) 1446 # injected? 1447 if etpData.get('injected'): 1448 self.setInjected(idpackage, do_commit = False) 1449 # is it a system package? 1450 if etpData.get('systempackage'): 1451 self.setSystemPackage(idpackage, do_commit = False) 1452 1453 self.clearCache() # we do live_cache.clear() here too 1454 if do_commit: 1455 self.commitChanges() 1456 1457 ### RSS Atom support 1458 ### dictionary will be elaborated by activator 1459 if self.SystemSettings.has_key(self.srv_sys_settings_plugin): 1460 if self.SystemSettings[self.srv_sys_settings_plugin]['server']['rss']['enabled'] and \ 1461 not self.clientDatabase: 1462 1463 self._write_rss_for_added_package(pkgatom, revision, 1464 etpData['description'], etpData['homepage']) 1465 1466 # Update category description 1467 if not self.clientDatabase: 1468 mycategory = etpData['category'] 1469 descdata = {} 1470 try: 1471 descdata = self.get_category_description_from_disk(mycategory) 1472 except (IOError, OSError, EOFError,): 1473 pass 1474 if descdata: 1475 self.setCategoryDescription(mycategory, descdata) 1476 1477 return idpackage, revision, etpData
1478
1479 - def _write_rss_for_added_package(self, pkgatom, revision, description, 1480 homepage):
1481 1482 rssAtom = pkgatom+"~"+str(revision) 1483 rssObj = self.dumpTools.loadobj(etpConst['rss-dump-name']) 1484 if rssObj: self.ServiceInterface.rssMessages = rssObj.copy() 1485 if not isinstance(self.ServiceInterface.rssMessages, dict): 1486 self.ServiceInterface.rssMessages = {} 1487 if not self.ServiceInterface.rssMessages.has_key('added'): 1488 self.ServiceInterface.rssMessages['added'] = {} 1489 if not self.ServiceInterface.rssMessages.has_key('removed'): 1490 self.ServiceInterface.rssMessages['removed'] = {} 1491 if rssAtom in self.ServiceInterface.rssMessages['removed']: 1492 del self.ServiceInterface.rssMessages['removed'][rssAtom] 1493 1494 self.ServiceInterface.rssMessages['added'][rssAtom] = {} 1495 self.ServiceInterface.rssMessages['added'][rssAtom]['description'] = \ 1496 description 1497 self.ServiceInterface.rssMessages['added'][rssAtom]['homepage'] = \ 1498 homepage 1499 self.ServiceInterface.rssMessages['light'][rssAtom] = {} 1500 self.ServiceInterface.rssMessages['light'][rssAtom]['description'] = \ 1501 description 1502 self.dumpTools.dumpobj(etpConst['rss-dump-name'], 1503 self.ServiceInterface.rssMessages)
1504
1505 - def _write_rss_for_removed_package(self, idpackage):
1506 1507 rssObj = self.dumpTools.loadobj(etpConst['rss-dump-name']) 1508 if rssObj: self.ServiceInterface.rssMessages = rssObj.copy() 1509 rssAtom = self.retrieveAtom(idpackage) 1510 rssRevision = self.retrieveRevision(idpackage) 1511 rssAtom += "~"+str(rssRevision) 1512 if not isinstance(self.ServiceInterface.rssMessages, dict): 1513 self.ServiceInterface.rssMessages = {} 1514 if not self.ServiceInterface.rssMessages.has_key('added'): 1515 self.ServiceInterface.rssMessages['added'] = {} 1516 if not self.ServiceInterface.rssMessages.has_key('removed'): 1517 self.ServiceInterface.rssMessages['removed'] = {} 1518 if rssAtom in self.ServiceInterface.rssMessages['added']: 1519 del self.ServiceInterface.rssMessages['added'][rssAtom] 1520 1521 mydict = {} 1522 try: 1523 mydict['description'] = self.retrieveDescription(idpackage) 1524 except TypeError: 1525 mydict['description'] = "N/A" 1526 try: 1527 mydict['homepage'] = self.retrieveHomepage(idpackage) 1528 except TypeError: 1529 mydict['homepage'] = "" 1530 1531 self.dumpTools.dumpobj(etpConst['rss-dump-name'], 1532 self.ServiceInterface.rssMessages) 1533 1534 self.ServiceInterface.rssMessages['removed'][rssAtom] = mydict
1535
1536 - def removePackage(self, idpackage, do_cleanup = True, do_commit = True, 1537 do_rss = True):
1538 1539 self.checkReadOnly() 1540 # clear caches 1541 self.clearCache() 1542 1543 ### RSS Atom support 1544 ### dictionary will be elaborated by activator 1545 if self.SystemSettings.has_key(self.srv_sys_settings_plugin): 1546 if self.SystemSettings[self.srv_sys_settings_plugin]['server']['rss']['enabled'] and \ 1547 (not self.clientDatabase) and do_rss: 1548 1549 # store addPackage action 1550 self._write_rss_for_removed_package(idpackage) 1551 1552 with self.__write_mutex: 1553 1554 r_tup = (idpackage,)*20 1555 self.cursor.executescript(""" 1556 DELETE FROM baseinfo WHERE idpackage = %d; 1557 DELETE FROM extrainfo WHERE idpackage = %d; 1558 DELETE FROM dependencies WHERE idpackage = %d; 1559 DELETE FROM provide WHERE idpackage = %d; 1560 DELETE FROM conflicts WHERE idpackage = %d; 1561 DELETE FROM configprotect WHERE idpackage = %d; 1562 DELETE FROM configprotectmask WHERE idpackage = %d; 1563 DELETE FROM sources WHERE idpackage = %d; 1564 DELETE FROM useflags WHERE idpackage = %d; 1565 DELETE FROM keywords WHERE idpackage = %d; 1566 DELETE FROM content WHERE idpackage = %d; 1567 DELETE FROM messages WHERE idpackage = %d; 1568 DELETE FROM counters WHERE idpackage = %d; 1569 DELETE FROM sizes WHERE idpackage = %d; 1570 DELETE FROM eclasses WHERE idpackage = %d; 1571 DELETE FROM needed WHERE idpackage = %d; 1572 DELETE FROM triggers WHERE idpackage = %d; 1573 DELETE FROM systempackages WHERE idpackage = %d; 1574 DELETE FROM injected WHERE idpackage = %d; 1575 DELETE FROM installedtable WHERE idpackage = %d; 1576 """ % r_tup) 1577 1578 # not yet possible to add these calls above 1579 try: 1580 self.removeAutomergefiles(idpackage) 1581 except self.dbapi2.OperationalError: 1582 pass 1583 try: 1584 self.removeSignatures(idpackage) 1585 except self.dbapi2.OperationalError: 1586 pass 1587 try: 1588 self.removeSpmPhases(idpackage) 1589 except self.dbapi2.OperationalError: 1590 pass 1591 1592 # Remove from dependstable if exists 1593 self.removePackageFromDependsTable(idpackage) 1594 1595 if do_cleanup: 1596 # Cleanups if at least one package has been removed 1597 self.doCleanups() 1598 1599 if do_commit: 1600 self.commitChanges()
1601
1602 - def removeMirrorEntries(self, mirrorname):
1603 with self.__write_mutex: 1604 self.cursor.execute(""" 1605 DELETE FROM mirrorlinks WHERE mirrorname = (?) 1606 """,(mirrorname,))
1607
1608 - def addMirrors(self, mirrorname, mirrorlist):
1609 with self.__write_mutex: 1610 data = [(mirrorname, x,) for x in mirrorlist] 1611 self.cursor.executemany(""" 1612 INSERT into mirrorlinks VALUES (?,?) 1613 """, data)
1614
1615 - def addCategory(self, category):
1616 with self.__write_mutex: 1617 self.cursor.execute(""" 1618 INSERT into categories VALUES (NULL,?) 1619 """, (category,)) 1620 return self.cursor.lastrowid
1621
1622 - def addProtect(self, protect):
1623 with self.__write_mutex: 1624 self.cursor.execute(""" 1625 INSERT into configprotectreference VALUES (NULL,?) 1626 """, (protect,)) 1627 return self.cursor.lastrowid
1628 1629
1630 - def addSource(self, source):
1631 with self.__write_mutex: 1632 self.cursor.execute(""" 1633 INSERT into sourcesreference VALUES (NULL,?) 1634 """, (source,)) 1635 return self.cursor.lastrowid
1636
1637 - def addDependency(self, dependency):
1638 with self.__write_mutex: 1639 self.cursor.execute('INSERT into dependenciesreference VALUES (NULL,?)', (dependency,)) 1640 return self.cursor.lastrowid
1641
1642 - def addKeyword(self, keyword):
1643 with self.__write_mutex: 1644 self.cursor.execute('INSERT into keywordsreference VALUES (NULL,?)', (keyword,)) 1645 return self.cursor.lastrowid
1646
1647 - def addUseflag(self, useflag):
1648 with self.__write_mutex: 1649 self.cursor.execute('INSERT into useflagsreference VALUES (NULL,?)', (useflag,)) 1650 return self.cursor.lastrowid
1651
1652 - def addEclass(self, eclass):
1653 with self.__write_mutex: 1654 self.cursor.execute('INSERT into eclassesreference VALUES (NULL,?)', (eclass,)) 1655 return self.cursor.lastrowid
1656
1657 - def addNeeded(self, needed):
1658 with self.__write_mutex: 1659 self.cursor.execute('INSERT into neededreference VALUES (NULL,?)', (needed,)) 1660 return self.cursor.lastrowid
1661
1662 - def addLicense(self, pkglicense):
1663 if not self.entropyTools.is_valid_string(pkglicense): 1664 pkglicense = ' ' # workaround for broken license entries 1665 with self.__write_mutex: 1666 self.cursor.execute('INSERT into licenses VALUES (NULL,?)', (pkglicense,)) 1667 return self.cursor.lastrowid
1668
1669 - def addCompileFlags(self, chost, cflags, cxxflags):
1670 with self.__write_mutex: 1671 self.cursor.execute('INSERT into flags VALUES (NULL,?,?,?)', (chost,cflags,cxxflags,)) 1672 return self.cursor.lastrowid
1673
1674 - def setSystemPackage(self, idpackage, do_commit = True):
1675 with self.__write_mutex: 1676 self.cursor.execute('INSERT into systempackages VALUES (?)', (idpackage,)) 1677 if do_commit: 1678 self.commitChanges()
1679
1680 - def setInjected(self, idpackage, do_commit = True):
1681 with self.__write_mutex: 1682 if not self.isInjected(idpackage): 1683 self.cursor.execute('INSERT into injected VALUES (?)', (idpackage,)) 1684 if do_commit: 1685 self.commitChanges()
1686 1687 # date expressed the unix way
1688 - def setDateCreation(self, idpackage, date):
1689 with self.__write_mutex: 1690 self.cursor.execute('UPDATE extrainfo SET datecreation = (?) WHERE idpackage = (?)', (str(date), idpackage,)) 1691 self.commitChanges()
1692
1693 - def setDigest(self, idpackage, digest):
1694 with self.__write_mutex: 1695 self.cursor.execute('UPDATE extrainfo SET digest = (?) WHERE idpackage = (?)', (digest, idpackage,)) 1696 self.commitChanges()
1697
1698 - def setSignatures(self, idpackage, signatures):
1699 with self.__write_mutex: 1700 sha1, sha256, sha512 = signatures['sha1'], signatures['sha256'], \ 1701 signatures['sha512'] 1702 self.cursor.execute(""" 1703 UPDATE packagesignatures SET sha1 = (?), sha256 = (?), sha512 = (?) 1704 WHERE idpackage = (?) 1705 """, (sha1, sha256, sha512, idpackage))
1706
1707 - def setDownloadURL(self, idpackage, url):
1708 with self.__write_mutex: 1709 self.cursor.execute('UPDATE extrainfo SET download = (?) WHERE idpackage = (?)', (url, idpackage,)) 1710 self.commitChanges()
1711
1712 - def setCategory(self, idpackage, category):
1713 # create new category if it doesn't exist 1714 catid = self.isCategoryAvailable(category) 1715 if (catid == -1): 1716 # create category 1717 catid = self.addCategory(category) 1718 with self.__write_mutex: 1719 self.cursor.execute('UPDATE baseinfo SET idcategory = (?) WHERE idpackage = (?)', (catid, idpackage,)) 1720 self.commitChanges()
1721
1722 - def setCategoryDescription(self, category, description_data):
1723 with self.__write_mutex: 1724 self.cursor.execute('DELETE FROM categoriesdescription WHERE category = (?)', (category,)) 1725 for locale in description_data: 1726 mydesc = description_data[locale] 1727 #if type(mydesc) is unicode: 1728 # mydesc = mydesc.encode('raw_unicode_escape') 1729 self.cursor.execute('INSERT INTO categoriesdescription VALUES (?,?,?)', (category, locale, mydesc,)) 1730 self.commitChanges()
1731
1732 - def setName(self, idpackage, name):
1733 with self.__write_mutex: 1734 self.cursor.execute('UPDATE baseinfo SET name = (?) WHERE idpackage = (?)', (name, idpackage,)) 1735 self.commitChanges()
1736
1737 - def setDependency(self, iddependency, dependency):
1738 with self.__write_mutex: 1739 self.cursor.execute('UPDATE dependenciesreference SET dependency = (?) WHERE iddependency = (?)', (dependency, iddependency,)) 1740 self.commitChanges()
1741
1742 - def setAtom(self, idpackage, atom):
1743 with self.__write_mutex: 1744 self.cursor.execute('UPDATE baseinfo SET atom = (?) WHERE idpackage = (?)', (atom, idpackage,)) 1745 self.commitChanges()
1746
1747 - def setSlot(self, idpackage, slot):
1748 with self.__write_mutex: 1749 self.cursor.execute('UPDATE baseinfo SET slot = (?) WHERE idpackage = (?)', (slot, idpackage,)) 1750 self.commitChanges()
1751
1752 - def removeLicensedata(self, license_name):
1753 with self.__write_mutex: 1754 self.cursor.execute('DELETE FROM licensedata WHERE licensename = (?)', (license_name,))
1755
1756 - def removeDependencies(self, idpackage):
1757 with self.__write_mutex: 1758 self.cursor.execute("DELETE FROM dependencies WHERE idpackage = (?)", (idpackage,)) 1759 self.commitChanges()
1760
1761 - def insertDependencies(self, idpackage, depdata):
1762 1763 dcache = set() 1764 add_dep = self.addDependency 1765 is_dep_avail = self.isDependencyAvailable 1766 def mymf(dep): 1767 1768 if dep in dcache: return 0 1769 iddep = is_dep_avail(dep) 1770 if iddep == -1: iddep = add_dep(dep) 1771 1772 deptype = 0 1773 if isinstance(depdata, dict): 1774 deptype = depdata[dep] 1775 1776 dcache.add(dep) 1777 return (idpackage, iddep, deptype,)
1778 1779 # do not place inside the with statement, otherwise there'll be an obvious lockup 1780 deps = [x for x in map(mymf, depdata) if type(x) != int] 1781 with self.__write_mutex: 1782 self.cursor.executemany('INSERT into dependencies VALUES (?,?,?)', deps)
1783
1784 - def insertManualDependencies(self, idpackage, manual_deps):
1785 mydict = {} 1786 for manual_dep in manual_deps: 1787 mydict[manual_dep] = etpConst['spm']['mdepend_id'] 1788 return self.insertDependencies(idpackage, mydict)
1789
1790 - def removeContent(self, idpackage):
1791 with self.__write_mutex: 1792 self.cursor.execute("DELETE FROM content WHERE idpackage = (?)", (idpackage,)) 1793 self.commitChanges()
1794
1795 - def insertContent(self, idpackage, content, already_formatted = False):
1796 1797 with self.__write_mutex: 1798 if already_formatted: 1799 self.cursor.executemany('INSERT INTO content VALUES (?,?,?)',((idpackage, x, y,) for a, x, y in content)) 1800 return 1801 def my_cmap(xfile): 1802 return (idpackage, xfile, content[xfile],)
1803 self.cursor.executemany('INSERT INTO content VALUES (?,?,?)',map(my_cmap, content)) 1804
1805 - def insertNeededPaths(self, library, paths):
1806 with self.__write_mutex: 1807 self.cursor.executemany('INSERT INTO neededlibrarypaths VALUES (?,?)', 1808 ((library, x,) for x in paths))
1809
1810 - def insertAutomergefiles(self, idpackage, automerge_data):
1811 with self.__write_mutex: 1812 self.cursor.executemany('INSERT INTO automergefiles VALUES (?,?,?)', 1813 ((idpackage, x, y,) for x, y in automerge_data))
1814
1815 - def removeAutomergefiles(self, idpackage):
1816 with self.__write_mutex: 1817 self.cursor.execute('DELETE FROM automergefiles WHERE idpackage = (?)', (idpackage,))
1818
1819 - def removeSignatures(self, idpackage):
1820 with self.__write_mutex: 1821 self.cursor.execute('DELETE FROM packagesignatures WHERE idpackage = (?)', (idpackage,))
1822
1823 - def removeSpmPhases(self, idpackage):
1824 with self.__write_mutex: 1825 self.cursor.execute('DELETE FROM packagespmphases WHERE idpackage = (?)', (idpackage,))
1826
1827 - def insertChangelog(self, category, name, changelog_txt):
1828 with self.__write_mutex: 1829 mytxt = changelog_txt.encode('raw_unicode_escape') 1830 self.cursor.execute('DELETE FROM packagechangelogs WHERE category = (?) AND name = (?)', (category, name,)) 1831 self.cursor.execute('INSERT INTO packagechangelogs VALUES (?,?,?)', (category, name, buffer(mytxt),))
1832
1833 - def removeChangelog(self, category, name):
1834 with self.__write_mutex: 1835 self.cursor.execute('DELETE FROM packagechangelogs WHERE category = (?) AND name = (?)', (category, name,))
1836
1837 - def insertLicenses(self, licenses_data):
1838 1839 mylicenses = licenses_data.keys() 1840 is_lic_avail = self.isLicensedataKeyAvailable 1841 def my_mf(mylicense): 1842 return not is_lic_avail(mylicense)
1843 1844 def my_mm(mylicense): 1845 lic_data = licenses_data.get(mylicense,'') 1846 # support both utf8 and str input 1847 if isinstance(lic_data, unicode): # encode to str 1848 try: 1849 lic_data = lic_data.encode('raw_unicode_escape') 1850 except (UnicodeDecodeError,): 1851 lic_data = lic_data.encode('utf-8') 1852 return (mylicense, buffer(lic_data), 0,) 1853 1854 with self.__write_mutex: 1855 self.cursor.executemany('INSERT into licensedata VALUES (?,?,?)',map(my_mm, list(set(filter(my_mf, mylicenses))))) 1856
1857 - def insertConfigProtect(self, idpackage, idprotect, mask = False):
1858 1859 mytable = 'configprotect' 1860 if mask: mytable += 'mask' 1861 with self.__write_mutex: 1862 self.cursor.execute('INSERT into %s VALUES (?,?)' % (mytable,), (idpackage, idprotect,))
1863
1864 - def insertMirrors(self, mirrors):
1865 1866 for mirrorname, mirrorlist in mirrors: 1867 # remove old 1868 self.removeMirrorEntries(mirrorname) 1869 # add new 1870 self.addMirrors(mirrorname, mirrorlist)
1871
1872 - def insertKeywords(self, idpackage, keywords):
1873 1874 mydata = set() 1875 for key in keywords: 1876 idkeyword = self.isKeywordAvailable(key) 1877 if (idkeyword == -1): 1878 # create category 1879 idkeyword = self.addKeyword(key) 1880 mydata.add((idpackage, idkeyword,)) 1881 1882 with self.__write_mutex: 1883 self.cursor.executemany('INSERT into keywords VALUES (?,?)', mydata)
1884
1885 - def insertUseflags(self, idpackage, useflags):
1886 1887 mydata = set() 1888 for flag in useflags: 1889 iduseflag = self.isUseflagAvailable(flag) 1890 if (iduseflag == -1): 1891 # create category 1892 iduseflag = self.addUseflag(flag) 1893 mydata.add((idpackage, iduseflag,)) 1894 1895 with self.__write_mutex: 1896 self.cursor.executemany('INSERT into useflags VALUES (?,?)', mydata)
1897
1898 - def insertSignatures(self, idpackage, signatures):
1899 with self.__write_mutex: 1900 sha1, sha256, sha512 = signatures['sha1'], signatures['sha256'], \ 1901 signatures['sha512'] 1902 self.cursor.execute(""" 1903 INSERT INTO packagesignatures VALUES (?,?,?,?) 1904 """, (idpackage, sha1, sha256, sha512))
1905
1906 - def insertSpmPhases(self, idpackage, phases):
1907 with self.__write_mutex: 1908 self.cursor.execute(""" 1909 INSERT INTO packagespmphases VALUES (?,?) 1910 """, (idpackage,phases,))
1911
1912 - def insertSources(self, idpackage, sources):
1913 1914 mydata = set() 1915 for source in sources: 1916 if (not source) or (source == "") or (not self.entropyTools.is_valid_string(source)): 1917 continue 1918 idsource = self.isSourceAvailable(source) 1919 if (idsource == -1): 1920 # create category 1921 idsource = self.addSource(source) 1922 mydata.add((idpackage, idsource,)) 1923 1924 with self.__write_mutex: 1925 self.cursor.executemany('INSERT into sources VALUES (?,?)', mydata)
1926
1927 - def insertConflicts(self, idpackage, conflicts):
1928 1929 def myiter(): 1930 for conflict in conflicts: 1931 yield (idpackage, conflict,)
1932 1933 with self.__write_mutex: 1934 self.cursor.executemany('INSERT into conflicts VALUES (?,?)', myiter()) 1935
1936 - def insertMessages(self, idpackage, messages):
1937 1938 def myiter(): 1939 for message in messages: 1940 yield (idpackage, message,)
1941 1942 with self.__write_mutex: 1943 self.cursor.executemany('INSERT into messages VALUES (?,?)', myiter()) 1944
1945 - def insertProvide(self, idpackage, provides):
1946 1947 def myiter(): 1948 for atom in provides: 1949 yield (idpackage, atom,)
1950 1951 with self.__write_mutex: 1952 self.cursor.executemany('INSERT into provide VALUES (?,?)', myiter()) 1953
1954 - def insertNeeded(self, idpackage, neededs):
1955 1956 mydata = set() 1957 for needed, elfclass in neededs: 1958 idneeded = self.isNeededAvailable(needed) 1959 if idneeded == -1: 1960 # create eclass 1961 idneeded = self.addNeeded(needed) 1962 mydata.add((idpackage, idneeded, elfclass)) 1963 1964 with self.__write_mutex: 1965 self.cursor.executemany('INSERT into needed VALUES (?,?,?)', mydata)
1966
1967 - def insertEclasses(self, idpackage, eclasses):
1968 1969 mydata = set() 1970 for eclass in eclasses: 1971 idclass = self.isEclassAvailable(eclass) 1972 if (idclass == -1): 1973 # create eclass 1974 idclass = self.addEclass(eclass) 1975 mydata.add((idpackage, idclass,)) 1976 1977 with self.__write_mutex: 1978 self.cursor.executemany('INSERT into eclasses VALUES (?,?)', mydata)
1979
1980 - def insertOnDiskSize(self, idpackage, mysize):
1981 with self.__write_mutex: 1982 self.cursor.execute('INSERT into sizes VALUES (?,?)', (idpackage, mysize,))
1983
1984 - def insertTrigger(self, idpackage, trigger):
1985 with self.__write_mutex: 1986 self.cursor.execute('INSERT into triggers VALUES (?,?)', (idpackage, buffer(trigger),))
1987
1988 - def insertPortageCounter(self, idpackage, counter, branch, injected):
1989 1990 if (counter != -1) and not injected: 1991 1992 if counter <= -2: 1993 # special cases 1994 counter = self.getNewNegativeCounter() 1995 1996 with self.__write_mutex: 1997 try: 1998 self.cursor.execute( 1999 'INSERT into counters VALUES ' 2000 '(?,?,?)' 2001 , ( counter, 2002 idpackage, 2003 branch, 2004 ) 2005 ) 2006 except self.dbapi2.IntegrityError: 2007 # we have a PRIMARY KEY we need to remove 2008 self._migrateCountersTable() 2009 self.cursor.execute( 2010 'INSERT into counters VALUES ' 2011 '(?,?,?)' 2012 , ( counter, 2013 idpackage, 2014 branch, 2015 ) 2016 ) 2017 except: 2018 if self.dbname == etpConst['clientdbid']: 2019 # force only for client database 2020 if self.doesTableExist("counters"): 2021 raise 2022 self.cursor.execute( 2023 'INSERT into counters VALUES ' 2024 '(?,?,?)' 2025 , ( counter, 2026 idpackage, 2027 branch, 2028 ) 2029 ) 2030 elif self.dbname.startswith(etpConst['serverdbid']): 2031 raise 2032 2033 return counter
2034
2035 - def insertCounter(self, idpackage, counter, branch = None):
2036 if not branch: branch = self.db_branch 2037 if not branch: branch = self.SystemSettings['repositories']['branch'] 2038 with self.__write_mutex: 2039 self.cursor.execute(""" 2040 DELETE FROM counters 2041 WHERE (counter = (?) OR 2042 idpackage = (?)) AND 2043 branch = (?)""", (counter, idpackage, branch,)) 2044 self.cursor.execute('INSERT INTO counters VALUES (?,?,?)', (counter, idpackage, branch,)) 2045 self.commitChanges()
2046
2047 - def setTrashedCounter(self, counter):
2048 with self.__write_mutex: 2049 self.cursor.execute('DELETE FROM trashedcounters WHERE counter = (?)', (counter,)) 2050 self.cursor.execute('INSERT INTO trashedcounters VALUES (?)', (counter,)) 2051 self.commitChanges()
2052 2053
2054 - def setCounter(self, idpackage, counter, branch = None):
2055 2056 branchstring = '' 2057 insertdata = [counter, idpackage] 2058 if branch: 2059 branchstring = ', branch = (?)' 2060 insertdata.insert(1, branch) 2061 2062 with self.__write_mutex: 2063 try: 2064 self.cursor.execute('UPDATE counters SET counter = (?) '+branchstring+' WHERE idpackage = (?)', insertdata) 2065 self.commitChanges() 2066 except: 2067 if self.dbname == etpConst['clientdbid']: 2068 raise
2069
2070 - def contentDiff(self, idpackage, dbconn, dbconn_idpackage):
2071 self.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 2072 # create a random table and fill 2073 randomtable = "cdiff%s" % (self.entropyTools.get_random_number(),) 2074 while self.doesTableExist(randomtable): 2075 randomtable = "cdiff%s" % (self.entropyTools.get_random_number(),) 2076 self.cursor.execute('CREATE TEMPORARY TABLE %s ( file VARCHAR )' % (randomtable,)) 2077 2078 try: 2079 dbconn.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 2080 dbconn.cursor.execute('select file from content where idpackage = (?)', (dbconn_idpackage,)) 2081 xfile = dbconn.cursor.fetchone() 2082 while xfile: 2083 self.cursor.execute('INSERT INTO %s VALUES (?)' % (randomtable,), (xfile[0],)) 2084 xfile = dbconn.cursor.fetchone() 2085 2086 # now compare 2087 self.cursor.execute(""" 2088 SELECT file FROM content 2089 WHERE content.idpackage = (?) AND 2090 content.file NOT IN (SELECT file from %s)""" % (randomtable,), (idpackage,)) 2091 diff = self.fetchall2set(self.cursor.fetchall()) 2092 return diff 2093 finally: 2094 self.cursor.execute('DROP TABLE IF EXISTS %s' % (randomtable,))
2095
2096 - def doCleanups(self):
2097 self.cleanupUseflags() 2098 self.cleanupSources() 2099 self.cleanupEclasses() 2100 self.cleanupNeeded() 2101 self.cleanupNeededPaths() 2102 self.cleanupDependencies() 2103 self.cleanupChangelogs()
2104
2105 - def cleanupUseflags(self):
2106 with self.__write_mutex: 2107 self.cursor.execute(""" 2108 DELETE FROM useflagsreference 2109 WHERE idflag NOT IN (SELECT idflag FROM useflags)""")
2110
2111 - def cleanupSources(self):
2112 with self.__write_mutex: 2113 self.cursor.execute(""" 2114 DELETE FROM sourcesreference 2115 WHERE idsource NOT IN (SELECT idsource FROM sources)""")
2116
2117 - def cleanupEclasses(self):
2118 with self.__write_mutex: 2119 self.cursor.execute(""" 2120 DELETE FROM eclassesreference 2121 WHERE idclass NOT IN (SELECT idclass FROM eclasses)""")
2122
2123 - def cleanupNeeded(self):
2124 with self.__write_mutex: 2125 self.cursor.execute(""" 2126 DELETE FROM neededreference 2127 WHERE idneeded NOT IN (SELECT idneeded FROM needed)""")
2128
2129 - def cleanupNeededPaths(self):
2130 with self.__write_mutex: 2131 self.cursor.execute(""" 2132 DELETE FROM neededlibrarypaths 2133 WHERE library NOT IN (SELECT library FROM neededreference)""")
2134
2135 - def cleanupDependencies(self):
2136 with self.__write_mutex: 2137 self.cursor.execute(""" 2138 DELETE FROM dependenciesreference 2139 WHERE iddependency NOT IN (SELECT iddependency FROM dependencies)""")
2140
2141 - def cleanupChangelogs(self):
2142 with self.__write_mutex: 2143 self.cursor.execute(""" 2144 DELETE FROM packagechangelogs 2145 WHERE category || "/" || name NOT IN 2146 (SELECT categories.category || "/" || baseinfo.name FROM baseinfo,categories 2147 WHERE baseinfo.idcategory = categories.idcategory 2148 )""")
2149
2150 - def getNewNegativeCounter(self):
2151 counter = -2 2152 try: 2153 self.cursor.execute('SELECT min(counter) FROM counters') 2154 dbcounter = self.cursor.fetchone() 2155 mycounter = 0 2156 if dbcounter: 2157 mycounter = dbcounter[0] 2158 2159 if mycounter >= -1: 2160 counter = -2 2161 else: 2162 counter = mycounter-1 2163 2164 except: 2165 pass 2166 return counter
2167
2168 - def getApi(self):
2169 self.cursor.execute('SELECT max(etpapi) FROM baseinfo') 2170 api = self.cursor.fetchone() 2171 if api: api = api[0] 2172 else: api = -1 2173 return api
2174
2175 - def getCategory(self, idcategory):
2176 self.cursor.execute('SELECT category from categories WHERE idcategory = (?)', (idcategory,)) 2177 cat = self.cursor.fetchone() 2178 if cat: cat = cat[0] 2179 return cat
2180
2181 - def get_category_description_from_disk(self, category):
2182 if not self.ServiceInterface: 2183 return {} 2184 return self.ServiceInterface.SpmService.get_category_description_data(category)
2185
2186 - def getIDPackage(self, atom, branch = None):
2187 branch_string = '' 2188 params = [atom] 2189 if branch: 2190 branch_string = ' AND branch = (?)' 2191 params.append(branch) 2192 self.cursor.execute('SELECT idpackage FROM baseinfo WHERE atom = (?)'+branch_string, params) 2193 idpackage = self.cursor.fetchone() 2194 if idpackage: return idpackage[0] 2195 return -1
2196
2197 - def getIDPackageFromDownload(self, download_relative_path, endswith = False):
2198 if endswith: 2199 self.cursor.execute(""" 2200 SELECT baseinfo.idpackage FROM baseinfo,extrainfo 2201 WHERE extrainfo.download LIKE (?)""", ("%"+download_relative_path,)) 2202 else: 2203 self.cursor.execute(""" 2204 SELECT baseinfo.idpackage FROM baseinfo,extrainfo 2205 WHERE extrainfo.download = (?)""", (download_relative_path,)) 2206 idpackage = self.cursor.fetchone() 2207 if idpackage: return idpackage[0] 2208 return -1
2209
2210 - def getIDPackagesFromFile(self, file):
2211 self.cursor.execute('SELECT idpackage FROM content WHERE file = (?)', (file,)) 2212 return self.fetchall2list(self.cursor.fetchall())
2213
2214 - def getIDCategory(self, category):
2215 self.cursor.execute('SELECT "idcategory" FROM categories WHERE category = (?)', (category,)) 2216 idcat = self.cursor.fetchone() 2217 if idcat: return idcat[0] 2218 return -1
2219
2220 - def getVersioningData(self, idpackage):
2221 self.cursor.execute('SELECT version,versiontag,revision FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 2222 return self.cursor.fetchone()
2223
2224 - def getStrictData(self, idpackage):
2225 self.cursor.execute(""" 2226 SELECT categories.category || "/" || baseinfo.name, 2227 baseinfo.slot,baseinfo.version,baseinfo.versiontag, 2228 baseinfo.revision,baseinfo.atom FROM baseinfo,categories 2229 WHERE baseinfo.idpackage = (?) AND 2230 baseinfo.idcategory = categories.idcategory""", (idpackage,)) 2231 return self.cursor.fetchone()
2232
2233 - def getStrictScopeData(self, idpackage):
2234 self.cursor.execute(""" 2235 SELECT atom,slot,revision FROM baseinfo 2236 WHERE idpackage = (?)""", (idpackage,)) 2237 rslt = self.cursor.fetchone() 2238 return rslt
2239
2240 - def getScopeData(self, idpackage):
2241 self.cursor.execute(""" 2242 SELECT 2243 baseinfo.atom, 2244 categories.category, 2245 baseinfo.name, 2246 baseinfo.version, 2247 baseinfo.slot, 2248 baseinfo.versiontag, 2249 baseinfo.revision, 2250 baseinfo.branch, 2251 baseinfo.etpapi 2252 FROM 2253 baseinfo, 2254 categories 2255 WHERE 2256 baseinfo.idpackage = (?) 2257 and baseinfo.idcategory = categories.idcategory 2258 """, (idpackage,)) 2259 return self.cursor.fetchone()
2260
2261 - def getBaseData(self, idpackage):
2262 2263 sql = """ 2264 SELECT 2265 baseinfo.atom, 2266 baseinfo.name, 2267 baseinfo.version, 2268 baseinfo.versiontag, 2269 extrainfo.description, 2270 categories.category, 2271 flags.chost, 2272 flags.cflags, 2273 flags.cxxflags, 2274 extrainfo.homepage, 2275 licenses.license, 2276 baseinfo.branch, 2277 extrainfo.download, 2278 extrainfo.digest, 2279 baseinfo.slot, 2280 baseinfo.etpapi, 2281 extrainfo.datecreation, 2282 extrainfo.size, 2283 baseinfo.revision 2284 FROM 2285 baseinfo, 2286 extrainfo, 2287 categories, 2288 flags, 2289 licenses 2290 WHERE 2291 baseinfo.idpackage = (?) 2292 and baseinfo.idpackage = extrainfo.idpackage 2293 and baseinfo.idcategory = categories.idcategory 2294 and extrainfo.idflags = flags.idflags 2295 and baseinfo.idlicense = licenses.idlicense 2296 """ 2297 self.cursor.execute(sql, (idpackage,)) 2298 return self.cursor.fetchone()
2299
2300 - def getTriggerInfo(self, idpackage):
2301 2302 atom, category, name, \ 2303 version, slot, versiontag, \ 2304 revision, branch, etpapi = self.getScopeData(idpackage) 2305 chost, cflags, cxxflags = self.retrieveCompileFlags(idpackage) 2306 2307 data = { 2308 'atom': atom, 2309 'category': category, 2310 'name': name, 2311 'version': version, 2312 'versiontag': versiontag, 2313 'revision': revision, 2314 'branch': branch, 2315 'chost': chost, 2316 'cflags': cflags, 2317 'cxxflags': cxxflags, 2318 'etpapi': etpapi, 2319 'trigger': self.retrieveTrigger(idpackage), 2320 'eclasses': self.retrieveEclasses(idpackage), 2321 'content': self.retrieveContent(idpackage), 2322 'spm_phases': self.retrieveSpmPhases(idpackage), 2323 } 2324 return data
2325
2326 - def getPackageData(self, idpackage, get_content = True, 2327 content_insert_formatted = False, trigger_unicode = True):
2328 data = {} 2329 2330 try: 2331 atom, name, version, versiontag, \ 2332 description, category, chost, \ 2333 cflags, cxxflags,homepage, \ 2334 mylicense, branch, download, \ 2335 digest, slot, etpapi, \ 2336 datecreation, size, revision = self.getBaseData(idpackage) 2337 except TypeError: 2338 return None 2339 2340 content = {} 2341 if get_content: 2342 content = self.retrieveContent( 2343 idpackage, extended = True, 2344 formatted = True, insert_formatted = content_insert_formatted 2345 ) 2346 2347 sources = self.retrieveSources(idpackage) 2348 mirrornames = set() 2349 for x in sources: 2350 if x.startswith("mirror://"): 2351 mirrornames.add(x.split("/")[2]) 2352 2353 data = { 2354 'atom': atom, 2355 'name': name, 2356 'version': version, 2357 'versiontag':versiontag, 2358 'description': description, 2359 'category': category, 2360 'chost': chost, 2361 'cflags': cflags, 2362 'cxxflags': cxxflags, 2363 'homepage': homepage, 2364 'license': mylicense, 2365 'branch': branch, 2366 'download': download, 2367 'digest': digest, 2368 'slot': slot, 2369 'etpapi': etpapi, 2370 'datecreation': datecreation, 2371 'size': size, 2372 'revision': revision, 2373 # risky to add to the sql above, still 2374 'counter': self.retrieveCounter(idpackage), 2375 'messages': self.retrieveMessages(idpackage), 2376 'trigger': self.retrieveTrigger(idpackage, get_unicode = trigger_unicode), 2377 'disksize': self.retrieveOnDiskSize(idpackage), 2378 'changelog': self.retrieveChangelog(idpackage), 2379 'injected': self.isInjected(idpackage), 2380 'systempackage': self.isSystemPackage(idpackage), 2381 'config_protect': self.retrieveProtect(idpackage), 2382 'config_protect_mask': self.retrieveProtectMask(idpackage), 2383 'useflags': self.retrieveUseflags(idpackage), 2384 'keywords': self.retrieveKeywords(idpackage), 2385 'sources': sources, 2386 'eclasses': self.retrieveEclasses(idpackage), 2387 'needed': self.retrieveNeeded(idpackage, extended = True), 2388 'needed_paths': self.retrieveNeededPaths(idpackage), 2389 'provide': self.retrieveProvide(idpackage), 2390 'conflicts': self.retrieveConflicts(idpackage), 2391 'licensedata': self.retrieveLicensedata(idpackage), 2392 'content': content, 2393 'dependencies': dict((x, y,) for x, y in \ 2394 self.retrieveDependencies(idpackage, extended = True)), 2395 'mirrorlinks': [[x,self.retrieveMirrorInfo(x)] for x in mirrornames], 2396 'signatures': self.retrieveSignatures(idpackage), 2397 'spm_phases': self.retrieveSpmPhases(idpackage), 2398 } 2399 2400 return data
2401
2402 - def fetchall2set(self, item):
2403 mycontent = set() 2404 for x in item: 2405 mycontent |= set(x) 2406 return mycontent
2407
2408 - def fetchall2list(self, item):
2409 content = [] 2410 for x in item: 2411 content += list(x) 2412 return content
2413
2414 - def fetchone2list(self, item):
2415 return list(item)
2416
2417 - def fetchone2set(self, item):
2418 return set(item)
2419
2420 - def clearCache(self, depends = False):
2421 2422 self.live_cache.clear() 2423 def do_clear(name): 2424 dump_path = os.path.join(etpConst['dumpstoragedir'], name) 2425 dump_dir = os.path.dirname(dump_path) 2426 if os.path.isdir(dump_dir): 2427 for item in os.listdir(dump_dir): 2428 try: os.remove(os.path.join(dump_dir, item)) 2429 except OSError: pass
2430 2431 do_clear("%s/%s/" % (self.dbMatchCacheKey, self.dbname,)) 2432 if depends: 2433 do_clear(etpCache['depends_tree']) 2434 do_clear(etpCache['dep_tree']) 2435 do_clear(etpCache['filter_satisfied_deps']) 2436
2437 - def retrieveRepositoryUpdatesDigest(self, repository):
2438 if not self.doesTableExist("treeupdates"): 2439 return -1 2440 self.cursor.execute('SELECT digest FROM treeupdates WHERE repository = (?)', (repository,)) 2441 mydigest = self.cursor.fetchone() 2442 if mydigest: 2443 return mydigest[0] 2444 else: 2445 return -1
2446
2447 - def listAllTreeUpdatesActions(self, no_ids_repos = False):
2448 if no_ids_repos: 2449 self.cursor.execute('SELECT command,branch,date FROM treeupdatesactions') 2450 else: 2451 self.cursor.execute('SELECT * FROM treeupdatesactions') 2452 return self.cursor.fetchall()
2453
2454 - def retrieveTreeUpdatesActions(self, repository, forbranch = None):
2455 2456 if not self.doesTableExist("treeupdatesactions"): return [] 2457 if forbranch == None: forbranch = self.db_branch 2458 params = [repository] 2459 branch_string = '' 2460 if forbranch: 2461 branch_string = 'and branch = (?)' 2462 params.append(forbranch) 2463 2464 self.cursor.execute(""" 2465 SELECT command FROM treeupdatesactions WHERE 2466 repository = (?) %s order by date""" % (branch_string,), params) 2467 return self.fetchall2list(self.cursor.fetchall())
2468 2469 # mainly used to restore a previous table, used by reagent in --initialize
2470 - def bumpTreeUpdatesActions(self, updates):
2471 with self.__write_mutex: 2472 self.cursor.execute('DELETE FROM treeupdatesactions') 2473 self.cursor.executemany('INSERT INTO treeupdatesactions VALUES (?,?,?,?,?)', updates) 2474 self.commitChanges()
2475
2476 - def removeTreeUpdatesActions(self, repository):
2477 with self.__write_mutex: 2478 self.cursor.execute('DELETE FROM treeupdatesactions WHERE repository = (?)', (repository,)) 2479 self.commitChanges()
2480
2481 - def insertTreeUpdatesActions(self, updates, repository):
2482 with self.__write_mutex: 2483 myupdates = [[repository]+list(x) for x in updates] 2484 self.cursor.executemany('INSERT INTO treeupdatesactions VALUES (NULL,?,?,?,?)', myupdates) 2485 self.commitChanges()
2486
2487 - def setRepositoryUpdatesDigest(self, repository, digest):
2488 with self.__write_mutex: 2489 self.cursor.execute('DELETE FROM treeupdates where repository = (?)', (repository,)) # doing it for safety 2490 self.cursor.execute('INSERT INTO treeupdates VALUES (?,?)', (repository, digest,))
2491
2492 - def addRepositoryUpdatesActions(self, repository, actions, branch):
2493 2494 mytime = str(self.entropyTools.get_current_unix_time()) 2495 with self.__write_mutex: 2496 myupdates = [ 2497 (repository, x, branch, mytime,) for x in actions \ 2498 if not self.doesTreeupdatesActionExist(repository, x, branch) 2499 ] 2500 self.cursor.executemany('INSERT INTO treeupdatesactions VALUES (NULL,?,?,?,?)', myupdates)
2501
2502 - def doesTreeupdatesActionExist(self, repository, command, branch):
2503 self.cursor.execute(""" 2504 SELECT * FROM treeupdatesactions 2505 WHERE repository = (?) and command = (?) and branch = (?)""", (repository, command, branch,)) 2506 result = self.cursor.fetchone() 2507 if result: 2508 return True 2509 return False
2510
2511 - def clearPackageSets(self):
2512 self.cursor.execute('DELETE FROM packagesets')
2513
2514 - def insertPackageSets(self, sets_data):
2515 2516 mysets = [] 2517 for setname in sorted(sets_data.keys()): 2518 for dependency in sorted(sets_data[setname]): 2519 try: 2520 mysets.append((unicode(setname), unicode(dependency),)) 2521 except (UnicodeDecodeError, UnicodeEncodeError,): 2522 continue 2523 2524 with self.__write_mutex: 2525 self.cursor.executemany('INSERT INTO packagesets VALUES (?,?)', mysets)
2526
2527 - def retrievePackageSets(self):
2528 if not self.doesTableExist("packagesets"): return {} 2529 self.cursor.execute('SELECT setname,dependency FROM packagesets') 2530 data = self.cursor.fetchall() 2531 sets = {} 2532 for setname, dependency in data: 2533 if not sets.has_key(setname): 2534 sets[setname] = set() 2535 sets[setname].add(dependency) 2536 return sets
2537
2538 - def retrievePackageSet(self, setname):
2539 self.cursor.execute('SELECT dependency FROM packagesets WHERE setname = (?)', (setname,)) 2540 return self.fetchall2set(self.cursor.fetchall())
2541
2542 - def retrieveSystemPackages(self):
2543 self.cursor.execute('SELECT idpackage FROM systempackages') 2544 return self.fetchall2set(self.cursor.fetchall())
2545
2546 - def retrieveAtom(self, idpackage):
2547 self.cursor.execute('SELECT atom FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 2548 atom = self.cursor.fetchone() 2549 if atom: return atom[0]
2550
2551 - def retrieveBranch(self, idpackage):
2552 self.cursor.execute('SELECT branch FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 2553 br = self.cursor.fetchone() 2554 if br: return br[0]
2555
2556 - def retrieveTrigger(self, idpackage, get_unicode = False):
2557 self.cursor.execute('SELECT data FROM triggers WHERE idpackage = (?)', (idpackage,)) 2558 trigger = self.cursor.fetchone() 2559 if not trigger: 2560 return '' # FIXME backward compatibility with <=0.52.x 2561 if not get_unicode: 2562 return trigger[0] 2563 return unicode(trigger[0], 'raw_unicode_escape')
2564
2565 - def retrieveDownloadURL(self, idpackage):
2566 self.cursor.execute('SELECT download FROM extrainfo WHERE idpackage = (?)', (idpackage,)) 2567 download = self.cursor.fetchone() 2568 if download: return download[0]
2569
2570 - def retrieveDescription(self, idpackage):
2571 self.cursor.execute('SELECT description FROM extrainfo WHERE idpackage = (?)', (idpackage,)) 2572 description = self.cursor.fetchone() 2573 if description: return description[0]
2574
2575 - def retrieveHomepage(self, idpackage):
2576 self.cursor.execute('SELECT homepage FROM extrainfo WHERE idpackage = (?)', (idpackage,)) 2577 home = self.cursor.fetchone() 2578 if home: return home[0]
2579
2580 - def retrieveCounter(self, idpackage):
2581 self.cursor.execute(""" 2582 SELECT counters.counter FROM counters,baseinfo 2583 WHERE counters.idpackage = (?) AND 2584 baseinfo.idpackage = counters.idpackage AND 2585 baseinfo.branch = counters.branch""", (idpackage,)) 2586 mycounter = self.cursor.fetchone() 2587 if mycounter: return mycounter[0] 2588 return -1
2589
2590 - def retrieveMessages(self, idpackage):
2591 self.cursor.execute('SELECT message FROM messages WHERE idpackage = (?)', (idpackage,)) 2592 return self.fetchall2list(self.cursor.fetchall())
2593 2594 # in bytes
2595 - def retrieveSize(self, idpackage):
2596 self.cursor.execute('SELECT size FROM extrainfo WHERE idpackage = (?)', (idpackage,)) 2597 size = self.cursor.fetchone() 2598 if size: return size[0]
2599 2600 # in bytes
2601 - def retrieveOnDiskSize(self, idpackage):
2602 self.cursor.execute('SELECT size FROM sizes WHERE idpackage = (?)', (idpackage,)) 2603 size = self.cursor.fetchone() # do not use [0]! 2604 if not size: size = 0 2605 else: size = size[0] 2606 return size
2607
2608 - def retrieveDigest(self, idpackage):
2609 self.cursor.execute('SELECT digest FROM extrainfo WHERE idpackage = (?)', (idpackage,)) 2610 digest = self.cursor.fetchone() 2611 if digest: return digest[0]
2612
2613 - def retrieveSignatures(self, idpackage):
2614 mydict = { 2615 'sha1': None, 2616 'sha256': None, 2617 'sha512': None, 2618 } 2619 # FIXME: remove this check in future 2620 if self.doesTableExist('packagesignatures'): 2621 self.cursor.execute(""" 2622 SELECT sha1, sha256, sha512 FROM packagesignatures 2623 WHERE idpackage = (?)""", (idpackage,)) 2624 data = self.cursor.fetchone() 2625 if data: 2626 mydict['sha1'], mydict['sha256'], mydict['sha512'] = data 2627 return mydict
2628
2629 - def retrieveName(self, idpackage):
2630 self.cursor.execute('SELECT name FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 2631 name = self.cursor.fetchone() 2632 if name: return name[0]
2633
2634 - def retrieveKeySlot(self, idpackage):
2635 self.cursor.execute(""" 2636 SELECT categories.category || "/" || baseinfo.name,baseinfo.slot FROM baseinfo,categories 2637 WHERE baseinfo.idpackage = (?) and baseinfo.idcategory = categories.idcategory""", (idpackage,)) 2638 data = self.cursor.fetchone() 2639 return data
2640
2641 - def retrieveKeySlotAggregated(self, idpackage):
2642 self.cursor.execute(""" 2643 SELECT categories.category || "/" || baseinfo.name || ":" || baseinfo.slot FROM baseinfo,categories 2644 WHERE baseinfo.idpackage = (?) and baseinfo.idcategory = categories.idcategory""", (idpackage,)) 2645 data = self.cursor.fetchone() 2646 if data: return data[0]
2647
2648 - def retrieveKeySlotTag(self, idpackage):
2649 self.cursor.execute(""" 2650 SELECT categories.category || "/" || baseinfo.name,baseinfo.slot,baseinfo.versiontag FROM baseinfo,categories 2651 WHERE baseinfo.idpackage = (?) and baseinfo.idcategory = categories.idcategory""", (idpackage,)) 2652 data = self.cursor.fetchone() 2653 return data
2654
2655 - def retrieveVersion(self, idpackage):
2656 self.cursor.execute('SELECT version FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 2657 ver = self.cursor.fetchone() 2658 if ver: return ver[0]
2659
2660 - def retrieveRevision(self, idpackage):
2661 self.cursor.execute('SELECT revision FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 2662 rev = self.cursor.fetchone() 2663 if rev: return rev[0]
2664
2665 - def retrieveDateCreation(self, idpackage):
2666 self.cursor.execute('SELECT datecreation FROM extrainfo WHERE idpackage = (?)', (idpackage,)) 2667 date = self.cursor.fetchone() 2668 if date: return date[0]
2669
2670 - def retrieveApi(self, idpackage):
2671 self.cursor.execute('SELECT etpapi FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 2672 api = self.cursor.fetchone() 2673 if api: return api[0]
2674
2675 - def retrieveUseflags(self, idpackage):
2676 self.cursor.execute(""" 2677 SELECT flagname FROM useflags,useflagsreference 2678 WHERE useflags.idpackage = (?) AND 2679 useflags.idflag = useflagsreference.idflag""", (idpackage,)) 2680 return self.fetchall2set(self.cursor.fetchall())
2681
2682 - def retrieveEclasses(self, idpackage):
2683 self.cursor.execute(""" 2684 SELECT classname FROM eclasses,eclassesreference 2685 WHERE eclasses.idpackage = (?) AND 2686 eclasses.idclass = eclassesreference.idclass""", (idpackage,)) 2687 return self.fetchall2set(self.cursor.fetchall())
2688
2689 - def retrieveSpmPhases(self, idpackage):
2690 # FIXME: remove this check in future: 2691 if not self.doesTableExist('packagespmphases'): 2692 return None 2693 self.cursor.execute(""" 2694 SELECT phases FROM packagespmphases 2695 WHERE idpackage = (?) 2696 """, (idpackage,)) 2697 rslt = self.cursor.fetchone() 2698 if rslt: return rslt[0]
2699
2700 - def retrieveNeededRaw(self, idpackage):
2701 self.cursor.execute(""" 2702 SELECT library FROM needed,neededreference 2703 WHERE needed.idpackage = (?) AND 2704 needed.idneeded = neededreference.idneeded""", (idpackage,)) 2705 return self.fetchall2set(self.cursor.fetchall())
2706
2707 - def retrieveNeeded(self, idpackage, extended = False, format = False):
2708 2709 if extended: 2710 self.cursor.execute(""" 2711 SELECT library,elfclass FROM needed,neededreference 2712 WHERE needed.idpackage = (?) AND 2713 needed.idneeded = neededreference.idneeded order by library""", (idpackage,)) 2714 needed = self.cursor.fetchall() 2715 else: 2716 self.cursor.execute(""" 2717 SELECT library FROM needed,neededreference 2718 WHERE needed.idpackage = (?) AND 2719 needed.idneeded = neededreference.idneeded ORDER BY library""", (idpackage,)) 2720 needed = self.fetchall2list(self.cursor.fetchall()) 2721 2722 if extended and format: 2723 data = {} 2724 for lib, elfclass in needed: 2725 data[lib] = elfclass 2726 needed = data 2727 2728 return needed
2729
2730 - def retrieveNeededPaths(self, idpackage):
2731 if not self.doesTableExist('neededlibrarypaths'): 2732 return {} 2733 self.cursor.execute(""" 2734 SELECT neededlibrarypaths.library, neededlibrarypaths.path FROM 2735 neededlibrarypaths, neededreference, needed WHERE 2736 needed.idpackage = (?) AND needed.idneeded = neededreference.idneeded 2737 AND neededreference.library = neededlibrarypaths.library 2738 """, (idpackage,)) 2739 data = {} 2740 for lib, path in self.cursor.fetchall(): 2741 obj = data.setdefault(lib, set()) 2742 obj.add(path) 2743 return data
2744
2745 - def retrieveNeededLibraryPaths(self, needed_library_name, elfclass = -1):
2746 if not self.doesTableExist('neededlibrarypaths'): 2747 return set() 2748 if elfclass != -1: 2749 self.cursor.execute(""" 2750 SELECT path FROM neededlibrarypaths, neededreference, needed 2751 WHERE neededlibrarypaths.library = (?) AND 2752 needed.elfclass = (?) AND 2753 neededreference.library = neededlibrarypaths.library AND 2754 needed.idneeded = neededreference.idneeded 2755 """, (needed_library_name, elfclass,)) 2756 else: 2757 self.cursor.execute(""" 2758 SELECT path FROM neededlibrarypaths WHERE library = (?) 2759 """, (needed_library_name,)) 2760 return self.fetchall2set(self.cursor.fetchall())
2761
2762 - def retrieveNeededLibraryIdpackages(self):
2763 if not self.doesTableExist('neededlibraryidpackages'): 2764 return [] 2765 self.cursor.execute('SELECT idpackage, library, elfclass FROM neededlibraryidpackages') 2766 return self.cursor.fetchall()
2767
2768 - def clearNeededLibraryIdpackages(self):
2769 if not self.doesTableExist('neededlibraryidpackages'): 2770 return 2771 self.cursor.execute('DELETE FROM neededlibraryidpackages')
2772
2773 - def setNeededLibraryIdpackages(self, library_map):
2774 if not self.doesTableExist('neededlibraryidpackages'): 2775 return 2776 self.cursor.executemany('INSERT INTO neededlibraryidpackages VALUES (?,?,?)', library_map)
2777
2778 - def retrieveConflicts(self, idpackage):
2779 self.cursor.execute('SELECT conflict FROM conflicts WHERE idpackage = (?)', (idpackage,)) 2780 return self.fetchall2set(self.cursor.fetchall())
2781
2782 - def retrieveProvide(self, idpackage):
2783 self.cursor.execute('SELECT atom FROM provide WHERE idpackage = (?)', (idpackage,)) 2784 return self.fetchall2set(self.cursor.fetchall())
2785
2786 - def retrieveDependenciesList(self, idpackage):
2787 self.cursor.execute(""" 2788 SELECT dependenciesreference.dependency FROM dependencies,dependenciesreference 2789 WHERE dependencies.idpackage = (?) AND 2790 dependencies.iddependency = dependenciesreference.iddependency 2791 UNION SELECT "!" || conflict FROM conflicts 2792 WHERE idpackage = (?)""", (idpackage, idpackage,)) 2793 return self.fetchall2set(self.cursor.fetchall())
2794
2795 - def retrievePostDependencies(self, idpackage, extended = False):
2796 return self.retrieveDependencies(idpackage, extended = extended, deptype = etpConst['spm']['pdepend_id'])
2797
2798 - def retrieveManualDependencies(self, idpackage, extended = False):
2799 return self.retrieveDependencies(idpackage, extended = extended, deptype = etpConst['spm']['mdepend_id'])
2800
2801 - def retrieveDependencies(self, idpackage, extended = False, deptype = None, 2802 exclude_deptypes = None):
2803 2804 searchdata = [idpackage] 2805 2806 depstring = '' 2807 if deptype != None: 2808 depstring = ' and dependencies.type = (?)' 2809 searchdata.append(deptype) 2810 2811 excluded_deptypes_query = "" 2812 if exclude_deptypes != None: 2813 for dep_type in exclude_deptypes: 2814 excluded_deptypes_query += " AND dependencies.type != %s" % ( 2815 dep_type,) 2816 2817 if extended: 2818 self.cursor.execute(""" 2819 SELECT dependenciesreference.dependency,dependencies.type 2820 FROM dependencies,dependenciesreference 2821 WHERE dependencies.idpackage = (?) AND 2822 dependencies.iddependency = dependenciesreference.iddependency %s %s""" % ( 2823 depstring,excluded_deptypes_query,), searchdata) 2824 deps = self.cursor.fetchall() 2825 else: 2826 self.cursor.execute(""" 2827 SELECT dependenciesreference.dependency 2828 FROM dependencies,dependenciesreference 2829 WHERE dependencies.idpackage = (?) AND 2830 dependencies.iddependency = dependenciesreference.iddependency %s %s""" % ( 2831 depstring,excluded_deptypes_query,), searchdata) 2832 deps = self.fetchall2set(self.cursor.fetchall()) 2833 2834 return deps
2835
2836 - def retrieveIdDependencies(self, idpackage):
2837 self.cursor.execute('SELECT iddependency FROM dependencies WHERE idpackage = (?)', (idpackage,)) 2838 return self.fetchall2set(self.cursor.fetchall())
2839
2840 - def retrieveDependencyFromIddependency(self, iddependency):
2841 self.cursor.execute('SELECT dependency FROM dependenciesreference WHERE iddependency = (?)', (iddependency,)) 2842 dep = self.cursor.fetchone() 2843 if dep: dep = dep[0] 2844 return dep
2845
2846 - def retrieveKeywords(self, idpackage):
2847 self.cursor.execute(""" 2848 SELECT keywordname FROM keywords,keywordsreference 2849 WHERE keywords.idpackage = (?) AND 2850 keywords.idkeyword = keywordsreference.idkeyword""", (idpackage,)) 2851 return self.fetchall2set(self.cursor.fetchall())
2852
2853 - def retrieveProtect(self, idpackage):
2854 self.cursor.execute(""" 2855 SELECT protect FROM configprotect,configprotectreference 2856 WHERE configprotect.idpackage = (?) AND 2857 configprotect.idprotect = configprotectreference.idprotect""", (idpackage,)) 2858 protect = self.cursor.fetchone() 2859 if not protect: protect = '' 2860 else: protect = protect[0] 2861 return protect
2862
2863 - def retrieveProtectMask(self, idpackage):
2864 self.cursor.execute(""" 2865 SELECT protect FROM configprotectmask,configprotectreference 2866 WHERE idpackage = (?) AND 2867 configprotectmask.idprotect = configprotectreference.idprotect""", (idpackage,)) 2868 protect = self.cursor.fetchone() 2869 if not protect: protect = '' 2870 else: protect = protect[0] 2871 return protect
2872
2873 - def retrieveSources(self, idpackage, extended = False):
2874 self.cursor.execute(""" 2875 SELECT sourcesreference.source FROM sources,sourcesreference 2876 WHERE idpackage = (?) AND 2877 sources.idsource = sourcesreference.idsource""", (idpackage,)) 2878 sources = self.fetchall2set(self.cursor.fetchall()) 2879 if not extended: 2880 return sources 2881 2882 source_data = {} 2883 mirror_str = "mirror://" 2884 for source in sources: 2885 source_data[source] = set() 2886 if source.startswith(mirror_str): 2887 mirrorname = source.split("/")[2] 2888 mirror_url = source.split("/", 3)[3:][0] 2889 source_data[source] |= set([os.path.join(url, mirror_url) for url in self.retrieveMirrorInfo(mirrorname)]) 2890 else: 2891 source_data[source].add(source) 2892 2893 return source_data
2894
2895 - def retrieveAutomergefiles(self, idpackage, get_dict = False):
2896 if not self.doesTableExist('automergefiles'): 2897 self.createAutomergefilesTable() 2898 # like portage does 2899 self.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 2900 self.cursor.execute('SELECT configfile, md5 FROM automergefiles WHERE idpackage = (?)', (idpackage,)) 2901 data = self.cursor.fetchall() 2902 if get_dict: 2903 data = dict(((x, y,) for x, y in data)) 2904 return data
2905
2906 - def retrieveContent(self, idpackage, extended = False, contentType = None, formatted = False, insert_formatted = False, order_by = ''):
2907 2908 extstring = '' 2909 if extended: 2910 extstring = ",type" 2911 extstring_idpackage = '' 2912 if insert_formatted: 2913 extstring_idpackage = 'idpackage,' 2914 2915 searchkeywords = [idpackage] 2916 contentstring = '' 2917 if contentType: 2918 searchkeywords.append(contentType) 2919 contentstring = ' and type = (?)' 2920 2921 order_by_string = '' 2922 if order_by: 2923 order_by_string = ' order by %s' % (order_by,) 2924 2925 did_try = False 2926 while 1: 2927 try: 2928 2929 self.cursor.execute('SELECT %s file%s FROM content WHERE idpackage = (?) %s%s' % ( 2930 extstring_idpackage, extstring, contentstring, order_by_string,), 2931 searchkeywords) 2932 2933 if extended and insert_formatted: 2934 fl = self.cursor.fetchall() 2935 elif extended and formatted: 2936 fl = {} 2937 items = self.cursor.fetchone() 2938 while items: 2939 fl[items[0]] = items[1] 2940 items = self.cursor.fetchone() 2941 elif extended: 2942 fl = self.cursor.fetchall() 2943 else: 2944 if order_by: 2945 fl = self.fetchall2list(self.cursor.fetchall()) 2946 else: 2947 fl = self.fetchall2set(self.cursor.fetchall()) 2948 break 2949 except (self.dbapi2.OperationalError,): 2950 if did_try: 2951 raise 2952 did_try = True 2953 # XXX support for old entropy db entries, which were 2954 # not inserted in utf-8 2955 self.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 2956 continue 2957 return fl
2958
2959 - def retrieveChangelog(self, idpackage):
2960 if not self.doesTableExist('packagechangelogs'): 2961 return None 2962 self.cursor.execute(""" 2963 SELECT packagechangelogs.changelog FROM packagechangelogs,baseinfo,categories 2964 WHERE baseinfo.idpackage = (?) AND 2965 baseinfo.idcategory = categories.idcategory AND 2966 packagechangelogs.name = baseinfo.name AND 2967 packagechangelogs.category = categories.category""", (idpackage,)) 2968 changelog = self.cursor.fetchone() 2969 if changelog: 2970 changelog = changelog[0] 2971 try: 2972 return unicode(changelog, 'raw_unicode_escape') 2973 except UnicodeDecodeError: 2974 return unicode(changelog, 'utf-8')
2975
2976 - def retrieveChangelogByKey(self, category, name):
2977 if not self.doesTableExist('packagechangelogs'): 2978 return None 2979 self.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 2980 self.cursor.execute('SELECT changelog FROM packagechangelogs WHERE category = (?) AND name = (?)', (category, name,)) 2981 changelog = self.cursor.fetchone() 2982 if changelog: return unicode(changelog[0], 'raw_unicode_escape')
2983
2984 - def retrieveSlot(self, idpackage):
2985 self.cursor.execute('SELECT slot FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 2986 slot = self.cursor.fetchone() 2987 if slot: return slot[0]
2988
2989 - def retrieveVersionTag(self, idpackage):
2990 self.cursor.execute('SELECT versiontag FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 2991 vtag = self.cursor.fetchone() 2992 if vtag: return vtag[0]
2993
2994 - def retrieveMirrorInfo(self, mirrorname):
2995 self.cursor.execute('SELECT mirrorlink FROM mirrorlinks WHERE mirrorname = (?)', (mirrorname,)) 2996 mirrorlist = self.fetchall2set(self.cursor.fetchall()) 2997 return mirrorlist
2998
2999 - def retrieveCategory(self, idpackage):
3000 self.cursor.execute(""" 3001 SELECT category FROM baseinfo,categories 3002 WHERE baseinfo.idpackage = (?) AND 3003 baseinfo.idcategory = categories.idcategory""", (idpackage,)) 3004 cat = self.cursor.fetchone() 3005 if cat: return cat[0]
3006
3007 - def retrieveCategoryDescription(self, category):
3008 data = {} 3009 self.cursor.execute('SELECT description,locale FROM categoriesdescription WHERE category = (?)', (category,)) 3010 description_data = self.cursor.fetchall() 3011 for description, locale in description_data: 3012 data[locale] = description 3013 return data
3014
3015 - def retrieveLicensedata(self, idpackage):
3016 3017 # insert license information 3018 licenses = self.retrieveLicense(idpackage) 3019 if licenses == None: 3020 return {} 3021 licenses = licenses.split() 3022 licdata = {} 3023 for licname in licenses: 3024 licname = licname.strip() 3025 if not self.entropyTools.is_valid_string(licname): 3026 continue 3027 3028 self.cursor.execute('SELECT text FROM licensedata WHERE licensename = (?)', (licname,)) 3029 lictext = self.cursor.fetchone() 3030 if lictext != None: 3031 lictext = lictext[0] 3032 try: 3033 licdata[licname] = unicode(lictext, 'raw_unicode_escape') 3034 except UnicodeDecodeError: 3035 licdata[licname] = unicode(lictext, 'utf-8') 3036 3037 return licdata
3038
3039 - def retrieveLicensedataKeys(self, idpackage):
3040 3041 licenses = self.retrieveLicense(idpackage) 3042 if licenses == None: 3043 return set() 3044 licenses = licenses.split() 3045 licdata = set() 3046 for licname in licenses: 3047 licname = licname.strip() 3048 if not self.entropyTools.is_valid_string(licname): 3049 continue 3050 self.cursor.execute('SELECT licensename FROM licensedata WHERE licensename = (?)', (licname,)) 3051 licidentifier = self.cursor.fetchone() 3052 if licidentifier: 3053 licdata.add(licidentifier[0]) 3054 3055 return licdata
3056
3057 - def retrieveLicenseText(self, license_name):
3058 3059 self.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 3060 3061 self.cursor.execute('SELECT text FROM licensedata WHERE licensename = (?)', (license_name,)) 3062 text = self.cursor.fetchone() 3063 if not text: 3064 return None 3065 return str(text[0])
3066
3067 - def retrieveLicense(self, idpackage):
3068 self.cursor.execute(""" 3069 SELECT license FROM baseinfo,licenses 3070 WHERE baseinfo.idpackage = (?) AND 3071 baseinfo.idlicense = licenses.idlicense""", (idpackage,)) 3072 licname = self.cursor.fetchone() 3073 if licname: return licname[0]
3074
3075 - def retrieveCompileFlags(self, idpackage):
3076 self.cursor.execute(""" 3077 SELECT chost,cflags,cxxflags FROM flags,extrainfo 3078 WHERE extrainfo.idpackage = (?) AND 3079 extrainfo.idflags = flags.idflags""", (idpackage,)) 3080 flags = self.cursor.fetchone() 3081 if not flags: 3082 flags = ("N/A", "N/A", "N/A",) 3083 return flags
3084
3085 - def retrieveDepends(self, idpackage, atoms = False, key_slot = False, 3086 exclude_deptypes = None):
3087 3088 # WARNING: never remove this, otherwise equo.db 3089 # (client database) dependstable will be always broken (trust me) 3090 # sanity check on the table 3091 if not self.isDependsTableSane(): # is empty, need generation 3092 self.regenerateDependsTable(output = False) 3093 3094 excluded_deptypes_query = "" 3095 if exclude_deptypes != None: 3096 for dep_type in exclude_deptypes: 3097 excluded_deptypes_query += " AND dependencies.type != %s" % ( 3098 dep_type,) 3099 3100 if atoms: 3101 self.cursor.execute(""" 3102 SELECT baseinfo.atom FROM dependstable,dependencies,baseinfo 3103 WHERE dependstable.idpackage = (?) AND 3104 dependstable.iddependency = dependencies.iddependency AND 3105 baseinfo.idpackage = dependencies.idpackage %s""" % ( 3106 excluded_deptypes_query,), (idpackage,)) 3107 result = self.fetchall2set(self.cursor.fetchall()) 3108 elif key_slot: 3109 self.cursor.execute(""" 3110 SELECT categories.category || "/" || baseinfo.name,baseinfo.slot 3111 FROM baseinfo,categories,dependstable,dependencies 3112 WHERE dependstable.idpackage = (?) AND 3113 dependstable.iddependency = dependencies.iddependency AND 3114 baseinfo.idpackage = dependencies.idpackage AND 3115 categories.idcategory = baseinfo.idcategory %s""" % ( 3116 excluded_deptypes_query,), (idpackage,)) 3117 result = self.cursor.fetchall() 3118 else: 3119 self.cursor.execute(""" 3120 SELECT dependencies.idpackage FROM dependstable,dependencies 3121 WHERE dependstable.idpackage = (?) AND 3122 dependstable.iddependency = dependencies.iddependency %s""" % ( 3123 excluded_deptypes_query,), (idpackage,)) 3124 result = self.fetchall2set(self.cursor.fetchall()) 3125 3126 return result
3127
3128 - def retrieveUnusedIdpackages(self):
3129 3130 # WARNING: never remove this, otherwise equo.db (client database) 3131 # dependstable will be always broken (trust me) 3132 # sanity check on the table 3133 if not self.isDependsTableSane(): # is empty, need generation 3134 self.regenerateDependsTable(output = False) 3135 3136 self.cursor.execute(""" 3137 SELECT idpackage FROM baseinfo 3138 WHERE idpackage NOT IN (SELECT idpackage FROM dependstable) ORDER BY atom 3139 """) 3140 return self.fetchall2list(self.cursor.fetchall())
3141
3142 - def isPackageAvailable(self, pkgatom):
3143 # You must provide the full atom to this function 3144 # WARNING: this function does not support branches 3145 pkgatom = self.entropyTools.remove_package_operators(pkgatom) 3146 self.cursor.execute('SELECT idpackage FROM baseinfo WHERE atom = (?)', (pkgatom,)) 3147 result = self.cursor.fetchone() 3148 if result: return result[0] 3149 return -1
3150
3151 - def isIDPackageAvailable(self, idpackage):
3152 self.cursor.execute('SELECT idpackage FROM baseinfo WHERE idpackage = (?)', (idpackage,)) 3153 result = self.cursor.fetchone() 3154 if not result: 3155 return False 3156 return True
3157
3158 - def areIDPackagesAvailable(self, idpackages):
3159 sql = 'SELECT count(idpackage) FROM baseinfo WHERE idpackage IN (%s)' % (','.join([str(x) for x in set(idpackages)]),) 3160 self.cursor.execute(sql) 3161 count = self.cursor.fetchone()[0] 3162 if count != len(idpackages): 3163 return False 3164 return True
3165
3166 - def isCategoryAvailable(self, category):
3167 self.cursor.execute('SELECT idcategory FROM categories WHERE category = (?)', (category,)) 3168 result = self.cursor.fetchone() 3169 if result: return result[0] 3170 return -1
3171
3172 - def isProtectAvailable(self, protect):
3173 self.cursor.execute('SELECT idprotect FROM configprotectreference WHERE protect = (?)', (protect,)) 3174 result = self.cursor.fetchone() 3175 if result: return result[0] 3176 return -1
3177
3178 - def isFileAvailable(self, myfile, get_id = False):
3179 self.cursor.execute('SELECT idpackage FROM content WHERE file = (?)', (myfile,)) 3180 result = self.cursor.fetchall() 3181 if get_id: 3182 return self.fetchall2set(result) 3183 elif result: 3184 return True 3185 return False
3186
3187 - def resolveNeeded(self, needed, elfclass = -1):
3188 3189 args = [needed] 3190 elfclass_txt = '' 3191 if elfclass != -1: 3192 elfclass_txt = ' AND elfclass = (?)' 3193 args.append(elfclass) 3194 3195 self.cursor.execute(""" 3196 SELECT idpackage FROM neededlibraryidpackages 3197 WHERE library = (?) 3198 """ + elfclass_txt, args) 3199 3200 return self.fetchall2set(self.cursor.fetchall())
3201
3202 - def isSourceAvailable(self, source):
3203 self.cursor.execute('SELECT idsource FROM sourcesreference WHERE source = (?)', (source,)) 3204 result = self.cursor.fetchone() 3205 if result: return result[0] 3206 return -1
3207
3208 - def isDependencyAvailable(self, dependency):
3209 self.cursor.execute('SELECT iddependency FROM dependenciesreference WHERE dependency = (?)', (dependency,)) 3210 result = self.cursor.fetchone() 3211 if result: return result[0] 3212 return -1
3213
3214 - def isKeywordAvailable(self, keyword):
3215 self.cursor.execute('SELECT idkeyword FROM keywordsreference WHERE keywordname = (?)', (keyword,)) 3216 result = self.cursor.fetchone() 3217 if result: return result[0] 3218 return -1
3219
3220 - def isUseflagAvailable(self, useflag):
3221 self.cursor.execute('SELECT idflag FROM useflagsreference WHERE flagname = (?)', (useflag,)) 3222 result = self.cursor.fetchone() 3223 if result: return result[0] 3224 return -1
3225
3226 - def isEclassAvailable(self, eclass):
3227 self.cursor.execute('SELECT idclass FROM eclassesreference WHERE classname = (?)', (eclass,)) 3228 result = self.cursor.fetchone() 3229 if result: return result[0] 3230 return -1
3231
3232 - def isNeededAvailable(self, needed):
3233 self.cursor.execute('SELECT idneeded FROM neededreference WHERE library = (?)', (needed,)) 3234 result = self.cursor.fetchone() 3235 if result: return result[0] 3236 return -1
3237
3238 - def isCounterAvailable(self, counter, branch = None, branch_operator = "="):
3239 params = [counter] 3240 branch_string = '' 3241 if branch: 3242 branch_string = ' and branch '+branch_operator+' (?)' 3243 params = [counter, branch] 3244 3245 self.cursor.execute('SELECT counter FROM counters WHERE counter = (?)'+branch_string, params) 3246 result = self.cursor.fetchone() 3247 if result: return True 3248 return False
3249
3250 - def isCounterTrashed(self, counter):
3251 self.cursor.execute('SELECT counter FROM trashedcounters WHERE counter = (?)', (counter,)) 3252 result = self.cursor.fetchone() 3253 if result: return True 3254 return False
3255
3256 - def isLicensedataKeyAvailable(self, license_name):
3257 self.cursor.execute('SELECT licensename FROM licensedata WHERE licensename = (?)', (license_name,)) 3258 result = self.cursor.fetchone() 3259 if not result: 3260 return False 3261 return True
3262
3263 - def isLicenseAccepted(self, license_name):
3264 self.cursor.execute('SELECT licensename FROM licenses_accepted WHERE licensename = (?)', (license_name,)) 3265 result = self.cursor.fetchone() 3266 if not result: 3267 return False 3268 return True
3269
3270 - def acceptLicense(self, license_name):
3271 if self.readOnly or (not self.entropyTools.is_user_in_entropy_group()): 3272 return 3273 if self.isLicenseAccepted(license_name): 3274 return 3275 with self.__write_mutex: 3276 self.cursor.execute('INSERT INTO licenses_accepted VALUES (?)', (license_name,)) 3277 self.commitChanges()
3278
3279 - def isLicenseAvailable(self, pkglicense):
3280 if not self.entropyTools.is_valid_string(pkglicense): 3281 pkglicense = ' ' 3282 self.cursor.execute('SELECT idlicense FROM licenses WHERE license = (?)', (pkglicense,)) 3283 result = self.cursor.fetchone() 3284 if result: return result[0] 3285 return -1
3286
3287 - def isSystemPackage(self, idpackage):
3288 self.cursor.execute('SELECT idpackage FROM systempackages WHERE idpackage = (?)', (idpackage,)) 3289 result = self.cursor.fetchone() 3290 if result: 3291 return True 3292 return False
3293
3294 - def isInjected(self, idpackage):
3295 self.cursor.execute('SELECT idpackage FROM injected WHERE idpackage = (?)', (idpackage,)) 3296 result = self.cursor.fetchone() 3297 if result: 3298 return True 3299 return False
3300
3301 - def areCompileFlagsAvailable(self, chost, cflags, cxxflags):
3302 3303 self.cursor.execute('SELECT idflags FROM flags WHERE chost = (?) AND cflags = (?) AND cxxflags = (?)', 3304 (chost, cflags, cxxflags,) 3305 ) 3306 result = self.cursor.fetchone() 3307 if result: return result[0] 3308 return -1
3309
3310 - def searchBelongs(self, file, like = False, branch = None, branch_operator = "="):
3311 3312 branchstring = '' 3313 searchkeywords = [file] 3314 if branch: 3315 searchkeywords.append(branch) 3316 branchstring = ' and baseinfo.branch '+branch_operator+' (?)' 3317 3318 if like: 3319 self.cursor.execute(""" 3320 SELECT content.idpackage FROM content,baseinfo 3321 WHERE file LIKE (?) AND 3322 content.idpackage = baseinfo.idpackage %s""" % (branchstring,), searchkeywords) 3323 else: 3324 self.cursor.execute("""SELECT content.idpackage FROM content,baseinfo 3325 WHERE file = (?) AND 3326 content.idpackage = baseinfo.idpackage %s""" % (branchstring,), searchkeywords) 3327 3328 return self.fetchall2set(self.cursor.fetchall())
3329 3330 ''' search packages that uses the eclass provided '''
3331 - def searchEclassedPackages(self, eclass, atoms = False): # atoms = return atoms directly
3332 if atoms: 3333 self.cursor.execute(""" 3334 SELECT baseinfo.atom,eclasses.idpackage FROM baseinfo,eclasses,eclassesreference 3335 WHERE eclassesreference.classname = (?) AND 3336 eclassesreference.idclass = eclasses.idclass AND 3337 eclasses.idpackage = baseinfo.idpackage""", (eclass,)) 3338 return self.cursor.fetchall() 3339 else: 3340 self.cursor.execute('SELECT idpackage FROM baseinfo WHERE versiontag = (?)', (eclass,)) 3341 return self.fetchall2set(self.cursor.fetchall()) 3342 3343 ''' search packages whose versiontag matches the one provided '''
3344 - def searchTaggedPackages(self, tag, atoms = False): # atoms = return atoms directly
3345 if atoms: 3346 self.cursor.execute('SELECT atom,idpackage FROM baseinfo WHERE versiontag = (?)', (tag,)) 3347 return self.cursor.fetchall() 3348 else: 3349 self.cursor.execute('SELECT idpackage FROM baseinfo WHERE versiontag = (?)', (tag,)) 3350 return self.fetchall2set(self.cursor.fetchall()) 3351
3352 - def searchLicenses(self, mylicense, caseSensitive = False, atoms = False):
3353 3354 if not self.entropyTools.is_valid_string(mylicense): 3355 return [] 3356 3357 request = "baseinfo.idpackage" 3358 if atoms: 3359 request = "baseinfo.atom,baseinfo.idpackage" 3360 3361 if caseSensitive: 3362 self.cursor.execute(""" 3363 SELECT %s FROM baseinfo,licenses 3364 WHERE licenses.license LIKE (?) AND 3365 licenses.idlicense = baseinfo.idlicense""" % (request,), ("%"+mylicense+"%",)) 3366 else: 3367 self.cursor.execute(""" 3368 SELECT %s FROM baseinfo,licenses 3369 WHERE LOWER(licenses.license) LIKE (?) AND 3370 licenses.idlicense = baseinfo.idlicense""" % (request,), ("%"+mylicense+"%".lower(),)) 3371 if atoms: 3372 return self.cursor.fetchall() 3373 return self.fetchall2set(self.cursor.fetchall())
3374 3375 ''' search packages whose slot matches the one provided '''
3376 - def searchSlottedPackages(self, slot, atoms = False): # atoms = return atoms directly
3377 if atoms: 3378 self.cursor.execute('SELECT atom,idpackage FROM baseinfo WHERE slot = (?)', (slot,)) 3379 return self.cursor.fetchall() 3380 else: 3381 self.cursor.execute('SELECT idpackage FROM baseinfo WHERE slot = (?)', (slot,)) 3382 return self.fetchall2set(self.cursor.fetchall()) 3383
3384 - def searchKeySlot(self, key, slot, branch = None):
3385 3386 branchstring = '' 3387 cat, name = key.split("/") 3388 params = [cat, name, slot] 3389 if branch: 3390 params.append(branch) 3391 branchstring = 'and baseinfo.branch = (?)' 3392 3393 self.cursor.execute(""" 3394 SELECT idpackage FROM baseinfo,categories 3395 WHERE baseinfo.idcategory = categories.idcategory AND 3396 categories.category = (?) AND 3397 baseinfo.name = (?) AND 3398 baseinfo.slot = (?) %s""" % (branchstring,), params) 3399 return self.cursor.fetchall()
3400 3401 ''' search packages that need the specified library (in neededreference table) specified by keyword '''
3402 - def searchNeeded(self, keyword, like = False):
3403 if like: 3404 self.cursor.execute(""" 3405 SELECT needed.idpackage FROM needed,neededreference 3406 WHERE library LIKE (?) AND 3407 needed.idneeded = neededreference.idneeded""", (keyword,)) 3408 else: 3409 self.cursor.execute(""" 3410 SELECT needed.idpackage FROM needed,neededreference 3411 WHERE library = (?) AND 3412 needed.idneeded = neededreference.idneeded""", (keyword,)) 3413 return self.fetchall2set(self.cursor.fetchall())
3414 3415 ''' search dependency string inside dependenciesreference table and retrieve iddependency '''
3416 - def searchDependency(self, dep, like = False, multi = False, strings = False):
3417 sign = "=" 3418 if like: 3419 sign = "LIKE" 3420 dep = "%"+dep+"%" 3421 item = 'iddependency' 3422 if strings: 3423 item = 'dependency' 3424 self.cursor.execute('SELECT %s FROM dependenciesreference WHERE dependency %s (?)' % (item, sign,), (dep,)) 3425 if multi: 3426 return self.fetchall2set(self.cursor.fetchall()) 3427 else: 3428 iddep = self.cursor.fetchone() 3429 if iddep: 3430 iddep = iddep[0] 3431 else: 3432 iddep = -1 3433 return iddep
3434 3435 ''' search iddependency inside dependencies table and retrieve idpackages '''
3436 - def searchIdpackageFromIddependency(self, iddep):
3437 self.cursor.execute('SELECT idpackage FROM dependencies WHERE iddependency = (?)', (iddep,)) 3438 return self.fetchall2set(self.cursor.fetchall())
3439
3440 - def searchSets(self, keyword):
3441 self.cursor.execute('SELECT DISTINCT(setname) FROM packagesets WHERE setname LIKE (?)', ("%"+keyword+"%",)) 3442 return self.fetchall2set(self.cursor.fetchall())
3443
3444 - def searchSimilarPackages(self, mystring, atom = False):
3445 s_item = 'name' 3446 if atom: s_item = 'atom' 3447 self.cursor.execute(""" 3448 SELECT idpackage FROM baseinfo 3449 WHERE soundex(%s) = soundex((?)) ORDER BY %s""" % (s_item, s_item,), (mystring,)) 3450 return self.fetchall2list(self.cursor.fetchall())
3451
3452 - def searchPackages(self, keyword, sensitive = False, slot = None, tag = None, branch = None, order_by = 'atom', just_id = False):
3453 3454 searchkeywords = ["%"+keyword+"%"] 3455 slotstring = '' 3456 if slot: 3457 searchkeywords.append(slot) 3458 slotstring = ' and slot = (?)' 3459 tagstring = '' 3460 if tag: 3461 searchkeywords.append(tag) 3462 tagstring = ' and versiontag = (?)' 3463 branchstring = '' 3464 if branch: 3465 searchkeywords.append(branch) 3466 branchstring = ' and branch = (?)' 3467 order_by_string = '' 3468 if order_by in ("atom", "idpackage", "branch",): 3469 order_by_string = ' order by %s' % (order_by,) 3470 3471 search_elements = 'atom,idpackage,branch' 3472 if just_id: search_elements = 'idpackage' 3473 3474 if sensitive: 3475 self.cursor.execute(""" 3476 SELECT %s FROM baseinfo WHERE atom LIKE (?) %s %s %s %s""" % ( 3477 search_elements,slotstring,tagstring,branchstring,order_by_string,), 3478 searchkeywords 3479 ) 3480 else: 3481 self.cursor.execute(""" 3482 SELECT %s FROM baseinfo WHERE 3483 LOWER(atom) LIKE (?) %s %s %s %s""" % ( 3484 search_elements,slotstring,tagstring,branchstring,order_by_string,), 3485 searchkeywords 3486 ) 3487 if just_id: 3488 return self.fetchall2list(self.cursor.fetchall()) 3489 return self.cursor.fetchall()
3490
3491 - def searchProvide(self, keyword, slot = None, tag = None, branch = None, justid = False):
3492 3493 slotstring = '' 3494 searchkeywords = [keyword] 3495 if slot: 3496 searchkeywords.append(slot) 3497 slotstring = ' and baseinfo.slot = (?)' 3498 tagstring = '' 3499 if tag: 3500 searchkeywords.append(tag) 3501 tagstring = ' and baseinfo.versiontag = (?)' 3502 branchstring = '' 3503 if branch: 3504 searchkeywords.append(branch) 3505 branchstring = ' and baseinfo.branch = (?)' 3506 atomstring = '' 3507 if not justid: 3508 atomstring = 'baseinfo.atom,' 3509 3510 self.cursor.execute(""" 3511 SELECT %s baseinfo.idpackage FROM baseinfo,provide 3512 WHERE provide.atom = (?) AND 3513 provide.idpackage = baseinfo.idpackage %s %s %s""" % ( 3514 atomstring,slotstring,tagstring,branchstring,), 3515 searchkeywords 3516 ) 3517 3518 if justid: 3519 results = self.fetchall2list(self.cursor.fetchall()) 3520 else: 3521 results = self.cursor.fetchall() 3522 return results
3523
3524 - def searchPackagesByDescription(self, keyword):
3525 self.cursor.execute(""" 3526 SELECT baseinfo.atom,baseinfo.idpackage FROM extrainfo,baseinfo 3527 WHERE LOWER(extrainfo.description) LIKE (?) AND 3528 baseinfo.idpackage = extrainfo.idpackage""", ("%"+keyword.lower()+"%",)) 3529 return self.cursor.fetchall()
3530
3531 - def searchPackagesByName(self, keyword, sensitive = False, branch = None, justid = False):
3532 3533 if sensitive: 3534 searchkeywords = [keyword] 3535 else: 3536 searchkeywords = [keyword.lower()] 3537 branchstring = '' 3538 atomstring = '' 3539 if not justid: 3540 atomstring = 'atom,' 3541 if branch: 3542 searchkeywords.append(branch) 3543 branchstring = ' and branch = (?)' 3544 3545 if sensitive: 3546 self.cursor.execute(""" 3547 SELECT %s idpackage FROM baseinfo 3548 WHERE name = (?) %s""" % (atomstring, branchstring,), searchkeywords) 3549 else: 3550 self.cursor.execute(""" 3551 SELECT %s idpackage FROM baseinfo 3552 WHERE LOWER(name) = (?) %s""" % (atomstring, branchstring,), searchkeywords) 3553 3554 if justid: 3555 results = self.fetchall2list(self.cursor.fetchall()) 3556 else: 3557 results = self.cursor.fetchall() 3558 return results
3559 3560
3561 - def searchPackagesByCategory(self, keyword, like = False, branch = None):
3562 3563 searchkeywords = [keyword] 3564 branchstring = '' 3565 if branch: 3566 searchkeywords.append(branch) 3567 branchstring = 'and branch = (?)' 3568 3569 if like: 3570 self.cursor.execute(""" 3571 SELECT baseinfo.atom,baseinfo.idpackage FROM baseinfo,categories 3572 WHERE categories.category LIKE (?) AND 3573 baseinfo.idcategory = categories.idcategory %s""" % (branchstring,), searchkeywords) 3574 else: 3575 self.cursor.execute(""" 3576 SELECT baseinfo.atom,baseinfo.idpackage FROM baseinfo,categories 3577 WHERE categories.category = (?) AND 3578 baseinfo.idcategory = categories.idcategory %s""" % (branchstring,), searchkeywords) 3579 3580 return self.cursor.fetchall()
3581
3582 - def searchPackagesByNameAndCategory(self, name, category, sensitive = False, branch = None, justid = False):
3583 3584 myname = name 3585 mycat = category 3586 if not sensitive: 3587 myname = name.lower() 3588 mycat = category.lower() 3589 3590 searchkeywords = [myname, mycat] 3591 branchstring = '' 3592 if branch: 3593 searchkeywords.append(branch) 3594 branchstring = ' and branch = (?)' 3595 atomstring = '' 3596 if not justid: 3597 atomstring = 'atom,' 3598 3599 if sensitive: 3600 self.cursor.execute(""" 3601 SELECT %s idpackage FROM baseinfo 3602 WHERE name = (?) AND 3603 idcategory IN ( 3604 SELECT idcategory FROM categories 3605 WHERE category = (?) 3606 ) %s""" % (atomstring, branchstring,), searchkeywords) 3607 else: 3608 self.cursor.execute(""" 3609 SELECT %s idpackage FROM baseinfo 3610 WHERE LOWER(name) = (?) AND 3611 idcategory IN ( 3612 SELECT idcategory FROM categories 3613 WHERE LOWER(category) = (?) 3614 ) %s""" % (atomstring, branchstring,), searchkeywords) 3615 3616 if justid: 3617 results = self.fetchall2list(self.cursor.fetchall()) 3618 else: 3619 results = self.cursor.fetchall() 3620 return results
3621
3622 - def isPackageScopeAvailable(self, atom, slot, revision):
3623 searchdata = (atom, slot, revision,) 3624 self.cursor.execute('SELECT idpackage FROM baseinfo where atom = (?) and slot = (?) and revision = (?)', searchdata) 3625 rslt = self.cursor.fetchone() 3626 idreason = 0 3627 idpackage = -1 3628 if rslt: 3629 # check if it's masked 3630 idpackage, idreason = self.idpackageValidator(rslt[0]) 3631 return idpackage, idreason
3632
3633 - def listAllPackages(self, get_scope = False, order_by = None, branch = None, branch_operator = "="):
3634 3635 branchstring = '' 3636 searchkeywords = [] 3637 if branch: 3638 searchkeywords = [branch] 3639 branchstring = ' where branch %s (?)' % (branch_operator,) 3640 3641 order_txt = '' 3642 if order_by: 3643 order_txt = ' order by %s' % (order_by,) 3644 if get_scope: 3645 self.cursor.execute('SELECT idpackage,atom,slot,revision FROM baseinfo'+order_txt+branchstring, searchkeywords) 3646 else: 3647 self.cursor.execute('SELECT atom,idpackage,branch FROM baseinfo'+order_txt+branchstring, searchkeywords) 3648 return self.cursor.fetchall()
3649
3650 - def listAllInjectedPackages(self, justFiles = False):
3651 self.cursor.execute('SELECT idpackage FROM injected') 3652 injecteds = self.fetchall2set(self.cursor.fetchall()) 3653 results = set() 3654 # get download 3655 for injected in injecteds: 3656 download = self.retrieveDownloadURL(injected) 3657 if justFiles: 3658 results.add(download) 3659 else: 3660 results.add((download, injected)) 3661 return results
3662
3663 - def listAllCounters(self, onlycounters = False, branch = None, branch_operator = "="):
3664 3665 branchstring = '' 3666 if branch: 3667 branchstring = ' WHERE branch '+branch_operator+' "'+str(branch)+'"' 3668 if onlycounters: 3669 self.cursor.execute('SELECT counter FROM counters'+branchstring) 3670 return self.fetchall2set(self.cursor.fetchall()) 3671 else: 3672 self.cursor.execute('SELECT counter,idpackage FROM counters'+branchstring) 3673 return self.cursor.fetchall()
3674
3675 - def listAllIdpackages(self, branch = None, branch_operator = "=", order_by = None):
3676 3677 branchstring = '' 3678 orderbystring = '' 3679 searchkeywords = [] 3680 if branch: 3681 searchkeywords.append(branch) 3682 branchstring = ' where branch %s (?)' % (str(branch_operator),) 3683 if order_by: 3684 orderbystring = ' order by '+order_by 3685 3686 self.cursor.execute('SELECT idpackage FROM baseinfo'+branchstring+orderbystring, searchkeywords) 3687 3688 try: 3689 if order_by: 3690 results = self.fetchall2list(self.cursor.fetchall()) 3691 else: 3692 results = self.fetchall2set(self.cursor.fetchall()) 3693 return results 3694 except self.dbapi2.OperationalError: 3695 if order_by: 3696 return [] 3697 return set()
3698
3699 - def listAllDependencies(self, only_deps = False):
3700 if only_deps: 3701 self.cursor.execute('SELECT dependency FROM dependenciesreference') 3702 return self.fetchall2set(self.cursor.fetchall()) 3703 else: 3704 self.cursor.execute('SELECT * FROM dependenciesreference') 3705 return self.cursor.fetchall()
3706
3707 - def listAllBranches(self):
3708 3709 cache = self.live_cache.get('listAllBranches') 3710 if cache != None: 3711 return cache 3712 3713 self.cursor.execute('SELECT distinct branch FROM baseinfo') 3714 results = self.fetchall2set(self.cursor.fetchall()) 3715 3716 self.live_cache['listAllBranches'] = results.copy() 3717 return results
3718
3719 - def listIdPackagesInIdcategory(self, idcategory, order_by = 'atom'):
3720 order_by_string = '' 3721 if order_by in ("atom", "name", "version",): 3722 order_by_string = ' ORDER BY %s' % (order_by,) 3723 self.cursor.execute('SELECT idpackage FROM baseinfo where idcategory = (?)'+order_by_string, (idcategory,)) 3724 return self.fetchall2set(self.cursor.fetchall())
3725
3726 - def listIdpackageDependencies(self, idpackage):
3727 self.cursor.execute(""" 3728 SELECT dependenciesreference.iddependency,dependenciesreference.dependency FROM dependenciesreference,dependencies 3729 WHERE dependencies.idpackage = (?) AND 3730 dependenciesreference.iddependency = dependencies.iddependency""", (idpackage,)) 3731 return set(self.cursor.fetchall())
3732
3733 - def listBranchPackagesTbz2(self, branch, do_sort = True, full_path = False):
3734 order_string = '' 3735 if do_sort: order_string = 'ORDER BY extrainfo.download' 3736 self.cursor.execute(""" 3737 SELECT extrainfo.download FROM baseinfo,extrainfo 3738 WHERE baseinfo.branch = (?) AND 3739 baseinfo.idpackage = extrainfo.idpackage %s""" % (order_string,), (branch,)) 3740 3741 if do_sort: results = self.fetchall2list(self.cursor.fetchall()) 3742 else: results = self.fetchall2set(self.cursor.fetchall()) 3743 3744 if not full_path: results = [os.path.basename(x) for x in results] 3745 if do_sort: return results 3746 return set(results)
3747
3748 - def listAllFiles(self, clean = False, count = False):
3749 self.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 3750 if count: 3751 self.cursor.execute('SELECT count(file) FROM content') 3752 else: 3753 self.cursor.execute('SELECT file FROM content') 3754 if count: 3755 return self.cursor.fetchone()[0] 3756 else: 3757 if clean: 3758 return self.fetchall2set(self.cursor.fetchall()) 3759 else: 3760 return self.fetchall2list(self.cursor.fetchall())
3761
3762 - def listAllCategories(self, order_by = ''):
3763 order_by_string = '' 3764 if order_by: order_by_string = ' order by %s' % (order_by,) 3765 self.cursor.execute('SELECT idcategory,category FROM categories %s' % ( 3766 order_by_string,)) 3767 return self.cursor.fetchall()
3768
3769 - def listConfigProtectDirectories(self, mask = False):
3770 mask_t = '' 3771 if mask: mask_t = 'mask' 3772 self.cursor.execute(""" 3773 SELECT DISTINCT(protect) FROM configprotectreference 3774 WHERE idprotect >= 1 AND 3775 idprotect <= (SELECT max(idprotect) FROM configprotect%s) 3776 ORDER BY protect""" % (mask_t,)) 3777 results = self.fetchall2set(self.cursor.fetchall()) 3778 dirs = set() 3779 for mystr in results: 3780 dirs |= set(map(unicode, mystr.split())) 3781 return sorted(list(dirs))
3782
3783 - def switchBranch(self, idpackage, tobranch):
3784 3785 key, slot = self.retrieveKeySlot(idpackage) 3786 3787 # if there are entries already, remove idpackage directly 3788 my_idpackage, result = self.atomMatch(key, matchSlot = slot, 3789 matchBranches = (tobranch,)) 3790 if my_idpackage != -1: return False 3791 3792 # otherwise, update the old one (set the new branch) 3793 with self.__write_mutex: 3794 self.cursor.execute(""" 3795 UPDATE baseinfo SET branch = (?) 3796 WHERE idpackage = (?)""", (tobranch, idpackage,)) 3797 self.commitChanges() 3798 self.clearCache() 3799 return True
3800
3801 - def databaseStructureUpdates(self):
3802 3803 old_readonly = self.readOnly 3804 self.readOnly = False 3805 3806 if not self.doesTableExist("licenses_accepted"): 3807 self.createLicensesAcceptedTable() 3808 3809 if not self.doesTableExist("installedtable"): 3810 self.createInstalledTable() 3811 3812 if not self.doesColumnInTableExist("installedtable", "source"): 3813 self.createInstalledTableSource() 3814 3815 if not self.doesTableExist('packagesets'): 3816 self.createPackagesetsTable() 3817 3818 if not self.doesTableExist('packagechangelogs'): 3819 self.createPackagechangelogsTable() 3820 3821 if not self.doesTableExist('automergefiles'): 3822 self.createAutomergefilesTable() 3823 3824 if not self.doesTableExist('packagesignatures'): 3825 self.createPackagesignaturesTable() 3826 3827 if not self.doesTableExist('packagespmphases'): 3828 self.createPackagespmphases() 3829 3830 if not self.doesTableExist('neededlibrarypaths'): 3831 self.createNeededlibrarypathsTable() 3832 3833 if not self.doesTableExist('neededlibraryidpackages'): 3834 self.createNeededlibraryidpackagesTable() 3835 elif not self.doesColumnInTableExist("neededlibraryidpackages", "elfclass"): 3836 self.createNeededlibraryidpackagesTable() 3837 3838 if not self.doesTableExist('dependstable'): 3839 self.createDependsTable() 3840 3841 self.readOnly = old_readonly 3842 self.connection.commit()
3843
3844 - def validateDatabase(self):
3845 self.cursor.execute('select name from SQLITE_MASTER where type = (?) and name = (?)', ("table", "baseinfo")) 3846 rslt = self.cursor.fetchone() 3847 if rslt == None: 3848 mytxt = _("baseinfo table not found. Either does not exist or corrupted.") 3849 raise SystemDatabaseError("SystemDatabaseError: %s" % (mytxt,)) 3850 self.cursor.execute('select name from SQLITE_MASTER where type = (?) and name = (?)', ("table", "extrainfo")) 3851 rslt = self.cursor.fetchone() 3852 if rslt == None: 3853 mytxt = _("extrainfo table not found. Either does not exist or corrupted.") 3854 raise SystemDatabaseError("SystemDatabaseError: %s" % (mytxt,))
3855
3856 - def getIdpackagesDifferences(self, foreign_idpackages):
3857 myids = self.listAllIdpackages() 3858 if isinstance(foreign_idpackages, (list, tuple,)): 3859 outids = set(foreign_idpackages) 3860 else: 3861 outids = foreign_idpackages 3862 added_ids = outids - myids 3863 removed_ids = myids - outids 3864 return added_ids, removed_ids
3865
3866 - def uniformBranch(self, branch):
3867 with self.__write_mutex: 3868 self.cursor.execute('UPDATE baseinfo SET branch = (?)', (branch,)) 3869 self.commitChanges() 3870 self.clearCache()
3871
3872 - def alignDatabases(self, dbconn, force = False, output_header = " ", align_limit = 300):
3873 3874 added_ids, removed_ids = self.getIdpackagesDifferences(dbconn.listAllIdpackages()) 3875 3876 if not force: 3877 if len(added_ids) > align_limit: # too much hassle 3878 return 0 3879 if len(removed_ids) > align_limit: # too much hassle 3880 return 0 3881 3882 if not added_ids and not removed_ids: 3883 return -1 3884 3885 mytxt = red("%s, %s ...") % (_("Syncing current database"), _("please wait"),) 3886 self.updateProgress( 3887 mytxt, 3888 importance = 1, 3889 type = "info", 3890 header = output_header, 3891 back = True 3892 ) 3893 maxcount = len(removed_ids) 3894 mycount = 0 3895 for idpackage in removed_ids: 3896 mycount += 1 3897 mytxt = "%s: %s" % (red(_("Removing entry")), blue(str(self.retrieveAtom(idpackage))),) 3898 self.updateProgress( 3899 mytxt, 3900 importance = 0, 3901 type = "info", 3902 header = output_header, 3903 back = True, 3904 count = (mycount, maxcount) 3905 ) 3906 self.removePackage(idpackage, do_cleanup = False, do_commit = False) 3907 3908 maxcount = len(added_ids) 3909 mycount = 0 3910 for idpackage in added_ids: 3911 mycount += 1 3912 mytxt = "%s: %s" % (red(_("Adding entry")), blue(str(dbconn.retrieveAtom(idpackage))),) 3913 self.updateProgress( 3914 mytxt, 3915 importance = 0, 3916 type = "info", 3917 header = output_header, 3918 back = True, 3919 count = (mycount, maxcount) 3920 ) 3921 mydata = dbconn.getPackageData(idpackage, get_content = True, content_insert_formatted = True) 3922 self.addPackage( 3923 mydata, 3924 revision = mydata['revision'], 3925 idpackage = idpackage, 3926 do_remove = False, 3927 do_commit = False, 3928 formatted_content = True 3929 ) 3930 3931 # do some cleanups 3932 self.doCleanups() 3933 # clear caches 3934 self.clearCache() 3935 self.commitChanges() 3936 self.regenerateDependsTable(output = False) 3937 dbconn.clearCache() 3938 3939 # verify both checksums, if they don't match, bomb out 3940 mycheck = self.database_checksum(do_order = True, strict = False) 3941 outcheck = dbconn.database_checksum(do_order = True, strict = False) 3942 if mycheck == outcheck: 3943 return 1 3944 return 0
3945
3946 - def checkDatabaseApi(self):
3947 3948 dbapi = self.getApi() 3949 if int(dbapi) > int(etpConst['etpapi']): 3950 self.updateProgress( 3951 red(_("Repository EAPI > Entropy EAPI. Please update Equo/Entropy as soon as possible !")), 3952 importance = 1, 3953 type = "warning", 3954 header = " * ! * ! * ! * " 3955 )
3956
3957 - def doDatabaseImport(self, dumpfile, dbfile):
3958 sqlite3_exec = "/usr/bin/sqlite3 %s < %s" % (dbfile, dumpfile,) 3959 retcode = subprocess.call(sqlite3_exec, shell = True) 3960 return retcode
3961
3962 - def doDatabaseExport(self, dumpfile, gentle_with_tables = True, 3963 exclude_tables = None):
3964 3965 if not exclude_tables: 3966 exclude_tables = [] 3967 3968 dumpfile.write("BEGIN TRANSACTION;\n") 3969 self.cursor.execute("SELECT name, type, sql FROM sqlite_master WHERE sql NOT NULL AND type=='table'") 3970 for name, x, sql in self.cursor.fetchall(): 3971 3972 self.updateProgress( 3973 red("%s " % (_("Exporting database table"),) )+"["+blue(str(name))+"]", 3974 importance = 0, 3975 type = "info", 3976 back = True, 3977 header = " " 3978 ) 3979 3980 if name == "sqlite_sequence": 3981 dumpfile.write("DELETE FROM sqlite_sequence;\n") 3982 elif name == "sqlite_stat1": 3983 dumpfile.write("ANALYZE sqlite_master;\n") 3984 elif name.startswith("sqlite_"): 3985 continue 3986 else: 3987 t_cmd = "CREATE TABLE" 3988 if sql.startswith(t_cmd) and gentle_with_tables: 3989 sql = "CREATE TABLE IF NOT EXISTS"+sql[len(t_cmd):] 3990 dumpfile.write("%s;\n" % sql) 3991 3992 if name in exclude_tables: 3993 continue 3994 3995 self.cursor.execute("PRAGMA table_info('%s')" % name) 3996 cols = [str(r[1]) for r in self.cursor.fetchall()] 3997 q = "SELECT 'INSERT INTO \"%(tbl_name)s\" VALUES(" 3998 q += ", ".join(["'||quote(" + x + ")||'" for x in cols]) 3999 q += ")' FROM '%(tbl_name)s'" 4000 self.cursor.execute(q % {'tbl_name': name}) 4001 self.connection.text_factory = lambda x: unicode(x, "raw_unicode_escape") 4002 for row in self.cursor: 4003 dumpfile.write("%s;\n" % str(row[0].encode('raw_unicode_escape'))) 4004 4005 self.cursor.execute("SELECT name, type, sql FROM sqlite_master WHERE sql NOT NULL AND type!='table' AND type!='meta'") 4006 for name, x, sql in self.cursor.fetchall(): 4007 dumpfile.write("%s;\n" % sql) 4008 4009 dumpfile.write("COMMIT;\n") 4010 try: 4011 dumpfile.flush() 4012 except: 4013 pass 4014 self.updateProgress( 4015 red(_("Database Export completed.")), 4016 importance = 0, 4017 type = "info", 4018 header = " " 4019 )
4020 # remember to close the file 4021
4022 - def listAllTables(self):
4023 self.cursor.execute(""" 4024 SELECT name FROM SQLITE_MASTER WHERE type = "table" 4025 """) 4026 return self.fetchall2list(self.cursor.fetchall())
4027
4028 - def doesTableExist(self, table):
4029 self.cursor.execute('select name from SQLITE_MASTER where type = "table" and name = (?)', (table,)) 4030 rslt = self.cursor.fetchone() 4031 if rslt == None: 4032 return False 4033 return True
4034
4035 - def doesColumnInTableExist(self, table, column):
4036 self.cursor.execute('PRAGMA table_info( %s )' % (table,)) 4037 rslt = (x[1] for x in self.cursor.fetchall()) 4038 if column in rslt: 4039 return True 4040 return False
4041
4042 - def database_checksum(self, do_order = False, strict = True, strings = False):
4043 4044 c_tup = ("database_checksum", do_order, strict, strings,) 4045 cache = self.live_cache.get(c_tup) 4046 if cache != None: return cache 4047 4048 idpackage_order = '' 4049 category_order = '' 4050 license_order = '' 4051 flags_order = '' 4052 if do_order: 4053 idpackage_order = 'order by idpackage' 4054 category_order = 'order by category' 4055 license_order = 'order by license' 4056 flags_order = 'order by chost' 4057 4058 def do_update_md5(m, cursor): 4059 mydata = cursor.fetchall() 4060 for record in mydata: 4061 for item in record: 4062 m.update(str(item))
4063 4064 if strings: 4065 import hashlib 4066 m = hashlib.md5() 4067 4068 self.cursor.execute(""" 4069 SELECT idpackage,atom,name,version,versiontag, 4070 revision,branch,slot,etpapi,trigger FROM 4071 baseinfo %s""" % (idpackage_order,)) 4072 if strings: 4073 do_update_md5(m, self.cursor) 4074 else: 4075 a_hash = hash(tuple(self.cursor.fetchall())) 4076 self.cursor.execute(""" 4077 SELECT idpackage,description,homepage, 4078 download,size,digest,datecreation FROM 4079 extrainfo %s""" % (idpackage_order,)) 4080 if strings: 4081 do_update_md5(m, self.cursor) 4082 else: 4083 b_hash = hash(tuple(self.cursor.fetchall())) 4084 self.cursor.execute('select category from categories %s' % (category_order,)) 4085 if strings: 4086 do_update_md5(m, self.cursor) 4087 else: 4088 c_hash = hash(tuple(self.cursor.fetchall())) 4089 d_hash = '0' 4090 e_hash = '0' 4091 if strict: 4092 self.cursor.execute('select * from licenses %s' % (license_order,)) 4093 if strings: 4094 do_update_md5(m, self.cursor) 4095 else: 4096 d_hash = hash(tuple(self.cursor.fetchall())) 4097 self.cursor.execute('select * from flags %s' % (flags_order,)) 4098 if strings: 4099 do_update_md5(m, self.cursor) 4100 else: 4101 e_hash = hash(tuple(self.cursor.fetchall())) 4102 4103 if strings: 4104 result = m.hexdigest() 4105 else: 4106 result = "%s:%s:%s:%s:%s" % (a_hash, b_hash, c_hash, d_hash, e_hash,) 4107 4108 self.live_cache[c_tup] = result[:] 4109 return result 4110 4111 4112 ######################################################## 4113 #### 4114 ## Client Database API / but also used by server part 4115 # 4116
4117 - def updateInstalledTableSource(self, idpackage, source):
4118 with self.__write_mutex: 4119 self.cursor.execute(""" 4120 UPDATE installedtable SET source = (?) WHERE idpackage = (?) 4121 """, (source, idpackage,))
4122
4123 - def addPackageToInstalledTable(self, idpackage, repoid, source = 0):
4124 with self.__write_mutex: 4125 self.cursor.execute('INSERT into installedtable VALUES (?,?,?)', 4126 (idpackage, repoid, source,))
4127 # self.commitChanges() 4128
4129 - def retrievePackageFromInstalledTable(self, idpackage):
4130 with self.__write_mutex: 4131 try: 4132 self.cursor.execute(""" 4133 SELECT repositoryname FROM installedtable 4134 WHERE idpackage = (?)""", (idpackage,)) 4135 return self.cursor.fetchone()[0] 4136 except (self.dbapi2.OperationalError,TypeError,): 4137 return 'Not available'
4138
4139 - def removePackageFromInstalledTable(self, idpackage):
4140 with self.__write_mutex: 4141 self.cursor.execute(""" 4142 DELETE FROM installedtable 4143 WHERE idpackage = (?)""", (idpackage,))
4144
4145 - def removePackageFromDependsTable(self, idpackage):
4146 with self.__write_mutex: 4147 try: 4148 self.cursor.execute('DELETE FROM dependstable WHERE idpackage = (?)', (idpackage,)) 4149 return 0 4150 except (self.dbapi2.OperationalError,): 4151 return 1 # need reinit
4152
4153 - def createDependsTable(self):
4154 with self.__write_mutex: 4155 self.cursor.executescript(""" 4156 CREATE TABLE IF NOT EXISTS dependstable ( iddependency INTEGER PRIMARY KEY, idpackage INTEGER ); 4157 INSERT INTO dependstable VALUES (-1,-1); 4158 """) 4159 if self.indexing: 4160 self.cursor.execute('CREATE INDEX IF NOT EXISTS dependsindex_idpackage ON dependstable ( idpackage )') 4161 self.commitChanges()
4162
4163 - def sanitizeDependsTable(self):
4164 with self.__write_mutex: 4165 self.cursor.execute('DELETE FROM dependstable where iddependency = -1') 4166 self.commitChanges()
4167
4168 - def isDependsTableSane(self):
4169 try: 4170 self.cursor.execute('SELECT iddependency FROM dependstable WHERE iddependency = -1') 4171 except (self.dbapi2.OperationalError,): 4172 return False # table does not exist, please regenerate and re-run 4173 status = self.cursor.fetchone() 4174 if status: return False 4175 4176 self.cursor.execute('select count(*) from dependstable') 4177 dependstable_count = self.cursor.fetchone() 4178 if dependstable_count < 2: 4179 return False 4180 return True
4181
4182 - def createXpakTable(self):
4183 with self.__write_mutex: 4184 self.cursor.execute('CREATE TABLE xpakdata ( idpackage INTEGER PRIMARY KEY, data BLOB );') 4185 self.commitChanges()
4186
4187 - def storeXpakMetadata(self, idpackage, blob):
4188 with self.__write_mutex: 4189 self.cursor.execute('INSERT into xpakdata VALUES (?,?)', (int(idpackage), buffer(blob),)) 4190 self.commitChanges()
4191
4192 - def retrieveXpakMetadata(self, idpackage):
4193 try: 4194 self.cursor.execute('SELECT data from xpakdata where idpackage = (?)', (idpackage,)) 4195 mydata = self.cursor.fetchone() 4196 if not mydata: 4197 return "" 4198 return mydata[0] 4199 except: 4200 return ""
4201
4202 - def dropAllIndexes(self):
4203 self.cursor.execute('SELECT name FROM SQLITE_MASTER WHERE type = "index"') 4204 indexes = self.fetchall2set(self.cursor.fetchall()) 4205 with self.__write_mutex: 4206 for index in indexes: 4207 if not index.startswith("sqlite"): 4208 self.cursor.execute('DROP INDEX IF EXISTS %s' % (index,))
4209
4210 - def listAllIndexes(self, only_entropy = True):
4211 self.cursor.execute('SELECT name FROM SQLITE_MASTER WHERE type = "index"') 4212 indexes = self.fetchall2set(self.cursor.fetchall()) 4213 if not only_entropy: 4214 return indexes 4215 myindexes = set() 4216 for index in indexes: 4217 if index.startswith("sqlite"): 4218 continue 4219 myindexes.add(index) 4220 return myindexes
4221 4222
4223 - def createAllIndexes(self):
4224 self.createContentIndex() 4225 self.createBaseinfoIndex() 4226 self.createKeywordsIndex() 4227 self.createDependenciesIndex() 4228 self.createProvideIndex() 4229 self.createConflictsIndex() 4230 self.createExtrainfoIndex() 4231 self.createNeededIndex() 4232 self.createUseflagsIndex() 4233 self.createLicensedataIndex() 4234 self.createLicensesIndex() 4235 self.createConfigProtectReferenceIndex() 4236 self.createMessagesIndex() 4237 self.createSourcesIndex() 4238 self.createCountersIndex() 4239 self.createEclassesIndex() 4240 self.createCategoriesIndex() 4241 self.createCompileFlagsIndex() 4242 self.createPackagesetsIndex() 4243 self.createAutomergefilesIndex() 4244 self.createNeededlibrarypathsIndex() 4245 self.createNeededlibraryidpackagesIndex()
4246
4247 - def createPackagesetsIndex(self):
4248 if self.indexing: 4249 with self.__write_mutex: 4250 try: 4251 self.cursor.execute('CREATE INDEX IF NOT EXISTS packagesetsindex ON packagesets ( setname )') 4252 self.commitChanges() 4253 except self.dbapi2.OperationalError: 4254 pass
4255
4256 - def createNeededlibraryidpackagesIndex(self):
4257 if self.indexing: 4258 with self.__write_mutex: 4259 try: 4260 self.cursor.executescript(""" 4261 CREATE INDEX IF NOT EXISTS neededlibidpackages_library 4262 ON neededlibraryidpackages ( library ); 4263 CREATE INDEX IF NOT EXISTS neededlibidpackages_idpackage 4264 ON neededlibraryidpackages ( idpackage ); 4265 CREATE INDEX IF NOT EXISTS neededlibidpackages_lib_elf 4266 ON neededlibraryidpackages ( library, elfclass ); 4267 """) 4268 except self.dbapi2.OperationalError: 4269 pass
4270
4271 - def createNeededlibrarypathsIndex(self):
4272 if self.indexing: 4273 with self.__write_mutex: 4274 try: 4275 self.cursor.execute(""" 4276 CREATE INDEX IF NOT EXISTS neededlibpaths_library 4277 ON neededlibrarypaths ( library ) 4278 """) 4279 except self.dbapi2.OperationalError: 4280 pass
4281
4282 - def createAutomergefilesIndex(self):
4283 if self.indexing: 4284 with self.__write_mutex: 4285 try: 4286 self.cursor.executescript(""" 4287 CREATE INDEX IF NOT EXISTS automergefiles_idpackage 4288 ON automergefiles ( idpackage ); 4289 CREATE INDEX IF NOT EXISTS automergefiles_file_md5 4290 ON automergefiles ( configfile, md5 ); 4291 """) 4292 except self.dbapi2.OperationalError: 4293 pass
4294
4295 - def createNeededIndex(self):
4296 if self.indexing: 4297 with self.__write_mutex: 4298 self.cursor.executescript(""" 4299 CREATE INDEX IF NOT EXISTS neededindex ON neededreference ( library ); 4300 CREATE INDEX IF NOT EXISTS neededindex_idneeded ON needed ( idneeded ); 4301 CREATE INDEX IF NOT EXISTS neededindex_idpackage ON needed ( idpackage ); 4302 CREATE INDEX IF NOT EXISTS neededindex_elfclass ON needed ( elfclass ); 4303 """)
4304
4305 - def createMessagesIndex(self):
4306 if self.indexing: 4307 with self.__write_mutex: 4308 self.cursor.execute('CREATE INDEX IF NOT EXISTS messagesindex ON messages ( idpackage )')
4309
4310 - def createCompileFlagsIndex(self):
4311 if self.indexing: 4312 with self.__write_mutex: 4313 self.cursor.execute('CREATE INDEX IF NOT EXISTS flagsindex ON flags ( chost,cflags,cxxflags )')
4314
4315 - def createUseflagsIndex(self):
4316 if self.indexing: 4317 with self.__write_mutex: 4318 self.cursor.executescript(""" 4319 CREATE INDEX IF NOT EXISTS useflagsindex_useflags_idpackage ON useflags ( idpackage ); 4320 CREATE INDEX IF NOT EXISTS useflagsindex_useflags_idflag ON useflags ( idflag ); 4321 CREATE INDEX IF NOT EXISTS useflagsindex ON useflagsreference ( flagname ); 4322 """)
4323
4324 - def dropContentIndex(self, only_file = False):
4325 with self.__write_mutex: 4326 self.cursor.execute("DROP INDEX IF EXISTS contentindex_file") 4327 if not only_file: 4328 self.cursor.executescript("DROP INDEX IF EXISTS contentindex_couple;")
4329
4330 - def createContentIndex(self):
4331 if self.indexing: 4332 with self.__write_mutex: 4333 if self.doesTableExist("content"): 4334 self.cursor.executescript(""" 4335 CREATE INDEX IF NOT EXISTS contentindex_couple ON content ( idpackage ); 4336 CREATE INDEX IF NOT EXISTS contentindex_file ON content ( file ); 4337 """)
4338
4339 - def createConfigProtectReferenceIndex(self):
4340 if self.indexing: 4341 with self.__write_mutex: 4342 self.cursor.execute('CREATE INDEX IF NOT EXISTS configprotectreferenceindex ON configprotectreference ( protect )')
4343
4344 - def createBaseinfoIndex(self):
4345 if self.indexing: 4346 with self.__write_mutex: 4347 self.cursor.executescript(""" 4348 CREATE INDEX IF NOT EXISTS baseindex_atom ON baseinfo ( atom ); 4349 CREATE INDEX IF NOT EXISTS baseindex_branch_name ON baseinfo ( name,branch ); 4350 CREATE INDEX IF NOT EXISTS baseindex_branch_name_idcategory ON baseinfo ( name,idcategory,branch ); 4351 CREATE INDEX IF NOT EXISTS baseindex_idcategory ON baseinfo ( idcategory ); 4352 """)
4353
4354 - def createLicensedataIndex(self):
4355 if self.indexing: 4356 with self.__write_mutex: 4357 self.cursor.execute('CREATE INDEX IF NOT EXISTS licensedataindex ON licensedata ( licensename )')
4358
4359 - def createLicensesIndex(self):
4360 if self.indexing: 4361 with self.__write_mutex: 4362 self.cursor.execute('CREATE INDEX IF NOT EXISTS licensesindex ON licenses ( license )')
4363
4364 - def createCategoriesIndex(self):
4365 if self.indexing: 4366 with self.__write_mutex: 4367 self.cursor.execute('CREATE INDEX IF NOT EXISTS categoriesindex_category ON categories ( category )')
4368
4369 - def createKeywordsIndex(self):
4370 if self.indexing: 4371 with self.__write_mutex: 4372 self.cursor.executescript(""" 4373 CREATE INDEX IF NOT EXISTS keywordsreferenceindex ON keywordsreference ( keywordname ); 4374 CREATE INDEX IF NOT EXISTS keywordsindex_idpackage ON keywords ( idpackage ); 4375 CREATE INDEX IF NOT EXISTS keywordsindex_idkeyword ON keywords ( idkeyword ); 4376 """)
4377
4378 - def createDependenciesIndex(self):
4379 if self.indexing: 4380 with self.__write_mutex: 4381 self.cursor.executescript(""" 4382 CREATE INDEX IF NOT EXISTS dependenciesindex_idpackage ON dependencies ( idpackage ); 4383 CREATE INDEX IF NOT EXISTS dependenciesindex_iddependency ON dependencies ( iddependency ); 4384 CREATE INDEX IF NOT EXISTS dependenciesreferenceindex_dependency ON dependenciesreference ( dependency ); 4385 """)
4386
4387 - def createCountersIndex(self):
4388 if self.indexing: 4389 with self.__write_mutex: 4390 self.cursor.executescript(""" 4391 CREATE INDEX IF NOT EXISTS countersindex_idpackage ON counters ( idpackage ); 4392 CREATE INDEX IF NOT EXISTS countersindex_counter ON counters ( counter ); 4393 """)
4394
4395 - def createSourcesIndex(self):
4396 if self.indexing: 4397 with self.__write_mutex: 4398 self.cursor.executescript(""" 4399 CREATE INDEX IF NOT EXISTS sourcesindex_idpackage ON sources ( idpackage ); 4400 CREATE INDEX IF NOT EXISTS sourcesindex_idsource ON sources ( idsource ); 4401 CREATE INDEX IF NOT EXISTS sourcesreferenceindex_source ON sourcesreference ( source ); 4402 """)
4403
4404 - def createProvideIndex(self):
4405 if self.indexing: 4406 with self.__write_mutex: 4407 self.cursor.executescript(""" 4408 CREATE INDEX IF NOT EXISTS provideindex_idpackage ON provide ( idpackage ); 4409 CREATE INDEX IF NOT EXISTS provideindex_atom ON provide ( atom ); 4410 """)
4411
4412 - def createConflictsIndex(self):
4413 if self.indexing: 4414 with self.__write_mutex: 4415 self.cursor.executescript(""" 4416 CREATE INDEX IF NOT EXISTS conflictsindex_idpackage ON conflicts ( idpackage ); 4417 CREATE INDEX IF NOT EXISTS conflictsindex_atom ON conflicts ( conflict ); 4418 """)
4419
4420 - def createExtrainfoIndex(self):
4421 if self.indexing: 4422 with self.__write_mutex: 4423 self.cursor.execute('CREATE INDEX IF NOT EXISTS extrainfoindex ON extrainfo ( description )') 4424 self.cursor.execute('CREATE INDEX IF NOT EXISTS extrainfoindex_pkgindex ON extrainfo ( idpackage )')
4425
4426 - def createEclassesIndex(self):
4427 if self.indexing: 4428 with self.__write_mutex: 4429 self.cursor.executescript(""" 4430 CREATE INDEX IF NOT EXISTS eclassesindex_idpackage ON eclasses ( idpackage ); 4431 CREATE INDEX IF NOT EXISTS eclassesindex_idclass ON eclasses ( idclass ); 4432 CREATE INDEX IF NOT EXISTS eclassesreferenceindex_classname ON eclassesreference ( classname ); 4433 """)
4434
4435 - def regenerateCountersTable(self, vdb_path, output = False):
4436 4437 # this is necessary now, counters table should be empty 4438 self.cursor.execute("DELETE FROM counters;") 4439 # assign a counter to an idpackage 4440 myids = self.listAllIdpackages() 4441 counter_path = etpConst['spm']['xpak_entries']['counter'] 4442 for myid in myids: 4443 # get atom 4444 myatom = self.retrieveAtom(myid) 4445 mybranch = self.retrieveBranch(myid) 4446 myatom = self.entropyTools.remove_tag(myatom) 4447 myatomcounterpath = "%s%s/%s" % (vdb_path, myatom, counter_path,) 4448 if os.path.isfile(myatomcounterpath): 4449 try: 4450 with open(myatomcounterpath, "r") as f: 4451 counter = int(f.readline().strip()) 4452 except: 4453 if output: 4454 mytxt = "%s: %s: %s" % ( 4455 bold(_("ATTENTION")), 4456 red(_("cannot open Spm counter file for")), 4457 bold(myatom), 4458 ) 4459 self.updateProgress( 4460 mytxt, 4461 importance = 1, 4462 type = "warning" 4463 ) 4464 continue 4465 # insert id+counter 4466 with self.__write_mutex: 4467 try: 4468 self.cursor.execute( 4469 'INSERT into counters VALUES ' 4470 '(?,?,?)', ( counter, myid, mybranch ) 4471 ) 4472 except self.dbapi2.IntegrityError: 4473 if output: 4474 mytxt = "%s: %s: %s" % ( 4475 bold(_("ATTENTION")), 4476 red(_("counter for atom is duplicated, ignoring")), 4477 bold(myatom), 4478 ) 4479 self.updateProgress( 4480 mytxt, 4481 importance = 1, 4482 type = "warning" 4483 ) 4484 continue 4485 # don't trust counters, they might not be unique 4486 4487 self.commitChanges()
4488
4489 - def clearTreeupdatesEntries(self, repository):
4490 if not self.doesTableExist("treeupdates"): 4491 self.createTreeupdatesTable() 4492 # treeupdates 4493 with self.__write_mutex: 4494 self.cursor.execute("DELETE FROM treeupdates WHERE repository = (?)", (repository,)) 4495 self.commitChanges()
4496
4497 - def resetTreeupdatesDigests(self):
4498 with self.__write_mutex: 4499 self.cursor.execute('UPDATE treeupdates SET digest = "-1"') 4500 self.commitChanges()
4501
4502 - def migrateCountersTable(self):
4503 with self.__write_mutex: 4504 self._migrateCountersTable()
4505
4506 - def _migrateCountersTable(self):
4507 self.cursor.executescript(""" 4508 DROP TABLE IF EXISTS counterstemp; 4509 CREATE TABLE counterstemp ( 4510 counter INTEGER, idpackage INTEGER, branch VARCHAR, 4511 PRIMARY KEY(idpackage,branch) 4512 ); 4513 INSERT INTO counterstemp (counter, idpackage, branch) 4514 SELECT counter, idpackage, branch FROM counters; 4515 DROP TABLE counters; 4516 ALTER TABLE counterstemp RENAME TO counters; 4517 """) 4518 self.commitChanges()
4519
4520 - def createNeededlibrarypathsTable(self):
4521 with self.__write_mutex: 4522 self.cursor.execute(""" 4523 CREATE TABLE neededlibrarypaths ( 4524 library VARCHAR, 4525 path VARCHAR 4526 ); 4527 """)
4528
4529 - def createNeededlibraryidpackagesTable(self):
4530 with self.__write_mutex: 4531 self.cursor.executescript(""" 4532 DROP TABLE IF EXISTS neededlibraryidpackages; 4533 CREATE TABLE neededlibraryidpackages ( 4534 idpackage INTEGER, 4535 library VARCHAR, 4536 elfclass INTEGER 4537 ); 4538 """)
4539
4540 - def createInstalledTableSource(self):
4541 with self.__write_mutex: 4542 self.cursor.execute('ALTER TABLE installedtable ADD source INTEGER;') 4543 self.cursor.execute(""" 4544 UPDATE installedtable SET source = (?) 4545 """, (etpConst['install_sources']['unknown'],))
4546
4547 - def createPackagechangelogsTable(self):
4548 with self.__write_mutex: 4549 self.cursor.execute('CREATE TABLE packagechangelogs ( category VARCHAR, name VARCHAR, changelog BLOB, PRIMARY KEY (category, name));')
4550
4551 - def createAutomergefilesTable(self):
4552 with self.__write_mutex: 4553 self.cursor.execute('CREATE TABLE automergefiles ( idpackage INTEGER, configfile VARCHAR, md5 VARCHAR );')
4554
4555 - def createPackagesignaturesTable(self):
4556 with self.__write_mutex: 4557 self.cursor.execute('CREATE TABLE packagesignatures ( idpackage INTEGER PRIMARY KEY, sha1 VARCHAR, sha256 VARCHAR, sha512 VARCHAR );')
4558
4559 - def createPackagespmphases(self):
4560 with self.__write_mutex: 4561 self.cursor.execute(""" 4562 CREATE TABLE packagespmphases ( 4563 idpackage INTEGER PRIMARY KEY, 4564 phases VARCHAR 4565 ); 4566 """)
4567
4568 - def createPackagesetsTable(self):
4569 with self.__write_mutex: 4570 self.cursor.execute('CREATE TABLE packagesets ( setname VARCHAR, dependency VARCHAR );')
4571
4572 - def createCategoriesdescriptionTable(self):
4573 with self.__write_mutex: 4574 self.cursor.execute('CREATE TABLE categoriesdescription ( category VARCHAR, locale VARCHAR, description VARCHAR );')
4575
4576 - def createTreeupdatesTable(self):
4577 with self.__write_mutex: 4578 self.cursor.execute('CREATE TABLE treeupdates ( repository VARCHAR PRIMARY KEY, digest VARCHAR );')
4579
4580 - def createLicensedataTable(self):
4581 with self.__write_mutex: 4582 self.cursor.execute('CREATE TABLE licensedata ( licensename VARCHAR UNIQUE, text BLOB, compressed INTEGER );')
4583
4584 - def createLicensesAcceptedTable(self):
4585 with self.__write_mutex: 4586 self.cursor.execute('CREATE TABLE licenses_accepted ( licensename VARCHAR UNIQUE );')
4587
4588 - def createInstalledTable(self):
4589 with self.__write_mutex: 4590 self.cursor.execute('DROP TABLE IF EXISTS installedtable;') 4591 self.cursor.execute('CREATE TABLE installedtable ( idpackage INTEGER PRIMARY KEY, repositoryname VARCHAR, source INTEGER );')
4592
4593 - def addDependsRelationToDependsTable(self, iterable):
4594 with self.__write_mutex: 4595 self.cursor.executemany('INSERT into dependstable VALUES (?,?)', iterable) 4596 if (self.entropyTools.is_user_in_entropy_group()) and \ 4597 (self.dbname.startswith(etpConst['serverdbid'])): 4598 # force commit even if readonly, this will allow to automagically fix dependstable server side 4599 self.connection.commit() # we don't care much about syncing the database since it's quite trivial
4600
4601 - def clearDependsTable(self):
4602 if not self.doesTableExist("dependstable"): 4603 return 4604 self.cursor.executescript(""" 4605 DELETE FROM dependstable; 4606 INSERT INTO dependstable VALUES (-1,-1); 4607 """)
4608
4609 - def regenerateDependsTable(self, output = True):
4610 4611 depends = self.listAllDependencies() 4612 count = 0 4613 total = len(depends) 4614 mydata = set() 4615 am = self.atomMatch 4616 up = self.updateProgress 4617 self.clearDependsTable() 4618 for iddep, atom in depends: 4619 count += 1 4620 4621 if output and ((count == 0) or (count % 150 == 0) or \ 4622 (count == total)): 4623 up( red("Resolving %s") % (atom,), importance = 0, 4624 type = "info", back = True, count = (count, total) 4625 ) 4626 4627 idpackage, rc = am(atom) 4628 if idpackage == -1: 4629 continue 4630 mydata.add((iddep, idpackage)) 4631 4632 if mydata: 4633 self.addDependsRelationToDependsTable(mydata) 4634 4635 # now validate dependstable 4636 self.sanitizeDependsTable()
4637
4638 - def regenerateLibrarypathsidpackageTable(self, output = True):
4639 4640 if output: 4641 self.updateProgress( 4642 "%s ..." % ( 4643 purple(_("Resolving libraries, please wait")), 4644 ), 4645 importance = 0, type = "info", back = True 4646 ) 4647 self.cursor.executescript(""" 4648 DELETE FROM neededlibraryidpackages; 4649 INSERT INTO neededlibraryidpackages (idpackage, library, elfclass) 4650 SELECT 4651 distinct(baseinfo.idpackage) as idpackage, 4652 neededlibrarypaths.library as library, 4653 needed.elfclass as elfclass 4654 FROM 4655 neededlibrarypaths, baseinfo, content, needed, neededreference 4656 WHERE 4657 neededlibrarypaths.library = neededreference.library AND 4658 neededreference.idneeded = needed.idneeded AND 4659 needed.idpackage = content.idpackage AND 4660 baseinfo.idpackage = needed.idpackage AND 4661 content.file = neededlibrarypaths.path ORDER BY baseinfo.idpackage; 4662 4663 """) 4664 if output: 4665 self.updateProgress( 4666 "%s" % ( 4667 purple(_("Libraries solved, all fine")), 4668 ), 4669 importance = 0, type = "info" 4670 )
4671
4672 - def moveCountersToBranch(self, to_branch):
4673 with self.__write_mutex: 4674 self.cursor.execute('UPDATE counters SET branch = (?)', to_branch) 4675 self.commitChanges() 4676 self.clearCache()
4677
4678 - def atomMatchFetchCache(self, *args):
4679 if self.xcache: 4680 cached = self.dumpTools.loadobj("%s/%s/%s" % (self.dbMatchCacheKey, self.dbname, hash(tuple(args)),)) 4681 if cached != None: return cached
4682
4683 - def atomMatchStoreCache(self, *args, **kwargs):
4684 if self.xcache: 4685 self.Cacher.push("%s/%s/%s" % ( 4686 self.dbMatchCacheKey,self.dbname,hash(tuple(args)),), 4687 kwargs.get('result') 4688 )
4689
4690 - def atomMatchValidateCache(self, cached_obj, multiMatch, extendedResults):
4691 4692 # time wasted for a reason 4693 data, rc = cached_obj 4694 if rc != 0: return cached_obj 4695 4696 if (not extendedResults) and (not multiMatch): 4697 if not self.isIDPackageAvailable(data): return None 4698 elif extendedResults and (not multiMatch): 4699 # ((idpackage,0,version,versiontag,revision,),0) 4700 if not self.isIDPackageAvailable(data[0]): return None 4701 elif extendedResults and multiMatch: 4702 # (set([(idpackage,0,version,version_tag,revision) for x in dbpkginfo]),0) 4703 idpackages = set([x[0] for x in data]) 4704 if not self.areIDPackagesAvailable(idpackages): return None 4705 elif (not extendedResults) and multiMatch: 4706 # (set([x[0] for x in dbpkginfo]),0) 4707 idpackages = set(data) 4708 if not self.areIDPackagesAvailable(idpackages): return None 4709 4710 return cached_obj
4711
4712 - def _idpackageValidator_live(self, idpackage, reponame):
4713 if (idpackage, reponame) in self.SystemSettings['live_packagemasking']['mask_matches']: 4714 # do not cache this 4715 return -1, self.SystemSettings['pkg_masking_reference']['user_live_mask'] 4716 elif (idpackage, reponame) in self.SystemSettings['live_packagemasking']['unmask_matches']: 4717 return idpackage, self.SystemSettings['pkg_masking_reference']['user_live_unmask']
4718
4719 - def _idpackageValidator_user_package_mask(self, idpackage, reponame, live):
4720 # check if user package.mask needs it masked 4721 4722 mykw = "%smask_ids" % (reponame,) 4723 user_package_mask_ids = self.SystemSettings.get(mykw) 4724 if not isinstance(user_package_mask_ids, set): 4725 user_package_mask_ids = set() 4726 for atom in self.SystemSettings['mask']: 4727 matches, r = self.atomMatch(atom, multiMatch = True, packagesFilter = False) 4728 if r != 0: 4729 continue 4730 user_package_mask_ids |= set(matches) 4731 self.SystemSettings[mykw] = user_package_mask_ids 4732 if idpackage in user_package_mask_ids: 4733 # sorry, masked 4734 myr = self.SystemSettings['pkg_masking_reference']['user_package_mask'] 4735 try: 4736 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 4737 validator_cache[(idpackage, reponame, live)] = -1, myr 4738 except KeyError: # system settings client plugin not found 4739 pass 4740 return -1, myr
4741
4742 - def _idpackageValidator_user_package_unmask(self, idpackage, reponame, live):
4743 # see if we can unmask by just lookin into user package.unmask stuff -> self.SystemSettings['unmask'] 4744 mykw = "%sunmask_ids" % (reponame,) 4745 user_package_unmask_ids = self.SystemSettings.get(mykw) 4746 if not isinstance(user_package_unmask_ids, set): 4747 user_package_unmask_ids = set() 4748 for atom in self.SystemSettings['unmask']: 4749 matches, r = self.atomMatch(atom, multiMatch = True, packagesFilter = False) 4750 if r != 0: 4751 continue 4752 user_package_unmask_ids |= set(matches) 4753 self.SystemSettings[mykw] = user_package_unmask_ids 4754 if idpackage in user_package_unmask_ids: 4755 myr = self.SystemSettings['pkg_masking_reference']['user_package_unmask'] 4756 try: 4757 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 4758 validator_cache[(idpackage, reponame, live)] = idpackage, myr 4759 except KeyError: # system settings client plugin not found 4760 pass 4761 return idpackage, myr
4762
4763 - def _idpackageValidator_packages_db_mask(self, idpackage, reponame, live):
4764 # check if repository packages.db.mask needs it masked 4765 repos_mask = self.SystemSettings['repos_mask'] 4766 repomask = repos_mask.get(reponame) 4767 if isinstance(repomask, set): 4768 # first, seek into generic masking, all branches 4769 mask_repo_id = "%s_ids@@:of:%s" % (reponame, reponame,) # avoid issues with repository names 4770 repomask_ids = repos_mask.get(mask_repo_id) 4771 if not isinstance(repomask_ids, set): 4772 repomask_ids = set() 4773 for atom in repomask: 4774 matches, r = self.atomMatch(atom, multiMatch = True, packagesFilter = False) 4775 if r != 0: 4776 continue 4777 repomask_ids |= set(matches) 4778 repos_mask[mask_repo_id] = repomask_ids 4779 if idpackage in repomask_ids: 4780 myr = self.SystemSettings['pkg_masking_reference']['repository_packages_db_mask'] 4781 try: 4782 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 4783 validator_cache[(idpackage, reponame, live)] = -1, myr 4784 except KeyError: # system settings client plugin not found 4785 pass 4786 return -1, myr
4787
4788 - def _idpackageValidator_package_license_mask(self, idpackage, reponame, live):
4789 if self.SystemSettings['license_mask']: 4790 mylicenses = self.retrieveLicense(idpackage) 4791 mylicenses = mylicenses.strip().split() 4792 lic_mask = self.SystemSettings['license_mask'] 4793 for mylicense in mylicenses: 4794 if mylicense not in lic_mask: continue 4795 myr = self.SystemSettings['pkg_masking_reference']['user_license_mask'] 4796 try: 4797 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 4798 validator_cache[(idpackage, reponame, live)] = -1, myr 4799 except KeyError: # system settings client plugin not found 4800 pass 4801 return -1, myr
4802
4803 - def _idpackageValidator_keyword_mask(self, idpackage, reponame, live):
4804 4805 mykeywords = self.retrieveKeywords(idpackage) 4806 # WORKAROUND for buggy entries 4807 if not mykeywords: mykeywords = [''] # ** is fine then 4808 # firstly, check if package keywords are in etpConst['keywords'] 4809 # (universal keywords have been merged from package.mask) 4810 for key in etpConst['keywords']: 4811 if key not in mykeywords: continue 4812 myr = self.SystemSettings['pkg_masking_reference']['system_keyword'] 4813 try: 4814 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 4815 validator_cache[(idpackage, reponame, live)] = idpackage, myr 4816 except KeyError: # system settings client plugin not found 4817 pass 4818 return idpackage, myr 4819 4820 # if we get here, it means we didn't find mykeywords in etpConst['keywords'] 4821 # we need to seek self.SystemSettings['keywords'] 4822 # seek in repository first 4823 if reponame in self.SystemSettings['keywords']['repositories']: 4824 for keyword in self.SystemSettings['keywords']['repositories'][reponame]: 4825 if keyword not in mykeywords: continue 4826 keyword_data = self.SystemSettings['keywords']['repositories'][reponame].get(keyword) 4827 if not keyword_data: continue 4828 if "*" in keyword_data: # all packages in this repo with keyword "keyword" are ok 4829 myr = self.SystemSettings['pkg_masking_reference']['user_repo_package_keywords_all'] 4830 try: 4831 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 4832 validator_cache[(idpackage, reponame, live)] = idpackage, myr 4833 except KeyError: # system settings client plugin not found 4834 pass 4835 return idpackage, myr 4836 kwd_key = "%s_ids" % (keyword,) 4837 keyword_data_ids = self.SystemSettings['keywords']['repositories'][reponame].get(kwd_key) 4838 if not isinstance(keyword_data_ids, set): 4839 keyword_data_ids = set() 4840 for atom in keyword_data: 4841 matches, r = self.atomMatch(atom, multiMatch = True, packagesFilter = False) 4842 if r != 0: 4843 continue 4844 keyword_data_ids |= matches 4845 self.SystemSettings['keywords']['repositories'][reponame][kwd_key] = keyword_data_ids 4846 if idpackage in keyword_data_ids: 4847 myr = self.SystemSettings['pkg_masking_reference']['user_repo_package_keywords'] 4848 try: 4849 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 4850 validator_cache[(idpackage, reponame, live)] = idpackage, myr 4851 except KeyError: # system settings client plugin not found 4852 pass 4853 return idpackage, myr 4854 4855 # if we get here, it means we didn't find a match in repositories 4856 # so we scan packages, last chance 4857 for keyword in self.SystemSettings['keywords']['packages']: 4858 # first of all check if keyword is in mykeywords 4859 if keyword not in mykeywords: continue 4860 keyword_data = self.SystemSettings['keywords']['packages'].get(keyword) 4861 if not keyword_data: continue 4862 kwd_key = "%s_ids" % (keyword,) 4863 keyword_data_ids = self.SystemSettings['keywords']['packages'].get(reponame+kwd_key) 4864 if not isinstance(keyword_data_ids, set): 4865 keyword_data_ids = set() 4866 for atom in keyword_data: 4867 # match atom 4868 matches, r = self.atomMatch(atom, multiMatch = True, packagesFilter = False) 4869 if r != 0: 4870 continue 4871 keyword_data_ids |= matches 4872 self.SystemSettings['keywords']['packages'][reponame+kwd_key] = keyword_data_ids 4873 if idpackage in keyword_data_ids: 4874 # valid! 4875 myr = self.SystemSettings['pkg_masking_reference']['user_package_keywords'] 4876 try: 4877 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 4878 validator_cache[(idpackage, reponame, live)] = idpackage, myr 4879 except KeyError: # system settings client plugin not found 4880 pass 4881 return idpackage, myr
4882 4883 4884 4885 # function that validate one atom by reading keywords settings 4886 # validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache']
4887 - def idpackageValidator(self, idpackage, live = True):
4888 4889 if self.dbname == etpConst['clientdbid']: 4890 return idpackage, 0 4891 elif self.dbname.startswith(etpConst['serverdbid']): 4892 return idpackage, 0 4893 4894 reponame = self.dbname[len(etpConst['dbnamerepoprefix']):] 4895 try: 4896 validator_cache = self.SystemSettings[self.client_settings_plugin_id]['masking_validation']['cache'] 4897 cached = validator_cache.get((idpackage, reponame, live)) 4898 if cached != None: 4899 return cached 4900 # avoid memleaks 4901 if len(validator_cache) > 10000: 4902 validator_cache.clear() 4903 except KeyError: # plugin does not exist 4904 pass 4905 4906 if live: 4907 data = self._idpackageValidator_live(idpackage, reponame) 4908 if data: return data 4909 4910 data = self._idpackageValidator_user_package_mask(idpackage, reponame, live) 4911 if data: return data 4912 4913 data = self._idpackageValidator_user_package_unmask(idpackage, reponame, live) 4914 if data: return data 4915 4916 data = self._idpackageValidator_packages_db_mask(idpackage, reponame, live) 4917 if data: return data 4918 4919 data = self._idpackageValidator_package_license_mask(idpackage, reponame, live) 4920 if data: return data 4921 4922 data = self._idpackageValidator_keyword_mask(idpackage, reponame, live) 4923 if data: return data 4924 4925 # holy crap, can't validate 4926 myr = self.SystemSettings['pkg_masking_reference']['completely_masked'] 4927 validator_cache[(idpackage, reponame, live)] = -1, myr 4928 return -1, myr
4929 4930 # packages filter used by atomMatch, input must me foundIDs, a list like this: 4931 # [608,1867]
4932 - def packagesFilter(self, results):
4933 # keywordsFilter ONLY FILTERS results if 4934 # self.dbname.startswith(etpConst['dbnamerepoprefix']) => repository database is open 4935 if not self.dbname.startswith(etpConst['dbnamerepoprefix']): 4936 return results 4937 4938 newresults = set() 4939 for idpackage in results: 4940 idpackage, reason = self.idpackageValidator(idpackage) 4941 if idpackage == -1: continue 4942 newresults.add(idpackage) 4943 return newresults
4944
4945 - def __filterSlot(self, idpackage, slot):
4946 if slot == None: 4947 return idpackage 4948 dbslot = self.retrieveSlot(idpackage) 4949 if str(dbslot) == str(slot): 4950 return idpackage
4951
4952 - def __filterTag(self, idpackage, tag, operators):
4953 if tag == None: 4954 return idpackage 4955 dbtag = self.retrieveVersionTag(idpackage) 4956 compare = cmp(tag, dbtag) 4957 if not operators or operators == "=": 4958 if compare == 0: 4959 return idpackage 4960 else: 4961 return self.__do_operator_compare(idpackage, operators, compare)
4962
4963 - def __filterUse(self, idpackage, use):
4964 if not use: 4965 return idpackage 4966 pkguse = self.retrieveUseflags(idpackage) 4967 disabled = set([x[1:] for x in use if x.startswith("-")]) 4968 enabled = set([x for x in use if not x.startswith("-")]) 4969 enabled_not_satisfied = enabled - pkguse 4970 # check enabled 4971 if enabled_not_satisfied: 4972 return None 4973 # check disabled 4974 disabled_not_satisfied = disabled - pkguse 4975 if len(disabled_not_satisfied) != len(disabled): 4976 return None 4977 return idpackage
4978
4979 - def __do_operator_compare(self, token, operators, compare):
4980 if operators == ">" and compare == -1: 4981 return token 4982 elif operators == ">=" and compare < 1: 4983 return token 4984 elif operators == "<" and compare == 1: 4985 return token 4986 elif operators == "<=" and compare > -1: 4987 return token
4988
4989 - def __filterSlotTagUse(self, foundIDs, slot, tag, use, operators):
4990 4991 def myfilter(idpackage): 4992 4993 idpackage = self.__filterSlot(idpackage, slot) 4994 if not idpackage: 4995 return False 4996 4997 idpackage = self.__filterUse(idpackage, use) 4998 if not idpackage: 4999 return False 5000 5001 idpackage = self.__filterTag(idpackage, tag, operators) 5002 if not idpackage: 5003 return False 5004 5005 return True
5006 5007 return set(filter(myfilter, foundIDs)) 5008 5009 ''' 5010 @description: matches the user chosen package name+ver, if possibile, in a single repository 5011 @input atom: string, atom to match 5012 @input caseSensitive: bool, should the atom be parsed case sensitive? 5013 @input matchSlot: string, match atoms with the provided slot 5014 @input multiMatch: bool, return all the available atoms 5015 @input matchBranches: tuple or list, match packages only in the specified branches 5016 @input matchTag: match packages only for the specified tag 5017 @input matchUse: match packages only if it owns the specified use flags 5018 @input packagesFilter: enable/disable package.mask/.keywords/.unmask filter 5019 @output: the package id, if found, otherwise -1 plus the status, 0 = ok, 1 = error 5020 '''
5021 - def atomMatch(self, atom, caseSensitive = True, matchSlot = None, multiMatch = False, 5022 matchBranches = (), matchTag = None, matchUse = (), packagesFilter = True, 5023 matchRevision = None, extendedResults = False, useCache = True ):
5024 5025 if not atom: 5026 return -1, 1 5027 5028 if useCache: 5029 cached = self.atomMatchFetchCache( 5030 atom, caseSensitive, matchSlot, 5031 multiMatch, matchBranches, matchTag, 5032 matchUse, packagesFilter, matchRevision, 5033 extendedResults 5034 ) 5035 if isinstance(cached, tuple): 5036 try: 5037 cached = self.atomMatchValidateCache(cached, multiMatch, extendedResults) 5038 except (TypeError, ValueError, IndexError, KeyError,): 5039 cached = None 5040 if isinstance(cached, tuple): 5041 return cached 5042 5043 atomTag = self.entropyTools.dep_gettag(atom) 5044 try: 5045 atomUse = self.entropyTools.dep_getusedeps(atom) 5046 except InvalidAtom: 5047 atomUse = () 5048 atomSlot = self.entropyTools.dep_getslot(atom) 5049 atomRev = self.entropyTools.dep_get_entropy_revision(atom) 5050 if isinstance(atomRev, (int, long,)): 5051 if atomRev < 0: atomRev = None 5052 5053 # use match 5054 scan_atom = self.entropyTools.remove_usedeps(atom) 5055 if (not matchUse) and (atomUse): 5056 matchUse = atomUse 5057 5058 # tag match 5059 scan_atom = self.entropyTools.remove_tag(scan_atom) 5060 if (matchTag == None) and (atomTag != None): 5061 matchTag = atomTag 5062 5063 # slot match 5064 scan_atom = self.entropyTools.remove_slot(scan_atom) 5065 if (matchSlot == None) and (atomSlot != None): 5066 matchSlot = atomSlot 5067 5068 # revision match 5069 scan_atom = self.entropyTools.remove_entropy_revision(scan_atom) 5070 if (matchRevision == None) and (atomRev != None): 5071 matchRevision = atomRev 5072 5073 branch_list = () 5074 direction = '' 5075 justname = True 5076 pkgkey = '' 5077 strippedAtom = '' 5078 foundIDs = [] 5079 dbpkginfo = set() 5080 5081 if scan_atom: 5082 5083 while 1: 5084 pkgversion = '' 5085 # check for direction 5086 strippedAtom = self.entropyTools.dep_getcpv(scan_atom) 5087 if scan_atom[-1] == "*": 5088 strippedAtom += "*" 5089 direction = scan_atom[0:len(scan_atom)-len(strippedAtom)] 5090 5091 justname = self.entropyTools.isjustname(strippedAtom) 5092 pkgkey = strippedAtom 5093 if justname == 0: 5094 # get version 5095 data = self.entropyTools.catpkgsplit(strippedAtom) 5096 if data == None: break # badly formatted 5097 pkgversion = data[2]+"-"+data[3] 5098 pkgkey = self.entropyTools.dep_getkey(strippedAtom) 5099 5100 splitkey = pkgkey.split("/") 5101 if (len(splitkey) == 2): 5102 pkgname = splitkey[1] 5103 pkgcat = splitkey[0] 5104 else: 5105 pkgname = splitkey[0] 5106 pkgcat = "null" 5107 5108 branch_list = (self.db_branch,) 5109 if matchBranches: 5110 # force to tuple for security 5111 branch_list = tuple(matchBranches) 5112 break 5113 5114 5115 if branch_list: 5116 # IDs found in the database that match our search 5117 foundIDs = self.__generate_found_ids_match(branch_list, pkgkey, pkgname, pkgcat, caseSensitive, multiMatch) 5118 5119 ### FILTERING 5120 # filter slot and tag 5121 if foundIDs: 5122 foundIDs = self.__filterSlotTagUse(foundIDs, matchSlot, matchTag, matchUse, direction) 5123 if packagesFilter: 5124 foundIDs = self.packagesFilter(foundIDs) 5125 ### END FILTERING 5126 5127 if foundIDs: 5128 dbpkginfo = self.__handle_found_ids_match(foundIDs, direction, matchTag, matchRevision, justname, strippedAtom, pkgversion) 5129 5130 if not dbpkginfo: 5131 if extendedResults: 5132 if multiMatch: 5133 x = set() 5134 else: 5135 x = (-1, 1, None, None, None,) 5136 self.atomMatchStoreCache( 5137 atom, caseSensitive, matchSlot, 5138 multiMatch, matchBranches, matchTag, 5139 matchUse, packagesFilter, matchRevision, 5140 extendedResults, result = (x, 1) 5141 ) 5142 return x, 1 5143 else: 5144 if multiMatch: 5145 x = set() 5146 else: 5147 x = -1 5148 self.atomMatchStoreCache( 5149 atom, caseSensitive, matchSlot, 5150 multiMatch, matchBranches, matchTag, 5151 matchUse, packagesFilter, matchRevision, 5152 extendedResults, result = (x, 1) 5153 ) 5154 return x, 1 5155 5156 if multiMatch: 5157 if extendedResults: 5158 x = set([(x[0], 0, x[1], self.retrieveVersionTag(x[0]), self.retrieveRevision(x[0])) for x in dbpkginfo]) 5159 self.atomMatchStoreCache( 5160 atom, caseSensitive, matchSlot, 5161 multiMatch, matchBranches, matchTag, 5162 matchUse, packagesFilter, matchRevision, 5163 extendedResults, result = (x, 0) 5164 ) 5165 return x, 0 5166 else: 5167 x = set([x[0] for x in dbpkginfo]) 5168 self.atomMatchStoreCache( 5169 atom, caseSensitive, matchSlot, 5170 multiMatch, matchBranches, matchTag, 5171 matchUse, packagesFilter, matchRevision, 5172 extendedResults, result = (x, 0) 5173 ) 5174 return x, 0 5175 5176 if len(dbpkginfo) == 1: 5177 x = dbpkginfo.pop() 5178 if extendedResults: 5179 x = (x[0], 0, x[1], self.retrieveVersionTag(x[0]), self.retrieveRevision(x[0])) 5180 self.atomMatchStoreCache( 5181 atom, caseSensitive, matchSlot, 5182 multiMatch, matchBranches, matchTag, 5183 matchUse, packagesFilter, matchRevision, 5184 extendedResults, result = (x, 0) 5185 ) 5186 return x, 0 5187 else: 5188 self.atomMatchStoreCache( 5189 atom, caseSensitive, matchSlot, 5190 multiMatch, matchBranches, matchTag, 5191 matchUse, packagesFilter, matchRevision, 5192 extendedResults, result = (x[0], 0) 5193 ) 5194 return x[0], 0 5195 5196 dbpkginfo = list(dbpkginfo) 5197 pkgdata = {} 5198 versions = set() 5199 for x in dbpkginfo: 5200 info_tuple = (x[1], self.retrieveVersionTag(x[0]), self.retrieveRevision(x[0])) 5201 versions.add(info_tuple) 5202 pkgdata[info_tuple] = x[0] 5203 newer = self.entropyTools.get_entropy_newer_version(list(versions))[0] 5204 x = pkgdata[newer] 5205 if extendedResults: 5206 x = (x, 0, newer[0], newer[1], newer[2]) 5207 self.atomMatchStoreCache( 5208 atom, caseSensitive, matchSlot, 5209 multiMatch, matchBranches, matchTag, 5210 matchUse, packagesFilter, matchRevision, 5211 extendedResults, result = (x, 0) 5212 ) 5213 return x, 0 5214 else: 5215 self.atomMatchStoreCache( 5216 atom, caseSensitive, matchSlot, 5217 multiMatch, matchBranches, matchTag, 5218 matchUse, packagesFilter, matchRevision, 5219 extendedResults, result = (x, 0) 5220 ) 5221 return x, 0
5222
5223 - def __generate_found_ids_match(self, branch_list, pkgkey, pkgname, pkgcat, caseSensitive, multiMatch):
5224 foundIDs = set() 5225 for idx in branch_list: 5226 5227 if pkgcat == "null": 5228 results = self.searchPackagesByName( 5229 pkgname, sensitive = caseSensitive, 5230 branch = idx, justid = True 5231 ) 5232 else: 5233 results = self.searchPackagesByNameAndCategory( 5234 name = pkgname, category = pkgcat, branch = idx, 5235 sensitive = caseSensitive, justid = True 5236 ) 5237 5238 mypkgcat = pkgcat 5239 mypkgname = pkgname 5240 virtual = False 5241 # if it's a PROVIDE, search with searchProvide 5242 # there's no package with that name 5243 if (not results) and (mypkgcat == "virtual"): 5244 virtuals = self.searchProvide(pkgkey, branch = idx, justid = True) 5245 if virtuals: 5246 virtual = True 5247 mypkgname = self.retrieveName(virtuals[0]) 5248 mypkgcat = self.retrieveCategory(virtuals[0]) 5249 results = virtuals 5250 5251 # now validate 5252 if not results: 5253 continue # search into a stabler branch 5254 5255 elif (len(results) > 1): 5256 5257 # if it's because category differs, it's a problem 5258 foundCat = None 5259 cats = set() 5260 for idpackage in results: 5261 cat = self.retrieveCategory(idpackage) 5262 cats.add(cat) 5263 if (cat == mypkgcat) or ((not virtual) and (mypkgcat == "virtual") and (cat == mypkgcat)): 5264 # in case of virtual packages only (that they're not stored as provide) 5265 foundCat = cat 5266 5267 # if we found something at least... 5268 if (not foundCat) and (len(cats) == 1) and (mypkgcat in ("virtual", "null")): 5269 foundCat = sorted(cats)[0] 5270 5271 if not foundCat: 5272 # got the issue 5273 continue 5274 5275 # we can use foundCat 5276 mypkgcat = foundCat 5277 5278 # we need to search using the category 5279 if (not multiMatch) and (pkgcat == "null" or virtual): 5280 # we searched by name, we need to search using category 5281 results = self.searchPackagesByNameAndCategory( 5282 name = mypkgname, category = mypkgcat, 5283 branch = idx, sensitive = caseSensitive, justid = True 5284 ) 5285 5286 # validate again 5287 if not results: 5288 continue # search into another branch 5289 5290 # if we get here, we have found the needed IDs 5291 foundIDs |= set(results) 5292 break 5293 5294 else: 5295 5296 idpackage = results[0] 5297 # if mypkgcat is virtual, we can force 5298 if (mypkgcat == "virtual") and (not virtual): 5299 # in case of virtual packages only (that they're not stored as provide) 5300 mypkgcat = self.retrieveCategory(idpackage) 5301 5302 # check if category matches 5303 if mypkgcat != "null": 5304 foundCat = self.retrieveCategory(idpackage) 5305 if mypkgcat == foundCat: 5306 foundIDs.add(idpackage) 5307 continue 5308 foundIDs.add(idpackage) 5309 break 5310 5311 return foundIDs
5312 5313
5314 - def __handle_found_ids_match(self, foundIDs, direction, matchTag, matchRevision, justname, strippedAtom, pkgversion):
5315 5316 dbpkginfo = set() 5317 # now we have to handle direction 5318 if ((direction) or ((not direction) and (not justname)) or ((not direction) and (not justname) and strippedAtom.endswith("*"))) and foundIDs: 5319 5320 if (not justname) and \ 5321 ((direction == "~") or (direction == "=") or \ 5322 (direction == '' and not justname) or (direction == '' and not justname and strippedAtom.endswith("*"))): 5323 # any revision within the version specified OR the specified version 5324 5325 if (direction == '' and not justname): 5326 direction = "=" 5327 5328 # remove gentoo revision (-r0 if none) 5329 if (direction == "="): 5330 if (pkgversion.split("-")[-1] == "r0"): 5331 pkgversion = self.entropyTools.remove_revision(pkgversion) 5332 if (direction == "~"): 5333 pkgrevision = self.entropyTools.dep_get_portage_revision(pkgversion) 5334 pkgversion = self.entropyTools.remove_revision(pkgversion) 5335 5336 for idpackage in foundIDs: 5337 5338 dbver = self.retrieveVersion(idpackage) 5339 if (direction == "~"): 5340 myrev = self.entropyTools.dep_get_portage_revision(dbver) 5341 myver = self.entropyTools.remove_revision(dbver) 5342 if myver == pkgversion and pkgrevision <= myrev: 5343 # found 5344 dbpkginfo.add((idpackage, dbver)) 5345 else: 5346 # media-libs/test-1.2* support 5347 if pkgversion[-1] == "*": 5348 if dbver.startswith(pkgversion[:-1]): 5349 dbpkginfo.add((idpackage, dbver)) 5350 elif (matchRevision != None) and (pkgversion == dbver): 5351 dbrev = self.retrieveRevision(idpackage) 5352 if dbrev == matchRevision: 5353 dbpkginfo.add((idpackage, dbver)) 5354 elif (pkgversion == dbver) and (matchRevision == None): 5355 dbpkginfo.add((idpackage, dbver)) 5356 5357 elif (direction.find(">") != -1) or (direction.find("<") != -1): 5358 5359 if not justname: 5360 5361 # remove revision (-r0 if none) 5362 if pkgversion.endswith("r0"): 5363 # remove 5364 self.entropyTools.remove_revision(pkgversion) 5365 5366 for idpackage in foundIDs: 5367 5368 revcmp = 0 5369 tagcmp = 0 5370 if matchRevision != None: 5371 dbrev = self.retrieveRevision(idpackage) 5372 revcmp = cmp(matchRevision, dbrev) 5373 if matchTag != None: 5374 dbtag = self.retrieveVersionTag(idpackage) 5375 tagcmp = cmp(matchTag, dbtag) 5376 dbver = self.retrieveVersion(idpackage) 5377 pkgcmp = self.entropyTools.compare_versions(pkgversion, dbver) 5378 if pkgcmp == None: 5379 import warnings 5380 warnings.warn("WARNING, invalid version string stored in %s: %s <-> %s" % (self.dbname, pkgversion, dbver,)) 5381 continue 5382 if direction == ">": 5383 if pkgcmp < 0: 5384 dbpkginfo.add((idpackage, dbver)) 5385 elif (matchRevision != None) and pkgcmp <= 0 and revcmp < 0: 5386 dbpkginfo.add((idpackage, dbver)) 5387 elif (matchTag != None) and tagcmp < 0: 5388 dbpkginfo.add((idpackage, dbver)) 5389 elif direction == "<": 5390 if pkgcmp > 0: 5391 dbpkginfo.add((idpackage, dbver)) 5392 elif (matchRevision != None) and pkgcmp >= 0 and revcmp > 0: 5393 dbpkginfo.add((idpackage, dbver)) 5394 elif (matchTag != None) and tagcmp > 0: 5395 dbpkginfo.add((idpackage, dbver)) 5396 elif direction == ">=": 5397 if (matchRevision != None) and pkgcmp <= 0: 5398 if pkgcmp == 0: 5399 if revcmp <= 0: 5400 dbpkginfo.add((idpackage, dbver)) 5401 else: 5402 dbpkginfo.add((idpackage, dbver)) 5403 elif pkgcmp <= 0 and matchRevision == None: 5404 dbpkginfo.add((idpackage, dbver)) 5405 elif (matchTag != None) and tagcmp <= 0: 5406 dbpkginfo.add((idpackage, dbver)) 5407 elif direction == "<=": 5408 if (matchRevision != None) and pkgcmp >= 0: 5409 if pkgcmp == 0: 5410 if revcmp >= 0: 5411 dbpkginfo.add((idpackage, dbver)) 5412 else: 5413 dbpkginfo.add((idpackage, dbver)) 5414 elif pkgcmp >= 0 and matchRevision == None: 5415 dbpkginfo.add((idpackage, dbver)) 5416 elif (matchTag != None) and tagcmp >= 0: 5417 dbpkginfo.add((idpackage, dbver)) 5418 5419 else: # just the key 5420 5421 dbpkginfo = set([(x, self.retrieveVersion(x),) for x in foundIDs]) 5422 5423 return dbpkginfo
5424