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