]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Workspace/MetaFileTable.py
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / MetaFileTable.py
index 22e2afa4c929504f7b2444465d2c32f2486f74a8..0555c91ccc3ada79c769ce3ba62972aea9295a2a 100644 (file)
@@ -1,28 +1,79 @@
 ## @file\r
 # This file is used to create/update/query/erase a meta file table\r
 #\r
-# Copyright (c) 2008, Intel Corporation\r
-# All rights reserved. This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution.  The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
 \r
 ##\r
 # Import Modules\r
 #\r
+from __future__ import absolute_import\r
+import uuid\r
+\r
 import Common.EdkLogger as EdkLogger\r
-from MetaDataTable import Table\r
-from MetaDataTable import ConvertToSqlString\r
+from Common.BuildToolError import FORMAT_INVALID\r
 \r
-## Python class representation of table storing module data\r
-class ModuleTable(Table):\r
+from CommonDataClass.DataClass import MODEL_FILE_DSC, MODEL_FILE_DEC, MODEL_FILE_INF, \\r
+                                      MODEL_FILE_OTHERS\r
+from Common.DataType import *\r
+\r
+class MetaFileTable():\r
     # TRICK: use file ID as the part before '.'\r
-    _ID_STEP_ = 0.00000001\r
-    _ID_MAX_  = 0.99999999\r
+    _ID_STEP_ = 1\r
+    _ID_MAX_ = 99999999\r
+\r
+    ## Constructor\r
+    def __init__(self, DB, MetaFile, FileType, Temporary, FromItem=None):\r
+        self.MetaFile = MetaFile\r
+        self.TableName = ""\r
+        self.DB = DB\r
+        self._NumpyTab = None\r
+\r
+        self.CurrentContent = []\r
+        DB.TblFile.append([MetaFile.Name,\r
+                        MetaFile.Ext,\r
+                        MetaFile.Dir,\r
+                        MetaFile.Path,\r
+                        FileType,\r
+                        MetaFile.TimeStamp,\r
+                        FromItem])\r
+        self.FileId = len(DB.TblFile)\r
+        self.ID = self.FileId * 10**8\r
+        if Temporary:\r
+            self.TableName = "_%s_%s_%s" % (FileType, len(DB.TblFile), uuid.uuid4().hex)\r
+        else:\r
+            self.TableName = "_%s_%s" % (FileType, len(DB.TblFile))\r
+\r
+    def IsIntegrity(self):\r
+        try:\r
+            TimeStamp = self.MetaFile.TimeStamp\r
+            if not self.CurrentContent:\r
+                Result = False\r
+            else:\r
+                Result = self.CurrentContent[-1][0] < 0\r
+            if not Result:\r
+                # update the timestamp in database\r
+                self.DB.SetFileTimeStamp(self.FileId, TimeStamp)\r
+                return False\r
+\r
+            if TimeStamp != self.DB.GetFileTimeStamp(self.FileId):\r
+                # update the timestamp in database\r
+                self.DB.SetFileTimeStamp(self.FileId, TimeStamp)\r
+                return False\r
+        except Exception as Exc:\r
+            EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc))\r
+            return False\r
+        return True\r
+\r
+    def SetEndFlag(self):\r
+        self.CurrentContent.append(self._DUMMY_)\r
+\r
+    def GetAll(self):\r
+        return [item for item in self.CurrentContent if item[0] >= 0 and item[-1]>=0]\r
+\r
+## Python class representation of table storing module data\r
+class ModuleTable(MetaFileTable):\r
     _COLUMN_ = '''\r
         ID REAL PRIMARY KEY,\r
         Model INTEGER NOT NULL,\r
@@ -39,11 +90,11 @@ class ModuleTable(Table):
         Enabled INTEGER DEFAULT 0\r
         '''\r
     # used as table end flag, in case the changes to database is not committed to db file\r
-    _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1"\r
+    _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]\r
 \r
     ## Constructor\r
