1## @file
2# This file is for installed package information database operations
3#
4# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
5#
6# This program and the accompanying materials are licensed and made available
7# under the terms and conditions of the BSD License which accompanies this
8# distribution. The full text of the license may be found at
9# http://opensource.org/licenses/bsd-license.php
10#
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13#
14
15'''
16IpiDb
17'''
18
19##
20# Import Modules
21#
22import sqlite3
23import os.path
24import time
25
26import Logger.Log as Logger
27from Logger import StringTable as ST
28from Logger.ToolError import UPT_ALREADY_RUNNING_ERROR
29from Logger.ToolError import UPT_DB_UPDATE_ERROR
30import platform as pf
31
32## IpiDb
33#
34# This class represents the installed package information database
35# Add/Remove/Get installed distribution package information here.
36#
37#
38# @param object:      Inherited from object class
39# @param DbPath:      A string for the path of the database
40#
41#
42class IpiDatabase(object):
43    def __init__(self, DbPath, Workspace):
44        Dir = os.path.dirname(DbPath)
45        if not os.path.isdir(Dir):
46            os.mkdir(Dir)
47        self.Conn = sqlite3.connect(DbPath, isolation_level='DEFERRED')
48        self.Conn.execute("PRAGMA page_size=4096")
49        self.Conn.execute("PRAGMA synchronous=OFF")
50        self.Cur = self.Conn.cursor()
51        self.DpTable = 'DpInfo'
52        self.PkgTable = 'PkgInfo'
53        self.ModInPkgTable = 'ModInPkgInfo'
54        self.StandaloneModTable = 'StandaloneModInfo'
55        self.ModDepexTable = 'ModDepexInfo'
56        self.DpFileListTable = 'DpFileListInfo'
57        self.DummyTable = 'Dummy'
58        self.Workspace = os.path.normpath(Workspace)
59
60    ## Initialize build database
61    #
62    #
63    def InitDatabase(self, SkipLock = False):
64        Logger.Verbose(ST.MSG_INIT_IPI_START)
65        if not SkipLock:
66            try:
67                #
68                # Create a dummy table, if already existed,
69                # then UPT is already running
70                #
71                SqlCommand = """
72                create table %s (
73                Dummy TEXT NOT NULL,
74                PRIMARY KEY (Dummy)
75                )""" % self.DummyTable
76                self.Cur.execute(SqlCommand)
77                self.Conn.commit()
78            except sqlite3.OperationalError:
79                Logger.Error("UPT",
80                             UPT_ALREADY_RUNNING_ERROR,
81                             ST.ERR_UPT_ALREADY_RUNNING_ERROR
82                             )
83
84        #
85        # Create new table
86        #
87        SqlCommand = """
88        create table IF NOT EXISTS %s (
89        DpGuid TEXT NOT NULL,DpVersion TEXT NOT NULL,
90        InstallTime REAL NOT NULL,
91        NewPkgFileName TEXT NOT NULL,
92        PkgFileName TEXT NOT NULL,
93        RePackage TEXT NOT NULL,
94        PRIMARY KEY (DpGuid, DpVersion)
95        )""" % self.DpTable
96        self.Cur.execute(SqlCommand)
97
98        SqlCommand = """
99        create table IF NOT EXISTS %s (
100        FilePath TEXT NOT NULL,
101        DpGuid TEXT,
102        DpVersion TEXT,
103        Md5Sum TEXT,
104        PRIMARY KEY (FilePath)
105        )""" % self.DpFileListTable
106        self.Cur.execute(SqlCommand)
107
108        SqlCommand = """
109        create table IF NOT EXISTS %s (
110        PackageGuid TEXT NOT NULL,
111        PackageVersion TEXT NOT NULL,
112        InstallTime REAL NOT NULL,
113        DpGuid TEXT,
114        DpVersion TEXT,
115        InstallPath TEXT NOT NULL,
116        PRIMARY KEY (PackageGuid, PackageVersion, InstallPath)
117        )""" % self.PkgTable
118        self.Cur.execute(SqlCommand)
119
120        SqlCommand = """
121        create table IF NOT EXISTS %s (
122        ModuleGuid TEXT NOT NULL,
123        ModuleVersion TEXT NOT NULL,
124        ModuleName TEXT NOT NULL,
125        InstallTime REAL NOT NULL,
126        PackageGuid TEXT,
127        PackageVersion TEXT,
128        InstallPath TEXT NOT NULL,
129        PRIMARY KEY (ModuleGuid, ModuleVersion, ModuleName, InstallPath)
130        )""" % self.ModInPkgTable
131        self.Cur.execute(SqlCommand)
132
133        SqlCommand = """
134        create table IF NOT EXISTS %s (
135        ModuleGuid TEXT NOT NULL,
136        ModuleVersion TEXT NOT NULL,
137        ModuleName TEXT NOT NULL,
138        InstallTime REAL NOT NULL,
139        DpGuid TEXT,
140        DpVersion TEXT,
141        InstallPath TEXT NOT NULL,
142        PRIMARY KEY (ModuleGuid, ModuleVersion, ModuleName, InstallPath)
143        )""" % self.StandaloneModTable
144        self.Cur.execute(SqlCommand)
145
146        SqlCommand = """
147        create table IF NOT EXISTS %s (
148        ModuleGuid TEXT NOT NULL,
149        ModuleVersion TEXT NOT NULL,
150        ModuleName TEXT NOT NULL,
151        InstallPath TEXT NOT NULL,
152        DepexGuid TEXT,
153        DepexVersion TEXT
154        )""" % self.ModDepexTable
155        self.Cur.execute(SqlCommand)
156
157        self.Conn.commit()
158
159        Logger.Verbose(ST.MSG_INIT_IPI_FINISH)
160
161    def RollBack(self):
162        self.Conn.rollback()
163
164    def Commit(self):
165        self.Conn.commit()
166
167    ## Add a distribution install information from DpObj
168    #
169    # @param DpObj:
170    # @param NewDpPkgFileName: New DpPkg File Name
171    # @param DpPkgFileName: DpPkg File Name
172    # @param RePackage: A RePackage
173    #
174    def AddDPObject(self, DpObj, NewDpPkgFileName, DpPkgFileName, RePackage):
175        try:
176            for PkgKey in DpObj.PackageSurfaceArea.keys():
177                PkgGuid = PkgKey[0]
178                PkgVersion = PkgKey[1]
179                PkgInstallPath = PkgKey[2]
180                self._AddPackage(PkgGuid, PkgVersion, DpObj.Header.GetGuid(), \
181                                 DpObj.Header.GetVersion(), PkgInstallPath)
182                PkgObj = DpObj.PackageSurfaceArea[PkgKey]
183                for ModKey in PkgObj.GetModuleDict().keys():
184                    ModGuid = ModKey[0]
185                    ModVersion = ModKey[1]
186                    ModName = ModKey[2]
187                    ModInstallPath = ModKey[3]
188                    ModInstallPath = \
189                    os.path.normpath(os.path.join(PkgInstallPath, ModInstallPath))
190                    self._AddModuleInPackage(ModGuid, ModVersion, ModName, PkgGuid, \
191                                             PkgVersion, ModInstallPath)
192                    ModObj = PkgObj.GetModuleDict()[ModKey]
193                    for Dep in ModObj.GetPackageDependencyList():
194                        DepexGuid = Dep.GetGuid()
195                        DepexVersion = Dep.GetVersion()
196                        self._AddModuleDepex(ModGuid, ModVersion, ModName, ModInstallPath, \
197                                             DepexGuid, DepexVersion)
198                for (FilePath, Md5Sum) in PkgObj.FileList:
199                    self._AddDpFilePathList(DpObj.Header.GetGuid(), \
200                                            DpObj.Header.GetVersion(), FilePath, \
201                                            Md5Sum)
202
203            for ModKey in DpObj.ModuleSurfaceArea.keys():
204                ModGuid = ModKey[0]
205                ModVersion = ModKey[1]
206                ModName = ModKey[2]
207                ModInstallPath = ModKey[3]
208                self._AddStandaloneModule(ModGuid, ModVersion, ModName, \
209                                          DpObj.Header.GetGuid(), \
210                                          DpObj.Header.GetVersion(), \
211                                          ModInstallPath)
212                ModObj = DpObj.ModuleSurfaceArea[ModKey]
213                for Dep in ModObj.GetPackageDependencyList():
214                    DepexGuid = Dep.GetGuid()
215                    DepexVersion = Dep.GetVersion()
216                    self._AddModuleDepex(ModGuid, ModVersion, ModName, ModInstallPath, \
217                                         DepexGuid, DepexVersion)
218                for (Path, Md5Sum) in ModObj.FileList:
219                    self._AddDpFilePathList(DpObj.Header.GetGuid(), \
220                                            DpObj.Header.GetVersion(), \
221                                            Path, Md5Sum)
222
223            #
224            # add tool/misc files
225            #
226            for (Path, Md5Sum) in DpObj.FileList:
227                self._AddDpFilePathList(DpObj.Header.GetGuid(), \
228                                        DpObj.Header.GetVersion(), Path, Md5Sum)
229
230            self._AddDp(DpObj.Header.GetGuid(), DpObj.Header.GetVersion(), \
231                        NewDpPkgFileName, DpPkgFileName, RePackage)
232
233        except sqlite3.IntegrityError, DetailMsg:
234            Logger.Error("UPT",
235                         UPT_DB_UPDATE_ERROR,
236                         ST.ERR_UPT_DB_UPDATE_ERROR,
237                         ExtraData = DetailMsg
238                         )
239
240    ## Add a distribution install information
241    #
242    # @param Guid         Guid of the distribution package
243    # @param Version      Version of the distribution package
244    # @param NewDpFileName the saved filename of distribution package file
245    # @param DistributionFileName the filename of distribution package file
246    #
247    def _AddDp(self, Guid, Version, NewDpFileName, DistributionFileName, \
248               RePackage):
249
250        if Version == None or len(Version.strip()) == 0:
251            Version = 'N/A'
252
253        #
254        # Add newly installed DP information to DB.
255        #
256        if NewDpFileName == None or len(NewDpFileName.strip()) == 0:
257            PkgFileName = 'N/A'
258        else:
259            PkgFileName = NewDpFileName
260        CurrentTime = time.time()
261        SqlCommand = \
262        """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % \
263        (self.DpTable, Guid, Version, CurrentTime, PkgFileName, \
264         DistributionFileName, str(RePackage).upper())
265        self.Cur.execute(SqlCommand)
266
267
268    ## Add a file list from DP
269    #
270    # @param DpGuid: A DpGuid
271    # @param DpVersion: A DpVersion
272    # @param Path: A Path
273    # @param Path: A Md5Sum
274    #
275    def _AddDpFilePathList(self, DpGuid, DpVersion, Path, Md5Sum):
276        Path = os.path.normpath(Path)
277        if pf.system() == 'Windows':
278            if Path.startswith(self.Workspace):
279                Path = Path[len(self.Workspace):]
280        else:
281            if Path.startswith(self.Workspace + os.sep):
282                Path = Path[len(self.Workspace)+1:]
283        SqlCommand = """insert into %s values('%s', '%s', '%s', '%s')""" % \
284        (self.DpFileListTable, Path, DpGuid, DpVersion, Md5Sum)
285
286        self.Cur.execute(SqlCommand)
287
288    ## Add a package install information
289    #
290    # @param Guid: A package guid
291    # @param Version: A package version
292    # @param DpGuid: A DpGuid
293    # @param DpVersion: A DpVersion
294    # @param Path: A Path
295    #
296    def _AddPackage(self, Guid, Version, DpGuid=None, DpVersion=None, Path=''):
297
298        if Version == None or len(Version.strip()) == 0:
299            Version = 'N/A'
300
301        if DpGuid == None or len(DpGuid.strip()) == 0:
302            DpGuid = 'N/A'
303
304        if DpVersion == None or len(DpVersion.strip()) == 0:
305            DpVersion = 'N/A'
306
307        #
308        # Add newly installed package information to DB.
309        #
310        CurrentTime = time.time()
311        SqlCommand = \
312        """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % \
313        (self.PkgTable, Guid, Version, CurrentTime, DpGuid, DpVersion, Path)
314        self.Cur.execute(SqlCommand)
315
316    ## Add a module that from a package install information
317    #
318    # @param Guid:    Module Guid
319    # @param Version: Module version
320    # @param Name:    Module Name
321    # @param PkgGuid: Package Guid
322    # @param PkgVersion: Package version
323    # @param Path:    Package relative path that module installs
324    #
325    def _AddModuleInPackage(self, Guid, Version, Name, PkgGuid=None, \
326                            PkgVersion=None, Path=''):
327
328        if Version == None or len(Version.strip()) == 0:
329            Version = 'N/A'
330
331        if PkgGuid == None or len(PkgGuid.strip()) == 0:
332            PkgGuid = 'N/A'
333
334        if PkgVersion == None or len(PkgVersion.strip()) == 0:
335            PkgVersion = 'N/A'
336
337        if os.name == 'posix':
338            Path = Path.replace('\\', os.sep)
339        else:
340            Path = Path.replace('/', os.sep)
341
342        #
343        # Add module from package information to DB.
344        #
345        CurrentTime = time.time()
346        SqlCommand = \
347        """insert into %s values('%s', '%s', '%s', %s, '%s', '%s', '%s')""" % \
348        (self.ModInPkgTable, Guid, Version, Name, CurrentTime, PkgGuid, PkgVersion, \
349         Path)
350        self.Cur.execute(SqlCommand)
351
352    ## Add a module that is standalone install information
353    #
354    # @param Guid: a module Guid
355    # @param Version: a module Version
356    # @param Name: a module name
357    # @param DpGuid: a DpGuid
358    # @param DpVersion: a DpVersion
359    # @param Path: path
360    #
361    def _AddStandaloneModule(self, Guid, Version, Name, DpGuid=None, \
362                             DpVersion=None, Path=''):
363
364        if Version == None or len(Version.strip()) == 0:
365            Version = 'N/A'
366
367        if DpGuid == None or len(DpGuid.strip()) == 0:
368            DpGuid = 'N/A'
369
370        if DpVersion == None or len(DpVersion.strip()) == 0:
371            DpVersion = 'N/A'
372
373        #
374        # Add module standalone information to DB.
375        #
376        CurrentTime = time.time()
377        SqlCommand = \
378        """insert into %s values('%s', '%s', '%s', %s, '%s', '%s', '%s')""" % \
379        (self.StandaloneModTable, Guid, Version, Name, CurrentTime, DpGuid, \
380         DpVersion, Path)
381        self.Cur.execute(SqlCommand)
382
383    ## Add a module depex
384    #
385    # @param Guid: a module Guid
386    # @param Version: a module Version
387    # @param Name: a module name
388    # @param DepexGuid: a module DepexGuid
389    # @param DepexVersion: a module DepexVersion
390    #
391    def _AddModuleDepex(self, Guid, Version, Name, Path, DepexGuid=None, \
392                        DepexVersion=None):
393
394        if DepexGuid == None or len(DepexGuid.strip()) == 0:
395            DepexGuid = 'N/A'
396
397        if DepexVersion == None or len(DepexVersion.strip()) == 0:
398            DepexVersion = 'N/A'
399
400        if os.name == 'posix':
401            Path = Path.replace('\\', os.sep)
402        else:
403            Path = Path.replace('/', os.sep)
404
405        #
406        # Add module depex information to DB.
407        #
408        SqlCommand = """insert into %s values('%s', '%s', '%s', '%s', '%s', '%s')"""\
409         % (self.ModDepexTable, Guid, Version, Name, Path, DepexGuid, DepexVersion)
410        self.Cur.execute(SqlCommand)
411
412    ## Remove a distribution install information, if no version specified,
413    # remove all DPs with this Guid.
414    #
415    # @param DpGuid: guid of dpex
416    # @param DpVersion: version of dpex
417    #
418    def RemoveDpObj(self, DpGuid, DpVersion):
419
420        PkgList = self.GetPackageListFromDp(DpGuid, DpVersion)
421        #
422        # delete from ModDepex the standalone module's dependency
423        #
424        SqlCommand = \
425        """delete from ModDepexInfo where ModDepexInfo.ModuleGuid in
426        (select ModuleGuid from StandaloneModInfo as B where B.DpGuid = '%s'
427        and B.DpVersion = '%s')
428        and ModDepexInfo.ModuleVersion in
429        (select ModuleVersion from StandaloneModInfo as B
430        where B.DpGuid = '%s' and B.DpVersion = '%s')
431        and ModDepexInfo.ModuleName in
432        (select ModuleName from StandaloneModInfo as B
433        where B.DpGuid = '%s' and B.DpVersion = '%s')
434        and ModDepexInfo.InstallPath in
435        (select InstallPath from StandaloneModInfo as B
436        where B.DpGuid = '%s' and B.DpVersion = '%s') """ % \
437        (DpGuid, DpVersion, DpGuid, DpVersion, DpGuid, DpVersion, DpGuid, DpVersion)
438
439        self.Cur.execute(SqlCommand)
440        #
441        # delete from ModDepex the from pkg module's dependency
442        #
443        for Pkg in PkgList:
444
445            SqlCommand = \
446            """delete from ModDepexInfo where ModDepexInfo.ModuleGuid in
447            (select ModuleGuid from ModInPkgInfo
448            where ModInPkgInfo.PackageGuid ='%s' and
449            ModInPkgInfo.PackageVersion = '%s')
450            and ModDepexInfo.ModuleVersion in
451            (select ModuleVersion from ModInPkgInfo
452            where ModInPkgInfo.PackageGuid ='%s' and
453            ModInPkgInfo.PackageVersion = '%s')
454            and ModDepexInfo.ModuleName in
455            (select ModuleName from ModInPkgInfo
456            where ModInPkgInfo.PackageGuid ='%s' and
457            ModInPkgInfo.PackageVersion = '%s')
458            and ModDepexInfo.InstallPath in
459            (select InstallPath from ModInPkgInfo where
460            ModInPkgInfo.PackageGuid ='%s'
461            and ModInPkgInfo.PackageVersion = '%s')""" \
462                            % (Pkg[0], Pkg[1], Pkg[0], Pkg[1], Pkg[0], Pkg[1],Pkg[0], Pkg[1])
463
464            self.Cur.execute(SqlCommand)
465        #
466        # delete the standalone module
467        #
468        SqlCommand = \
469        """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % \
470        (self.StandaloneModTable, DpGuid, DpVersion)
471        self.Cur.execute(SqlCommand)
472        #
473        # delete the from pkg module
474        #
475        for Pkg in PkgList:
476            SqlCommand = \
477            """delete from %s where %s.PackageGuid ='%s'
478            and %s.PackageVersion = '%s'""" % \
479            (self.ModInPkgTable, self.ModInPkgTable, Pkg[0], \
480             self.ModInPkgTable, Pkg[1])
481            self.Cur.execute(SqlCommand)
482        #
483        # delete packages
484        #
485        SqlCommand = \
486        """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % \
487        (self.PkgTable, DpGuid, DpVersion)
488        self.Cur.execute(SqlCommand)
489        #
490        # delete file list from DP
491        #
492        SqlCommand = \
493        """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % \
494        (self.DpFileListTable, DpGuid, DpVersion)
495        self.Cur.execute(SqlCommand)
496        #
497        # delete DP
498        #
499        SqlCommand = \
500        """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % \
501        (self.DpTable, DpGuid, DpVersion)
502        self.Cur.execute(SqlCommand)
503
504        #self.Conn.commit()
505
506    ## Get a list of distribution install information.
507    #
508    # @param Guid: distribution package guid
509    # @param Version: distribution package version
510    #
511    def GetDp(self, Guid, Version):
512
513        if Version == None or len(Version.strip()) == 0:
514            Version = 'N/A'
515            Logger.Verbose(ST.MSG_GET_DP_INSTALL_LIST)
516            (DpGuid, DpVersion) = (Guid, Version)
517            SqlCommand = """select * from %s where DpGuid ='%s'""" % \
518            (self.DpTable, DpGuid)
519            self.Cur.execute(SqlCommand)
520
521        else:
522            Logger.Verbose(ST.MSG_GET_DP_INSTALL_INFO_START)
523            (DpGuid, DpVersion) = (Guid, Version)
524            SqlCommand = \
525            """select * from %s where DpGuid ='%s' and DpVersion = '%s'""" % \
526            (self.DpTable, DpGuid, DpVersion)
527            self.Cur.execute(SqlCommand)
528
529        DpList = []
530        for DpInfo in self.Cur:
531            DpGuid = DpInfo[0]
532            DpVersion = DpInfo[1]
533            InstallTime = DpInfo[2]
534            PkgFileName = DpInfo[3]
535            DpList.append((DpGuid, DpVersion, InstallTime, PkgFileName))
536
537        Logger.Verbose(ST.MSG_GET_DP_INSTALL_INFO_FINISH)
538        return DpList
539
540    ## Get a list of distribution install dirs
541    #
542    # @param Guid: distribution package guid
543    # @param Version: distribution package version
544    #
545    def GetDpInstallDirList(self, Guid, Version):
546        SqlCommand = """select InstallPath from PkgInfo where DpGuid = '%s' and DpVersion = '%s'""" % (Guid, Version)
547        self.Cur.execute(SqlCommand)
548        DirList = []
549        for Result in self.Cur:
550            if Result[0] not in DirList:
551                DirList.append(Result[0])
552
553        SqlCommand = """select InstallPath from StandaloneModInfo where DpGuid = '%s' and DpVersion = '%s'""" % \
554                     (Guid, Version)
555        self.Cur.execute(SqlCommand)
556        for Result in self.Cur:
557            if Result[0] not in DirList:
558                DirList.append(Result[0])
559
560        return DirList
561
562
563    ## Get a list of distribution install file path information.
564    #
565    # @param Guid: distribution package guid
566    # @param Version: distribution package version
567    #
568    def GetDpFileList(self, Guid, Version):
569
570        (DpGuid, DpVersion) = (Guid, Version)
571        SqlCommand = \
572        """select * from %s where DpGuid ='%s' and DpVersion = '%s'""" % \
573        (self.DpFileListTable, DpGuid, DpVersion)
574        self.Cur.execute(SqlCommand)
575
576        PathList = []
577        for Result in self.Cur:
578            Path = Result[0]
579            Md5Sum = Result[3]
580            PathList.append((os.path.join(self.Workspace, Path), Md5Sum))
581
582        return PathList
583
584    ## Get files' repackage attribute if present that are installed into current workspace
585    #
586    # @retval FileDict:  a Dict of file, key is file path, value is (DpGuid, DpVersion, NewDpFileName, RePackage)
587    #
588    def GetRePkgDict(self):
589        SqlCommand = """select * from %s """ % (self.DpTable)
590        self.Cur.execute(SqlCommand)
591
592        DpInfoList = []
593        for Result in self.Cur:
594            DpInfoList.append(Result)
595
596        FileDict = {}
597        for Result in DpInfoList:
598            DpGuid = Result[0]
599            DpVersion = Result[1]
600            NewDpFileName = Result[3]
601            RePackage = Result[5]
602            if RePackage == 'TRUE':
603                RePackage = True
604            else:
605                RePackage = False
606            for FileInfo in self.GetDpFileList(DpGuid, DpVersion):
607                PathInfo = FileInfo[0]
608                FileDict[PathInfo] = DpGuid, DpVersion, NewDpFileName, RePackage
609
610        return FileDict
611
612    ## Get (Guid, Version) from distribution file name information.
613    #
614    # @param DistributionFile: Distribution File
615    #
616    def GetDpByName(self, DistributionFile):
617        SqlCommand = """select * from %s where NewPkgFileName like '%s'""" % \
618        (self.DpTable, '%' + DistributionFile)
619        self.Cur.execute(SqlCommand)
620
621        for Result in self.Cur:
622            DpGuid = Result[0]
623            DpVersion = Result[1]
624            NewDpFileName = Result[3]
625
626            return (DpGuid, DpVersion, NewDpFileName)
627        else:
628            return (None, None, None)
629
630    ## Get a list of package information.
631    #
632    # @param Guid: package guid
633    # @param Version: package version
634    #
635    def GetPackage(self, Guid, Version, DpGuid='', DpVersion=''):
636
637        if DpVersion == '' or DpGuid == '':
638
639            (PackageGuid, PackageVersion) = (Guid, Version)
640            SqlCommand = """select * from %s where PackageGuid ='%s'
641            and PackageVersion = '%s'""" % (self.PkgTable, PackageGuid, \
642                                            PackageVersion)
643            self.Cur.execute(SqlCommand)
644
645        elif Version == None or len(Version.strip()) == 0:
646
647            SqlCommand = """select * from %s where PackageGuid ='%s'""" % \
648            (self.PkgTable, Guid)
649            self.Cur.execute(SqlCommand)
650        else:
651            (PackageGuid, PackageVersion) = (Guid, Version)
652            SqlCommand = """select * from %s where PackageGuid ='%s' and
653            PackageVersion = '%s'
654                            and DpGuid = '%s' and DpVersion = '%s'""" % \
655                            (self.PkgTable, PackageGuid, PackageVersion, \
656                             DpGuid, DpVersion)
657            self.Cur.execute(SqlCommand)
658
659        PkgList = []
660        for PkgInfo in self.Cur:
661            PkgGuid = PkgInfo[0]
662            PkgVersion = PkgInfo[1]
663            InstallTime = PkgInfo[2]
664            InstallPath = PkgInfo[5]
665            PkgList.append((PkgGuid, PkgVersion, InstallTime, DpGuid, \
666                            DpVersion, InstallPath))
667
668        return PkgList
669
670
671    ## Get a list of module in package information.
672    #
673    # @param Guid: A module guid
674    # @param Version: A module version
675    #
676    def GetModInPackage(self, Guid, Version, Name, Path, PkgGuid='', PkgVersion=''):
677        (ModuleGuid, ModuleVersion, ModuleName, InstallPath) = (Guid, Version, Name, Path)
678        if PkgVersion == '' or PkgGuid == '':
679            SqlCommand = """select * from %s where ModuleGuid ='%s' and
680            ModuleVersion = '%s' and InstallPath = '%s'
681            and ModuleName = '%s'""" % (self.ModInPkgTable, ModuleGuid, \
682                                       ModuleVersion, InstallPath, ModuleName)
683            self.Cur.execute(SqlCommand)
684        else:
685            SqlCommand = """select * from %s where ModuleGuid ='%s' and
686            ModuleVersion = '%s' and InstallPath = '%s'
687            and ModuleName = '%s' and PackageGuid ='%s'
688            and PackageVersion = '%s'
689                            """ % (self.ModInPkgTable, ModuleGuid, \
690                                   ModuleVersion, InstallPath, ModuleName, PkgGuid, PkgVersion)
691            self.Cur.execute(SqlCommand)
692
693        ModList = []
694        for ModInfo in self.Cur:
695            ModGuid = ModInfo[0]
696            ModVersion = ModInfo[1]
697            InstallTime = ModInfo[2]
698            InstallPath = ModInfo[5]
699            ModList.append((ModGuid, ModVersion, InstallTime, PkgGuid, \
700                            PkgVersion, InstallPath))
701
702        return ModList
703
704    ## Get a list of module standalone.
705    #
706    # @param Guid: A module guid
707    # @param Version: A module version
708    #
709    def GetStandaloneModule(self, Guid, Version, Name, Path, DpGuid='', DpVersion=''):
710        (ModuleGuid, ModuleVersion, ModuleName, InstallPath) = (Guid, Version, Name, Path)
711        if DpGuid == '':
712            SqlCommand = """select * from %s where ModuleGuid ='%s' and
713            ModuleVersion = '%s' and InstallPath = '%s'
714            and ModuleName = '%s'""" % (self.StandaloneModTable, ModuleGuid, \
715                                       ModuleVersion, InstallPath, ModuleName)
716            self.Cur.execute(SqlCommand)
717
718        else:
719            SqlCommand = """select * from %s where ModuleGuid ='%s' and
720            ModuleVersion = '%s' and InstallPath = '%s' and ModuleName = '%s' and DpGuid ='%s' and DpVersion = '%s'
721                            """ % (self.StandaloneModTable, ModuleGuid, \
722                                   ModuleVersion, ModuleName, InstallPath, DpGuid, DpVersion)
723            self.Cur.execute(SqlCommand)
724
725        ModList = []
726        for ModInfo in self.Cur:
727            ModGuid = ModInfo[0]
728            ModVersion = ModInfo[1]
729            InstallTime = ModInfo[2]
730            InstallPath = ModInfo[5]
731            ModList.append((ModGuid, ModVersion, InstallTime, DpGuid, \
732                            DpVersion, InstallPath))
733
734        return ModList
735
736    ## Get a list of module information that comes from DP.
737    #
738    # @param DpGuid: A Distrabution Guid
739    # @param DpVersion: A Distrabution version
740    #
741    def GetSModInsPathListFromDp(self, DpGuid, DpVersion):
742
743        PathList = []
744        SqlCommand = """select InstallPath from %s where DpGuid ='%s'
745        and DpVersion = '%s'
746                        """ % (self.StandaloneModTable, DpGuid, DpVersion)
747        self.Cur.execute(SqlCommand)
748
749        for Result in self.Cur:
750            InstallPath = Result[0]
751            PathList.append(InstallPath)
752
753        return PathList
754
755    ## Get a list of package information.
756    #
757    # @param DpGuid: A Distrabution Guid
758    # @param DpVersion: A Distrabution version
759    #
760    def GetPackageListFromDp(self, DpGuid, DpVersion):
761
762        SqlCommand = """select * from %s where DpGuid ='%s' and
763        DpVersion = '%s' """ % (self.PkgTable, DpGuid, DpVersion)
764        self.Cur.execute(SqlCommand)
765
766        PkgList = []
767        for PkgInfo in self.Cur:
768            PkgGuid = PkgInfo[0]
769            PkgVersion = PkgInfo[1]
770            InstallPath = PkgInfo[5]
771            PkgList.append((PkgGuid, PkgVersion, InstallPath))
772
773        return PkgList
774
775    ## Get a list of modules that depends on package information from a DP.
776    #
777    # @param DpGuid: A Distrabution Guid
778    # @param DpVersion: A Distrabution version
779    #
780    def GetDpDependentModuleList(self, DpGuid, DpVersion):
781
782        ModList = []
783        PkgList = self.GetPackageListFromDp(DpGuid, DpVersion)
784        if len(PkgList) > 0:
785            return ModList
786
787        for Pkg in PkgList:
788            #
789            # get all in-package modules that depends on current
790            # Pkg (Guid match, Version match or NA) but not belong to
791            # current Pkg
792            #
793            SqlCommand = """select t1.ModuleGuid, t1.ModuleVersion,
794            t1.InstallPath from %s as t1, %s as t2 where
795            t1.ModuleGuid = t2.ModuleGuid and
796            t1.ModuleVersion = t2.ModuleVersion and t2.DepexGuid ='%s'
797            and (t2.DepexVersion = '%s' or t2.DepexVersion = 'N/A') and
798            t1.PackageGuid != '%s' and t1.PackageVersion != '%s'
799                        """ % (self.ModInPkgTable, \
800                               self.ModDepexTable, Pkg[0], Pkg[1], Pkg[0], \
801                               Pkg[1])
802            self.Cur.execute(SqlCommand)
803            for ModInfo in self.Cur:
804                ModGuid = ModInfo[0]
805                ModVersion = ModInfo[1]
806                InstallPath = ModInfo[2]
807                ModList.append((ModGuid, ModVersion, InstallPath))
808
809            #
810            # get all modules from standalone modules that depends on current
811            #Pkg (Guid match, Version match or NA) but not in current dp
812            #
813            SqlCommand = \
814            """select t1.ModuleGuid, t1.ModuleVersion, t1.InstallPath
815            from %s as t1, %s as t2 where t1.ModuleGuid = t2.ModuleGuid and
816            t1.ModuleVersion = t2.ModuleVersion and t2.DepexGuid ='%s'
817            and (t2.DepexVersion = '%s' or t2.DepexVersion = 'N/A') and
818                            t1.DpGuid != '%s' and t1.DpVersion != '%s'
819                        """ % \
820                        (self.StandaloneModTable, self.ModDepexTable, Pkg[0], \
821                         Pkg[1], DpGuid, DpVersion)
822            self.Cur.execute(SqlCommand)
823            for ModInfo in self.Cur:
824                ModGuid = ModInfo[0]
825                ModVersion = ModInfo[1]
826                InstallPath = ModInfo[2]
827                ModList.append((ModGuid, ModVersion, InstallPath))
828
829
830        return ModList
831
832    ## Get Dp's list of modules.
833    #
834    # @param DpGuid: A Distrabution Guid
835    # @param DpVersion: A Distrabution version
836    #
837    def GetDpModuleList(self, DpGuid, DpVersion):
838        ModList = []
839        #
840        # get Dp module list from the DpFileList table
841        #
842        SqlCommand = """select FilePath
843                        from %s
844                        where DpGuid = '%s' and DpVersion = '%s' and
845                        FilePath like '%%.inf'
846                    """ % (self.DpFileListTable, DpGuid, DpVersion)
847        self.Cur.execute(SqlCommand)
848        for ModuleInfo in self.Cur:
849            FilePath = ModuleInfo[0]
850            ModList.append(os.path.join(self.Workspace, FilePath))
851
852        return ModList
853
854
855    ## Get a module depex
856    #
857    # @param DpGuid: A module Guid
858    # @param DpVersion: A module version
859    # @param Path:
860    #
861    def GetModuleDepex(self, Guid, Version, Path):
862
863        #
864        # Get module depex information to DB.
865        #
866        SqlCommand = """select * from %s where ModuleGuid ='%s' and
867        ModuleVersion = '%s' and InstallPath ='%s'
868                            """ % (self.ModDepexTable, Guid, Version, Path)
869        self.Cur.execute(SqlCommand)
870
871
872        DepexList = []
873        for DepInfo in self.Cur:
874            DepexGuid = DepInfo[3]
875            DepexVersion = DepInfo[4]
876            DepexList.append((DepexGuid, DepexVersion))
877
878        return DepexList
879
880    ## Inventory the distribution installed to current workspace
881    #
882    # Inventory the distribution installed to current workspace
883    #
884    def InventoryDistInstalled(self):
885        SqlCommand = """select * from %s """ % (self.DpTable)
886        self.Cur.execute(SqlCommand)
887
888        DpInfoList = []
889        for Result in self.Cur:
890            DpGuid = Result[0]
891            DpVersion = Result[1]
892            DpAliasName = Result[3]
893            DpFileName = Result[4]
894            DpInfoList.append((DpGuid, DpVersion, DpFileName, DpAliasName))
895
896        return DpInfoList
897
898    ## Close entire database
899    #
900    # Close the connection and cursor
901    #
902    def CloseDb(self):
903        #
904        # drop the dummy table
905        #
906        SqlCommand = """
907        drop table IF EXISTS %s
908        """ % self.DummyTable
909        self.Cur.execute(SqlCommand)
910        self.Conn.commit()
911
912        self.Cur.close()
913        self.Conn.close()
914
915    ## Convert To Sql String
916    #
917    # 1. Replace "'" with "''" in each item of StringList
918    #
919    # @param StringList:  A list for strings to be converted
920    #
921    def __ConvertToSqlString(self, StringList):
922        if self.DpTable:
923            pass
924        return map(lambda s: s.replace("'", "''") , StringList)
925
926
927
928