X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FWorkspace%2FMetaFileTable.py;h=e0a0b8d923517388871eed61cde6dc12997d1c5b;hp=22e2afa4c929504f7b2444465d2c32f2486f74a8;hb=1100bc5aa05097306cdecc4d0118cc312da79d45;hpb=30fdf1140b8d1ce93f3821d986fa165552023440 diff --git a/BaseTools/Source/Python/Workspace/MetaFileTable.py b/BaseTools/Source/Python/Workspace/MetaFileTable.py index 22e2afa4c9..e0a0b8d923 100644 --- a/BaseTools/Source/Python/Workspace/MetaFileTable.py +++ b/BaseTools/Source/Python/Workspace/MetaFileTable.py @@ -1,8 +1,8 @@ ## @file # This file is used to create/update/query/erase a meta file table # -# Copyright (c) 2008, Intel Corporation -# All rights reserved. This program and the accompanying materials +# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
+# This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at # http://opensource.org/licenses/bsd-license.php @@ -14,13 +14,63 @@ ## # Import Modules # +from __future__ import absolute_import +import uuid + import Common.EdkLogger as EdkLogger -from MetaDataTable import Table -from MetaDataTable import ConvertToSqlString +from Common.BuildToolError import FORMAT_INVALID -## Python class representation of table storing module data -class ModuleTable(Table): +from .MetaDataTable import Table, TableFile +from .MetaDataTable import ConvertToSqlString +from CommonDataClass.DataClass import MODEL_FILE_DSC, MODEL_FILE_DEC, MODEL_FILE_INF, \ + MODEL_FILE_OTHERS +from Common.DataType import * + +class MetaFileTable(Table): # TRICK: use file ID as the part before '.' + _ID_STEP_ = 0.00000001 + _ID_MAX_ = 0.99999999 + + ## Constructor + def __init__(self, Cursor, MetaFile, FileType, Temporary, FromItem=None): + self.MetaFile = MetaFile + + self._FileIndexTable = TableFile(Cursor) + self._FileIndexTable.Create(False) + + FileId = self._FileIndexTable.GetFileId(MetaFile, FromItem) + if not FileId: + FileId = self._FileIndexTable.InsertFile(MetaFile, FileType, FromItem) + + if Temporary: + TableName = "_%s_%s_%s" % (FileType, FileId, uuid.uuid4().hex) + else: + TableName = "_%s_%s" % (FileType, FileId) + + #Table.__init__(self, Cursor, TableName, FileId, False) + Table.__init__(self, Cursor, TableName, FileId, Temporary) + self.Create(not self.IsIntegrity()) + + def IsIntegrity(self): + try: + TimeStamp = self.MetaFile.TimeStamp + Result = self.Cur.execute("select ID from %s where ID<0" % (self.Table)).fetchall() + if not Result: + # update the timestamp in database + self._FileIndexTable.SetFileTimeStamp(self.IdBase, TimeStamp) + return False + + if TimeStamp != self._FileIndexTable.GetFileTimeStamp(self.IdBase): + # update the timestamp in database + self._FileIndexTable.SetFileTimeStamp(self.IdBase, TimeStamp) + return False + except Exception as Exc: + EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc)) + return False + return True + +## Python class representation of table storing module data +class ModuleTable(MetaFileTable): _ID_STEP_ = 0.00000001 _ID_MAX_ = 0.99999999 _COLUMN_ = ''' @@ -42,8 +92,8 @@ class ModuleTable(Table): _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1" ## Constructor - def __init__(self, Cursor, Name='Inf', IdBase=0, Temporary=False): - Table.__init__(self, Cursor, Name, IdBase, Temporary) + def __init__(self, Cursor, MetaFile, Temporary): + MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_INF, Temporary) ## Insert a record into table Inf # @@ -60,49 +110,49 @@ class ModuleTable(Table): # @param EndColumn: EndColumn of a Inf item # @param Enabled: If this item enabled # - def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON', + def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON, BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0): (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2)) return Table.Insert( - self, - Model, - Value1, - Value2, - Value3, - Scope1, + self, + Model, + Value1, + Value2, + Value3, + Scope1, Scope2, - BelongsToItem, - StartLine, - StartColumn, - EndLine, - EndColumn, + BelongsToItem, + StartLine, + StartColumn, + EndLine, + EndColumn, Enabled ) ## Query table # - # @param Model: The Model of Record - # @param Arch: The Arch attribute of Record - # @param Platform The Platform attribute of Record + # @param Model: The Model of Record + # @param Arch: The Arch attribute of Record + # @param Platform The Platform attribute of Record # - # @retval: A recordSet of all found records + # @retval: A recordSet of all found records # - def Query(self, Model, Arch=None, Platform=None): + def Query(self, Model, Arch=None, Platform=None, BelongsToItem=None): ConditionString = "Model=%s AND Enabled>=0" % Model ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine" - if Arch != None and Arch != 'COMMON': + if Arch is not None and Arch != TAB_ARCH_COMMON: ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch - if Platform != None and Platform != 'COMMON': + if Platform is not None and Platform != TAB_COMMON: ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Platform + if BelongsToItem is not None: + ConditionString += " AND BelongsToItem=%s" % BelongsToItem SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString) return self.Exec(SqlCommand) ## Python class representation of table storing package data -class PackageTable(Table): - _ID_STEP_ = 0.00000001 - _ID_MAX_ = 0.99999999 +class PackageTable(MetaFileTable): _COLUMN_ = ''' ID REAL PRIMARY KEY, Model INTEGER NOT NULL, @@ -122,8 +172,8 @@ class PackageTable(Table): _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1" ## Constructor - def __init__(self, Cursor, Name='Dec', IdBase=0, Temporary=False): - Table.__init__(self, Cursor, Name, IdBase, Temporary) + def __init__(self, Cursor, MetaFile, Temporary): + MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DEC, Temporary) ## Insert table # @@ -142,46 +192,79 @@ class PackageTable(Table): # @param EndColumn: EndColumn of a Dec item # @param Enabled: If this item enabled # - def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON', + def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON, BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0): (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2)) return Table.Insert( - self, - Model, - Value1, - Value2, - Value3, - Scope1, + self, + Model, + Value1, + Value2, + Value3, + Scope1, Scope2, - BelongsToItem, - StartLine, - StartColumn, - EndLine, - EndColumn, + BelongsToItem, + StartLine, + StartColumn, + EndLine, + EndColumn, Enabled ) ## Query table # - # @param Model: The Model of Record - # @param Arch: The Arch attribute of Record + # @param Model: The Model of Record + # @param Arch: The Arch attribute of Record # - # @retval: A recordSet of all found records + # @retval: A recordSet of all found records # def Query(self, Model, Arch=None): ConditionString = "Model=%s AND Enabled>=0" % Model - ValueString = "Value1,Value2,Value3,Scope1,ID,StartLine" + ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine" - if Arch != None and Arch != 'COMMON': + if Arch is not None and Arch != TAB_ARCH_COMMON: ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString) return self.Exec(SqlCommand) + def GetValidExpression(self, TokenSpaceGuid, PcdCName): + SqlCommand = "select Value1,StartLine from %s WHERE Value2='%s' and Value3='%s'" % (self.Table, TokenSpaceGuid, PcdCName) + self.Cur.execute(SqlCommand) + validateranges = [] + validlists = [] + expressions = [] + try: + for row in self.Cur: + comment = row[0] + + LineNum = row[1] + comment = comment.strip("#") + comment = comment.strip() + oricomment = comment + if comment.startswith("@ValidRange"): + comment = comment.replace("@ValidRange", "", 1) + validateranges.append(comment.split("|")[1].strip()) + if comment.startswith("@ValidList"): + comment = comment.replace("@ValidList", "", 1) + validlists.append(comment.split("|")[1].strip()) + if comment.startswith("@Expression"): + comment = comment.replace("@Expression", "", 1) + expressions.append(comment.split("|")[1].strip()) + except Exception as Exc: + ValidType = "" + if oricomment.startswith("@ValidRange"): + ValidType = "@ValidRange" + if oricomment.startswith("@ValidList"): + ValidType = "@ValidList" + if oricomment.startswith("@Expression"): + ValidType = "@Expression" + EdkLogger.error('Parser', FORMAT_INVALID, "The syntax for %s of PCD %s.%s is incorrect" % (ValidType, TokenSpaceGuid, PcdCName), + ExtraData=oricomment, File=self.MetaFile, Line=LineNum) + return set(), set(), set() + return set(validateranges), set(validlists), set(expressions) ## Python class representation of table storing platform data -class PlatformTable(Table): - _ID_STEP_ = 0.00000001 - _ID_MAX_ = 0.99999999 +class PlatformTable(MetaFileTable): _COLUMN_ = ''' ID REAL PRIMARY KEY, Model INTEGER NOT NULL, @@ -190,6 +273,7 @@ class PlatformTable(Table): Value3 TEXT, Scope1 TEXT, Scope2 TEXT, + Scope3 TEXT, BelongsToItem REAL NOT NULL, FromItem REAL NOT NULL, StartLine INTEGER NOT NULL, @@ -199,11 +283,11 @@ class PlatformTable(Table): Enabled INTEGER DEFAULT 0 ''' # used as table end flag, in case the changes to database is not committed to db file - _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1, -1" + _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====','====', -1, -1, -1, -1, -1, -1, -1" ## Constructor - def __init__(self, Cursor, Name='Dsc', IdBase=0, Temporary=False): - Table.__init__(self, Cursor, Name, IdBase, Temporary) + def __init__(self, Cursor, MetaFile, Temporary, FromItem=0): + MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DSC, Temporary, FromItem) ## Insert table # @@ -223,53 +307,95 @@ class PlatformTable(Table): # @param EndColumn: EndColumn of a Dsc item # @param Enabled: If this item enabled # - def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON', BelongsToItem=-1, + def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON, Scope3=TAB_DEFAULT_STORES_DEFAULT,BelongsToItem=-1, FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1): - (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2)) + (Value1, Value2, Value3, Scope1, Scope2, Scope3) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2, Scope3)) return Table.Insert( - self, - Model, - Value1, - Value2, - Value3, - Scope1, + self, + Model, + Value1, + Value2, + Value3, + Scope1, Scope2, - BelongsToItem, + Scope3, + BelongsToItem, FromItem, - StartLine, - StartColumn, - EndLine, - EndColumn, + StartLine, + StartColumn, + EndLine, + EndColumn, Enabled ) ## Query table # - # @param Model: The Model of Record + # @param Model: The Model of Record # @param Scope1: Arch of a Dsc item # @param Scope2: Module type of a Dsc item # @param BelongsToItem: The item belongs to which another item # @param FromItem: The item belongs to which dsc file # - # @retval: A recordSet of all found records + # @retval: A recordSet of all found records # def Query(self, Model, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None): - ConditionString = "Model=%s AND Enabled>=0" % Model - ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine" + ConditionString = "Model=%s AND Enabled>0" % Model + ValueString = "Value1,Value2,Value3,Scope1,Scope2,Scope3,ID,StartLine" - if Scope1 != None and Scope1 != 'COMMON': + if Scope1 is not None and Scope1 != TAB_ARCH_COMMON: ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Scope1 - if Scope2 != None and Scope2 != 'COMMON': - ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Scope2 + if Scope2 is not None and Scope2 != TAB_COMMON: + # Cover the case that CodeBase is 'COMMON' for BuildOptions section + if '.' in Scope2: + Index = Scope2.index('.') + NewScope = TAB_COMMON + Scope2[Index:] + ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT' OR Scope2='%s')" % (Scope2, NewScope) + else: + ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Scope2 - if BelongsToItem != None: + if BelongsToItem is not None: ConditionString += " AND BelongsToItem=%s" % BelongsToItem else: ConditionString += " AND BelongsToItem<0" - if FromItem != None: + if FromItem is not None: ConditionString += " AND FromItem=%s" % FromItem SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString) return self.Exec(SqlCommand) +## Factory class to produce different storage for different type of meta-file +class MetaFileStorage(object): + _FILE_TABLE_ = { + MODEL_FILE_INF : ModuleTable, + MODEL_FILE_DEC : PackageTable, + MODEL_FILE_DSC : PlatformTable, + MODEL_FILE_OTHERS : MetaFileTable, + } + + _FILE_TYPE_ = { + ".inf" : MODEL_FILE_INF, + ".dec" : MODEL_FILE_DEC, + ".dsc" : MODEL_FILE_DSC, + } + + ## Constructor + def __new__(Class, Cursor, MetaFile, FileType=None, Temporary=False, FromItem=None): + # no type given, try to find one + if not FileType: + if MetaFile.Type in self._FILE_TYPE_: + FileType = Class._FILE_TYPE_[MetaFile.Type] + else: + FileType = MODEL_FILE_OTHERS + + # don't pass the type around if it's well known + if FileType == MODEL_FILE_OTHERS: + Args = (Cursor, MetaFile, FileType, Temporary) + else: + Args = (Cursor, MetaFile, Temporary) + if FromItem: + Args = Args + (FromItem,) + + # create the storage object and return it to caller + return Class._FILE_TABLE_[FileType](*Args) +