-    def __init__(self, Cursor, Name='Inf', IdBase=0, Temporary=False):\r
-        Table.__init__(self, Cursor, Name, IdBase, Temporary)\r
+    def __init__(self, Db, MetaFile, Temporary):\r
+        MetaFileTable.__init__(self, Db, MetaFile, MODEL_FILE_INF, Temporary)\r
 \r
     ## Insert a record into table Inf\r
     #\r
@@ -60,49 +111,62 @@ class ModuleTable(Table):
     # @param EndColumn:      EndColumn of a Inf item\r
     # @param Enabled:        If this item enabled\r
     #\r
-    def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON',\r
+    def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,\r
                BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):\r
-        (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2))\r
-        return Table.Insert(\r
-                        self, \r
-                        Model, \r
-                        Value1, \r
-                        Value2, \r
-                        Value3, \r
-                        Scope1, \r
-                        Scope2,\r
-                        BelongsToItem, \r
-                        StartLine, \r
-                        StartColumn, \r
-                        EndLine, \r
-                        EndColumn, \r
-                        Enabled\r
-                        )\r
+\r
+        (Value1, Value2, Value3, Scope1, Scope2) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip())\r
+        self.ID = self.ID + self._ID_STEP_\r
+        if self.ID >= (MODEL_FILE_INF + self._ID_MAX_):\r
+            self.ID = MODEL_FILE_INF + self._ID_STEP_\r
+\r
+        row = [ self.ID,\r
+                Model,\r
+                Value1,\r
+                Value2,\r
+                Value3,\r
+                Scope1,\r
+                Scope2,\r
+                BelongsToItem,\r
+                StartLine,\r
+                StartColumn,\r
+                EndLine,\r
+                EndColumn,\r
+                Enabled\r
+            ]\r
+        self.CurrentContent.append(row)\r
+        return self.ID\r
 \r
     ## Query table\r
     #\r
-    # @param    Model:      The Model of Record \r
-    # @param    Arch:       The Arch attribute of Record \r
-    # @param    Platform    The Platform attribute of Record \r
+    # @param    Model:      The Model of Record\r
+    # @param    Arch:       The Arch attribute of Record\r
+    # @param    Platform    The Platform attribute of Record\r
     #\r
-    # @retval:       A recordSet of all found records \r
+    # @retval:       A recordSet of all found records\r
     #\r
-    def Query(self, Model, Arch=None, Platform=None):\r
-        ConditionString = "Model=%s AND Enabled>=0" % Model\r
-        ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"\r
+    def Query(self, Model, Arch=None, Platform=None, BelongsToItem=None):\r
 \r
-        if Arch != None and Arch != 'COMMON':\r
-            ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch\r
-        if Platform != None and Platform != 'COMMON':\r
-            ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Platform\r
+        QueryTab = self.CurrentContent\r
+        result = [item for item in QueryTab if item[1] == Model and item[-1]>=0 ]\r
 \r
-        SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)\r
-        return self.Exec(SqlCommand)\r
+        if Arch is not None and Arch != TAB_ARCH_COMMON:\r
+            ArchList = set(['COMMON'])\r
+            ArchList.add(Arch)\r
+            result = [item for item in result if item[5] in ArchList]\r
+\r
+        if Platform is not None and Platform != TAB_COMMON:\r
+            Platformlist = set( ['COMMON','DEFAULT'])\r
+            Platformlist.add(Platform)\r
+            result = [item for item in result if item[6] in Platformlist]\r
+\r
+        if BelongsToItem is not None:\r
+            result = [item for item in result if item[7] == BelongsToItem]\r
+\r
+        result = [ [r[2],r[3],r[4],r[5],r[6],r[0],r[9]] for r in result ]\r
+        return result\r
 \r
 ## Python class representation of table storing package data\r
-class PackageTable(Table):\r
-    _ID_STEP_ = 0.00000001\r
-    _ID_MAX_ = 0.99999999\r
+class PackageTable(MetaFileTable):\r
     _COLUMN_ = '''\r
         ID REAL PRIMARY KEY,\r
         Model INTEGER NOT NULL,\r
@@ -119,11 +183,11 @@ class PackageTable(Table):
         Enabled INTEGER DEFAULT 0\r
         '''\r
     # used as table end flag, in case the changes to database is not committed to db file\r
