Home | History | Annotate | Download | only in Workspace
      1 ## @file

      2 # This file is used to create/update/query/erase a meta file table

      3 #

      4 # Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>

      5 # This program and the accompanying materials

      6 # are licensed and made available under the terms and conditions of the BSD License

      7 # which accompanies this distribution.  The full text of the license may be found at

      8 # http://opensource.org/licenses/bsd-license.php

      9 #

     10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

     11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

     12 #

     13 
     14 ##

     15 # Import Modules

     16 #

     17 import uuid
     18 
     19 import Common.EdkLogger as EdkLogger
     20 from Common.BuildToolError import FORMAT_INVALID
     21 
     22 from MetaDataTable import Table, TableFile
     23 from MetaDataTable import ConvertToSqlString
     24 from CommonDataClass.DataClass import MODEL_FILE_DSC, MODEL_FILE_DEC, MODEL_FILE_INF, \
     25                                       MODEL_FILE_OTHERS
     26 
     27 class MetaFileTable(Table):
     28     # TRICK: use file ID as the part before '.'

     29     _ID_STEP_ = 0.00000001
     30     _ID_MAX_ = 0.99999999
     31 
     32     ## Constructor

     33     def __init__(self, Cursor, MetaFile, FileType, Temporary):
     34         self.MetaFile = MetaFile
     35 
     36         self._FileIndexTable = TableFile(Cursor)
     37         self._FileIndexTable.Create(False)
     38 
     39         FileId = self._FileIndexTable.GetFileId(MetaFile)
     40         if not FileId:
     41             FileId = self._FileIndexTable.InsertFile(MetaFile, FileType)
     42 
     43         if Temporary:
     44             TableName = "_%s_%s_%s" % (FileType, FileId, uuid.uuid4().hex)
     45         else:
     46             TableName = "_%s_%s" % (FileType, FileId)
     47 
     48         #Table.__init__(self, Cursor, TableName, FileId, False)

     49         Table.__init__(self, Cursor, TableName, FileId, Temporary)
     50         self.Create(not self.IsIntegrity())
     51 
     52     def IsIntegrity(self):
     53         try:
     54             TimeStamp = self.MetaFile.TimeStamp
     55             Result = self.Cur.execute("select ID from %s where ID<0" % (self.Table)).fetchall()
     56             if not Result:
     57                 # update the timestamp in database

     58                 self._FileIndexTable.SetFileTimeStamp(self.IdBase, TimeStamp)                
     59                 return False
     60 
     61             if TimeStamp != self._FileIndexTable.GetFileTimeStamp(self.IdBase):
     62                 # update the timestamp in database

     63                 self._FileIndexTable.SetFileTimeStamp(self.IdBase, TimeStamp)
     64                 return False
     65         except Exception, Exc:
     66             EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc))
     67             return False
     68         return True
     69 
     70 ## Python class representation of table storing module data

     71 class ModuleTable(MetaFileTable):
     72     _ID_STEP_ = 0.00000001
     73     _ID_MAX_  = 0.99999999
     74     _COLUMN_ = '''
     75         ID REAL PRIMARY KEY,
     76         Model INTEGER NOT NULL,
     77         Value1 TEXT NOT NULL,
     78         Value2 TEXT,
     79         Value3 TEXT,
     80         Scope1 TEXT,
     81         Scope2 TEXT,
     82         BelongsToItem REAL NOT NULL,
     83         StartLine INTEGER NOT NULL,
     84         StartColumn INTEGER NOT NULL,
     85         EndLine INTEGER NOT NULL,
     86         EndColumn INTEGER NOT NULL,
     87         Enabled INTEGER DEFAULT 0
     88         '''
     89     # used as table end flag, in case the changes to database is not committed to db file

     90     _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1"
     91 
     92     ## Constructor

     93     def __init__(self, Cursor, MetaFile, Temporary):
     94         MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_INF, Temporary)
     95 
     96     ## Insert a record into table Inf

     97     #

     98     # @param Model:          Model of a Inf item

     99     # @param Value1:         Value1 of a Inf item

    100     # @param Value2:         Value2 of a Inf item

    101     # @param Value3:         Value3 of a Inf item

    102     # @param Scope1:         Arch of a Inf item

    103     # @param Scope2          Platform os a Inf item

    104     # @param BelongsToItem:  The item belongs to which another item

    105     # @param StartLine:      StartLine of a Inf item

    106     # @param StartColumn:    StartColumn of a Inf item

    107     # @param EndLine:        EndLine of a Inf item

    108     # @param EndColumn:      EndColumn of a Inf item

    109     # @param Enabled:        If this item enabled

    110     #

    111     def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON',
    112                BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):
    113         (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2))
    114         return Table.Insert(
    115                         self, 
    116                         Model, 
    117                         Value1, 
    118                         Value2, 
    119                         Value3, 
    120                         Scope1, 
    121                         Scope2,
    122                         BelongsToItem, 
    123                         StartLine, 
    124                         StartColumn, 
    125                         EndLine, 
    126                         EndColumn, 
    127                         Enabled
    128                         )
    129 
    130     ## Query table

    131     #

    132     # @param    Model:      The Model of Record 

    133     # @param    Arch:       The Arch attribute of Record 

    134     # @param    Platform    The Platform attribute of Record 

    135     #

    136     # @retval:       A recordSet of all found records 

    137     #

    138     def Query(self, Model, Arch=None, Platform=None, BelongsToItem=None):
    139         ConditionString = "Model=%s AND Enabled>=0" % Model
    140         ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"
    141 
    142         if Arch != None and Arch != 'COMMON':
    143             ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch
    144         if Platform != None and Platform != 'COMMON':
    145             ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Platform
    146         if BelongsToItem != None:
    147             ConditionString += " AND BelongsToItem=%s" % BelongsToItem
    148 
    149         SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)
    150         return self.Exec(SqlCommand)
    151 
    152 ## Python class representation of table storing package data

    153 class PackageTable(MetaFileTable):
    154     _COLUMN_ = '''
    155         ID REAL PRIMARY KEY,
    156         Model INTEGER NOT NULL,
    157         Value1 TEXT NOT NULL,
    158         Value2 TEXT,
    159         Value3 TEXT,
    160         Scope1 TEXT,
    161         Scope2 TEXT,
    162         BelongsToItem REAL NOT NULL,
    163         StartLine INTEGER NOT NULL,
    164         StartColumn INTEGER NOT NULL,
    165         EndLine INTEGER NOT NULL,
    166         EndColumn INTEGER NOT NULL,
    167         Enabled INTEGER DEFAULT 0
    168         '''
    169     # used as table end flag, in case the changes to database is not committed to db file

    170     _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1"
    171 
    172     ## Constructor

    173     def __init__(self, Cursor, MetaFile, Temporary):
    174         MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DEC, Temporary)
    175 
    176     ## Insert table

    177     #

    178     # Insert a record into table Dec

    179     #

    180     # @param Model:          Model of a Dec item

    181     # @param Value1:         Value1 of a Dec item

    182     # @param Value2:         Value2 of a Dec item

    183     # @param Value3:         Value3 of a Dec item

    184     # @param Scope1:         Arch of a Dec item

    185     # @param Scope2:         Module type of a Dec item

    186     # @param BelongsToItem:  The item belongs to which another item

    187     # @param StartLine:      StartLine of a Dec item

    188     # @param StartColumn:    StartColumn of a Dec item

    189     # @param EndLine:        EndLine of a Dec item

    190     # @param EndColumn:      EndColumn of a Dec item

    191     # @param Enabled:        If this item enabled

    192     #

    193     def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON',
    194                BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):
    195         (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2))
    196         return Table.Insert(
    197                         self, 
    198                         Model, 
    199                         Value1, 
    200                         Value2, 
    201                         Value3, 
    202                         Scope1, 
    203                         Scope2,
    204                         BelongsToItem, 
    205                         StartLine, 
    206                         StartColumn, 
    207                         EndLine, 
    208                         EndColumn, 
    209                         Enabled
    210                         )
    211 
    212     ## Query table

    213     #

    214     # @param    Model:  The Model of Record 

    215     # @param    Arch:   The Arch attribute of Record 

    216     #

    217     # @retval:       A recordSet of all found records 

    218     #

    219     def Query(self, Model, Arch=None):
    220         ConditionString = "Model=%s AND Enabled>=0" % Model
    221         ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"
    222 
    223         if Arch != None and Arch != 'COMMON':
    224             ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch
    225 
    226         SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)
    227         return self.Exec(SqlCommand)
    228 
    229     def GetValidExpression(self, TokenSpaceGuid, PcdCName):
    230         SqlCommand = "select Value1,StartLine from %s WHERE Value2='%s' and Value3='%s'" % (self.Table, TokenSpaceGuid, PcdCName)
    231         self.Cur.execute(SqlCommand)
    232         validateranges = []
    233         validlists = []
    234         expressions = []
    235         try:
    236             for row in self.Cur:
    237                 comment = row[0]
    238                 
    239                 LineNum = row[1]
    240                 comment = comment.strip("#")
    241                 comment = comment.strip()
    242                 oricomment = comment
    243                 if comment.startswith("@ValidRange"):
    244                     comment = comment.replace("@ValidRange", "", 1)
    245                     validateranges.append(comment.split("|")[1].strip())
    246                 if comment.startswith("@ValidList"):
    247                     comment = comment.replace("@ValidList", "", 1)
    248                     validlists.append(comment.split("|")[1].strip())
    249                 if comment.startswith("@Expression"):
    250                     comment = comment.replace("@Expression", "", 1)
    251                     expressions.append(comment.split("|")[1].strip())
    252         except Exception, Exc:
    253             ValidType = ""
    254             if oricomment.startswith("@ValidRange"):
    255                 ValidType = "@ValidRange"
    256             if oricomment.startswith("@ValidList"):
    257                 ValidType = "@ValidList"
    258             if oricomment.startswith("@Expression"):
    259                 ValidType = "@Expression"
    260             EdkLogger.error('Parser', FORMAT_INVALID, "The syntax for %s of PCD %s.%s is incorrect" % (ValidType,TokenSpaceGuid, PcdCName),
    261                             ExtraData=oricomment,File=self.MetaFile, Line=LineNum)
    262             return set(), set(), set()
    263         return set(validateranges), set(validlists), set(expressions)
    264 ## Python class representation of table storing platform data

    265 class PlatformTable(MetaFileTable):
    266     _COLUMN_ = '''
    267         ID REAL PRIMARY KEY,
    268         Model INTEGER NOT NULL,
    269         Value1 TEXT NOT NULL,
    270         Value2 TEXT,
    271         Value3 TEXT,
    272         Scope1 TEXT,
    273         Scope2 TEXT,
    274         BelongsToItem REAL NOT NULL,
    275         FromItem REAL NOT NULL,
    276         StartLine INTEGER NOT NULL,
    277         StartColumn INTEGER NOT NULL,
    278         EndLine INTEGER NOT NULL,
    279         EndColumn INTEGER NOT NULL,
    280         Enabled INTEGER DEFAULT 0
    281         '''
    282     # used as table end flag, in case the changes to database is not committed to db file

    283     _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1, -1"
    284 
    285     ## Constructor

    286     def __init__(self, Cursor, MetaFile, Temporary):
    287         MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DSC, Temporary)
    288 
    289     ## Insert table

    290     #

    291     # Insert a record into table Dsc

    292     #

    293     # @param Model:          Model of a Dsc item

    294     # @param Value1:         Value1 of a Dsc item

    295     # @param Value2:         Value2 of a Dsc item

    296     # @param Value3:         Value3 of a Dsc item

    297     # @param Scope1:         Arch of a Dsc item

    298     # @param Scope2:         Module type of a Dsc item

    299     # @param BelongsToItem:  The item belongs to which another item

    300     # @param FromItem:       The item belongs to which dsc file

    301     # @param StartLine:      StartLine of a Dsc item

    302     # @param StartColumn:    StartColumn of a Dsc item

    303     # @param EndLine:        EndLine of a Dsc item

    304     # @param EndColumn:      EndColumn of a Dsc item

    305     # @param Enabled:        If this item enabled

    306     #

    307     def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON', BelongsToItem=-1, 
    308                FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1):
    309         (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2))
    310         return Table.Insert(
    311                         self, 
    312                         Model, 
    313                         Value1, 
    314                         Value2, 
    315                         Value3, 
    316                         Scope1, 
    317                         Scope2,
    318                         BelongsToItem, 
    319                         FromItem,
    320                         StartLine, 
    321                         StartColumn, 
    322                         EndLine, 
    323                         EndColumn, 
    324                         Enabled
    325                         )
    326 
    327     ## Query table

    328     #

    329     # @param Model:          The Model of Record 

    330     # @param Scope1:         Arch of a Dsc item

    331     # @param Scope2:         Module type of a Dsc item

    332     # @param BelongsToItem:  The item belongs to which another item

    333     # @param FromItem:       The item belongs to which dsc file

    334     #

    335     # @retval:       A recordSet of all found records 

    336     #

    337     def Query(self, Model, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None):
    338         ConditionString = "Model=%s AND Enabled>0" % Model
    339         ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"
    340 
    341         if Scope1 != None and Scope1 != 'COMMON':
    342             ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Scope1
    343         if Scope2 != None and Scope2 != 'COMMON':
    344             # Cover the case that CodeBase is 'COMMON' for BuildOptions section

    345             if '.' in Scope2:
    346                 Index = Scope2.index('.')
    347                 NewScope = 'COMMON'+ Scope2[Index:]
    348                 ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT' OR Scope2='%s')" % (Scope2, NewScope)
    349             else:
    350                 ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Scope2
    351 
    352         if BelongsToItem != None:
    353             ConditionString += " AND BelongsToItem=%s" % BelongsToItem
    354         else:
    355             ConditionString += " AND BelongsToItem<0"
    356 
    357         if FromItem != None:
    358             ConditionString += " AND FromItem=%s" % FromItem
    359 
    360         SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)
    361         return self.Exec(SqlCommand)
    362 
    363 ## Factory class to produce different storage for different type of meta-file

    364 class MetaFileStorage(object):
    365     _FILE_TABLE_ = {
    366         MODEL_FILE_INF      :   ModuleTable,
    367         MODEL_FILE_DEC      :   PackageTable,
    368         MODEL_FILE_DSC      :   PlatformTable,
    369         MODEL_FILE_OTHERS   :   MetaFileTable,
    370     }
    371 
    372     _FILE_TYPE_ = {
    373         ".inf"  : MODEL_FILE_INF,
    374         ".dec"  : MODEL_FILE_DEC,
    375         ".dsc"  : MODEL_FILE_DSC,
    376     }
    377 
    378     ## Constructor

    379     def __new__(Class, Cursor, MetaFile, FileType=None, Temporary=False):
    380         # no type given, try to find one

    381         if not FileType:
    382             if MetaFile.Type in self._FILE_TYPE_:
    383                 FileType = Class._FILE_TYPE_[MetaFile.Type]
    384             else:
    385                 FileType = MODEL_FILE_OTHERS
    386 
    387         # don't pass the type around if it's well known

    388         if FileType == MODEL_FILE_OTHERS:
    389             Args = (Cursor, MetaFile, FileType, Temporary)
    390         else:
    391             Args = (Cursor, MetaFile, Temporary)
    392 
    393         # create the storage object and return it to caller

    394         return Class._FILE_TABLE_[FileType](*Args)
    395 
    396