-    _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1"\r
+    _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]\r
 \r
     ## Constructor\r
-    def __init__(self, Cursor, Name='Dec', IdBase=0, Temporary=False):\r
-        Table.__init__(self, Cursor, Name, IdBase, Temporary)\r
+    def __init__(self, Cursor, MetaFile, Temporary):\r
+        MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DEC, Temporary)\r
 \r
     ## Insert table\r
     #\r
@@ -142,46 +206,86 @@ class PackageTable(Table):
     # @param EndColumn:      EndColumn of a Dec item\r
     # @param Enabled:        If this item enabled\r
     #\r
-    def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON',\r
+    def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,\r
                BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):\r
-        (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2))\r
-        return Table.Insert(\r
-                        self, \r
-                        Model, \r
-                        Value1, \r
-                        Value2, \r
-                        Value3, \r
-                        Scope1, \r
-                        Scope2,\r
-                        BelongsToItem, \r
-                        StartLine, \r
-                        StartColumn, \r
-                        EndLine, \r
-                        EndColumn, \r
-                        Enabled\r
-                        )\r
+        (Value1, Value2, Value3, Scope1, Scope2) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip())\r
+        self.ID = self.ID + self._ID_STEP_\r
+\r
+        row = [ self.ID,\r
+                Model,\r
+                Value1,\r
+                Value2,\r
+                Value3,\r
+                Scope1,\r
+                Scope2,\r
+                BelongsToItem,\r
+                StartLine,\r
+                StartColumn,\r
+                EndLine,\r
+                EndColumn,\r
+                Enabled\r
+            ]\r
+        self.CurrentContent.append(row)\r
+        return self.ID\r
 \r
     ## Query table\r
     #\r
-    # @param    Model:  The Model of Record \r
-    # @param    Arch:   The Arch attribute of Record \r
+    # @param    Model:  The Model of Record\r
+    # @param    Arch:   The Arch attribute of Record\r
     #\r
-    # @retval:       A recordSet of all found records \r
+    # @retval:       A recordSet of all found records\r
     #\r
     def Query(self, Model, Arch=None):\r
-        ConditionString = "Model=%s AND Enabled>=0" % Model\r
-        ValueString = "Value1,Value2,Value3,Scope1,ID,StartLine"\r
 \r
-        if Arch != None and Arch != 'COMMON':\r
-            ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch\r
+        QueryTab = self.CurrentContent\r
+        result = [item for item in QueryTab if item[1] == Model and item[-1]>=0 ]\r
+\r
+        if Arch is not None and Arch != TAB_ARCH_COMMON:\r
+            ArchList = set(['COMMON'])\r
+            ArchList.add(Arch)\r
+            result = [item for item in result if item[5] in ArchList]\r
+\r
+        return [[r[2], r[3], r[4], r[5], r[6], r[0], r[8]] for r in result]\r
+\r
+    def GetValidExpression(self, TokenSpaceGuid, PcdCName):\r
+\r
+        QueryTab = self.CurrentContent\r
+        result = [[item[2], item[8]] for item in QueryTab if item[3] == TokenSpaceGuid and item[4] == PcdCName]\r
+        validateranges = []\r
+        validlists = []\r
+        expressions = []\r
+        try:\r
+            for row in result:\r
+                comment = row[0]\r
 \r
-        SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)\r
-        return self.Exec(SqlCommand)\r
+                LineNum = row[1]\r
+                comment = comment.strip("#")\r
+                comment = comment.strip()\r
+                oricomment = comment\r
+                if comment.startswith("@ValidRange"):\r
+                    comment = comment.replace("@ValidRange", "", 1)\r
+                    validateranges.append(comment.split("|")[1].strip())\r
+                if comment.startswith("@ValidList"):\r
+                    comment = comment.replace("@ValidList", "", 1)\r
+                    validlists.append(comment.split("|")[1].strip())\r
+                if comment.startswith("@Expression"):\r
+                    comment = comment.replace("@Expression", "", 1)\r
+                    expressions.append(comment.split("|")[1].strip())\r
+        except Exception as Exc:\r
+            ValidType = ""\r
+            if oricomment.startswith("@ValidRange"):\r
+                ValidType = "@ValidRange"\r
+            if oricomment.startswith("@ValidList"):\r
+                ValidType = "@ValidList"\r
+            if oricomment.startswith("@Expression"):\r
+                ValidType = "@Expression"\r
+            EdkLogger.error('Parser', FORMAT_INVALID, "The syntax for %s of PCD %s.%s is incorrect" % (ValidType, TokenSpaceGuid, PcdCName),\r
+                            ExtraData=oricomment, File=self.MetaFile, Line=LineNum)\r
+            return set(), set(), set()\r
+        return set(validateranges), set(validlists), set(expressions)\r
 \r
 ## Python class representation of table storing platform data\r
-class PlatformTable(Table):\r
-    _ID_STEP_ = 0.00000001\r
-    _ID_MAX_ = 0.99999999\r
+class PlatformTable(MetaFileTable):\r
     _COLUMN_ = '''\r
         ID REAL PRIMARY KEY,\r
         Model INTEGER NOT NULL,\r
@@ -190,6 +294,7 @@ class PlatformTable(Table):
         Value3 TEXT,\r
         Scope1 TEXT,\r
         Scope2 TEXT,\r
+        Scope3 TEXT,\r
         BelongsToItem REAL NOT NULL,\r
         FromItem REAL NOT NULL,\r
         StartLine INTEGER NOT NULL,\r
@@ -199,11 +304,11 @@ class PlatformTable(Table):
         Enabled INTEGER DEFAULT 0\r
         '''\r
     # used as table end flag, in case the changes to database is not committed to db file\r
-    _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1, -1"\r
+    _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====','====', -1, -1, -1, -1, -1, -1, -1]\r
 \r
     ## Constructor\r
-    def __init__(self, Cursor, Name='Dsc', IdBase=0, Temporary=False):\r
-        Table.__init__(self, Cursor, Name, IdBase, Temporary)\r
+    def __init__(self, Cursor, MetaFile, Temporary, FromItem=0):\r
+        MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DSC, Temporary, FromItem)\r
 \r
     ## Insert table\r
     #\r
@@ -223,53 +328,111 @@ class PlatformTable(Table):
     # @param EndColumn:      EndColumn of a Dsc item\r
     # @param Enabled:        If this item enabled\r
     #\r
-    def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON', BelongsToItem=-1, \r
+    def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON, Scope3=TAB_DEFAULT_STORES_DEFAULT,BelongsToItem=-1,\r
                FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1):\r
-        (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2))\r
-        return Table.Insert(\r
-                        self, \r
-                        Model, \r
-                        Value1, \r
-                        Value2, \r
-                        Value3, \r
-                        Scope1, \r
-                        Scope2,\r
-                        BelongsToItem, \r
-                        FromItem,\r
-                        StartLine, \r
-                        StartColumn, \r
-                        EndLine, \r
-                        EndColumn, \r
-                        Enabled\r
-                        )\r
+        (Value1, Value2, Value3, Scope1, Scope2, Scope3) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip(), Scope3.strip())\r
+        self.ID = self.ID + self._ID_STEP_\r
+\r
+        row = [ self.ID,\r
+                Model,\r
+                Value1,\r
+                Value2,\r
+                Value3,\r
+                Scope1,\r
+                Scope2,\r
+                Scope3,\r
+                BelongsToItem,\r
+                FromItem,\r
+                StartLine,\r
+                StartColumn,\r
+                EndLine,\r
+                EndColumn,\r
+                Enabled\r
+            ]\r
+        self.CurrentContent.append(row)\r
+        return self.ID\r
+\r
 \r
     ## Query table\r
     #\r
-    # @param Model:          The Model of Record \r
+    # @param Model:          The Model of Record\r
     # @param Scope1:         Arch of a Dsc item\r
     # @param Scope2:         Module type of a Dsc item\r
     # @param BelongsToItem:  The item belongs to which another item\r
     # @param FromItem:       The item belongs to which dsc file\r
     #\r
-    # @retval:       A recordSet of all found records \r
+    # @retval:       A recordSet of all found records\r
     #\r
     def Query(self, Model, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None):\r
-        ConditionString = "Model=%s AND Enabled>=0" % Model\r
-        ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"\r
 \r
-        if Scope1 != None and Scope1 != 'COMMON':\r
-            ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Scope1\r
-        if Scope2 != None and Scope2 != 'COMMON':\r
-            ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Scope2\r
+        QueryTab = self.CurrentContent\r
+        result = [item for item in QueryTab if item[1] == Model and item[-1]>0 ]\r
+        if Scope1 is not None and Scope1 != TAB_ARCH_COMMON:\r
+            Sc1 = set(['COMMON'])\r
+            Sc1.add(Scope1)\r
+            result = [item for item in result if item[5] in Sc1]\r
+        Sc2 = set( ['COMMON','DEFAULT'])\r
+        if Scope2 and Scope2 != TAB_COMMON:\r
+            if '.' in Scope2:\r
+                Index = Scope2.index('.')\r
+                NewScope = TAB_COMMON + Scope2[Index:]\r
+                Sc2.add(NewScope)\r
+            Sc2.add(Scope2)\r
+            result = [item for item in result if item[6] in Sc2]\r
 \r
-        if BelongsToItem != None:\r
-            ConditionString += " AND BelongsToItem=%s" % BelongsToItem\r
+        if BelongsToItem is not None:\r
+            result = [item for item in result if item[8] == BelongsToItem]\r
         else:\r
-            ConditionString += " AND BelongsToItem<0"\r
+            result = [item for item in result if item[8] < 0]\r
+        if FromItem is not None:\r
+            result = [item for item in result if item[9] == FromItem]\r
+\r
+        result = [ [r[2],r[3],r[4],r[5],r[6],r[7],r[0],r[10]] for r in result ]\r
+        return result\r
+\r
+    def DisableComponent(self,comp_id):\r
+        for item in self.CurrentContent:\r
+            if item[0] == comp_id or item[8] == comp_id:\r
+                item[-1] = -1\r
 \r
-        if FromItem != None:\r
-            ConditionString += " AND FromItem=%s" % FromItem\r
+## Factory class to produce different storage for different type of meta-file\r
+class MetaFileStorage(object):\r
+    _FILE_TABLE_ = {\r
+        MODEL_FILE_INF      :   ModuleTable,\r
+        MODEL_FILE_DEC      :   PackageTable,\r
+        MODEL_FILE_DSC      :   PlatformTable,\r
+        MODEL_FILE_OTHERS   :   MetaFileTable,\r
+    }\r
+\r
+    _FILE_TYPE_ = {\r
+        ".inf"  : MODEL_FILE_INF,\r
+        ".dec"  : MODEL_FILE_DEC,\r
+        ".dsc"  : MODEL_FILE_DSC,\r
+    }\r
+    _ObjectCache = {}\r
+    ## Constructor\r
+    def __new__(Class, Cursor, MetaFile, FileType=None, Temporary=False, FromItem=None):\r
+        # no type given, try to find one\r
+        key = (MetaFile.Path, FileType,Temporary,FromItem)\r
+        if key in Class._ObjectCache:\r
+            return Class._ObjectCache[key]\r
+        if not FileType:\r
+            if MetaFile.Type in self._FILE_TYPE_:\r
+                FileType = Class._FILE_TYPE_[MetaFile.Type]\r
+            else:\r
+                FileType = MODEL_FILE_OTHERS\r
+\r
+        # don't pass the type around if it's well known\r
+        if FileType == MODEL_FILE_OTHERS:\r
+            Args = (Cursor, MetaFile, FileType, Temporary)\r
+        else:\r
+            Args = (Cursor, MetaFile, Temporary)\r
+        if FromItem:\r
+            Args = Args + (FromItem,)\r
 \r
-        SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)\r
-        return self.Exec(SqlCommand)\r
+        # create the storage object and return it to caller\r
+        reval = Class._FILE_TABLE_[FileType](*Args)\r
+        if not Temporary:\r
+            Class._ObjectCache[key] = reval\r
+        return reval\r
 \r