BaseTools: Use absolute import in Workspace
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / MetaFileTable.py
CommitLineData
30fdf114
LG
1## @file\r
2# This file is used to create/update/query/erase a meta file table\r
3#\r
55c84777 4# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r
40d841f6 5# This program and the accompanying materials\r
30fdf114
LG
6# are licensed and made available under the terms and conditions of the BSD License\r
7# which accompanies this distribution. The full text of the license may be found at\r
8# http://opensource.org/licenses/bsd-license.php\r
9#\r
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12#\r
13\r
14##\r
15# Import Modules\r
16#\r
1100bc5a 17from __future__ import absolute_import\r
0d2711a6
LG
18import uuid\r
19\r
30fdf114 20import Common.EdkLogger as EdkLogger\r
901fd822 21from Common.BuildToolError import FORMAT_INVALID\r
0d2711a6 22\r
1100bc5a
GL
23from .MetaDataTable import Table, TableFile\r
24from .MetaDataTable import ConvertToSqlString\r
0d2711a6
LG
25from CommonDataClass.DataClass import MODEL_FILE_DSC, MODEL_FILE_DEC, MODEL_FILE_INF, \\r
26 MODEL_FILE_OTHERS\r
8518bf0b 27from Common.DataType import *\r
30fdf114 28\r
0d2711a6 29class MetaFileTable(Table):\r
30fdf114 30 # TRICK: use file ID as the part before '.'\r
0d2711a6
LG
31 _ID_STEP_ = 0.00000001\r
32 _ID_MAX_ = 0.99999999\r
33\r
34 ## Constructor\r
395f3336 35 def __init__(self, Cursor, MetaFile, FileType, Temporary, FromItem=None):\r
0d2711a6
LG
36 self.MetaFile = MetaFile\r
37\r
38 self._FileIndexTable = TableFile(Cursor)\r
39 self._FileIndexTable.Create(False)\r
40\r
395f3336 41 FileId = self._FileIndexTable.GetFileId(MetaFile, FromItem)\r
0d2711a6 42 if not FileId:\r
395f3336 43 FileId = self._FileIndexTable.InsertFile(MetaFile, FileType, FromItem)\r
0d2711a6
LG
44\r
45 if Temporary:\r
46 TableName = "_%s_%s_%s" % (FileType, FileId, uuid.uuid4().hex)\r
47 else:\r
48 TableName = "_%s_%s" % (FileType, FileId)\r
49\r
50 #Table.__init__(self, Cursor, TableName, FileId, False)\r
51 Table.__init__(self, Cursor, TableName, FileId, Temporary)\r
52 self.Create(not self.IsIntegrity())\r
53\r
54 def IsIntegrity(self):\r
55 try:\r
64b2609f 56 TimeStamp = self.MetaFile.TimeStamp\r
0d2711a6
LG
57 Result = self.Cur.execute("select ID from %s where ID<0" % (self.Table)).fetchall()\r
58 if not Result:\r
64b2609f 59 # update the timestamp in database\r
f7496d71 60 self._FileIndexTable.SetFileTimeStamp(self.IdBase, TimeStamp)\r
0d2711a6
LG
61 return False\r
62\r
0d2711a6
LG
63 if TimeStamp != self._FileIndexTable.GetFileTimeStamp(self.IdBase):\r
64 # update the timestamp in database\r
65 self._FileIndexTable.SetFileTimeStamp(self.IdBase, TimeStamp)\r
66 return False\r
5b0671c1 67 except Exception as Exc:\r
0d2711a6
LG
68 EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc))\r
69 return False\r
70 return True\r
71\r
72## Python class representation of table storing module data\r
73class ModuleTable(MetaFileTable):\r
30fdf114
LG
74 _ID_STEP_ = 0.00000001\r
75 _ID_MAX_ = 0.99999999\r
76 _COLUMN_ = '''\r
77 ID REAL PRIMARY KEY,\r
78 Model INTEGER NOT NULL,\r
79 Value1 TEXT NOT NULL,\r
80 Value2 TEXT,\r
81 Value3 TEXT,\r
82 Scope1 TEXT,\r
83 Scope2 TEXT,\r
84 BelongsToItem REAL NOT NULL,\r
85 StartLine INTEGER NOT NULL,\r
86 StartColumn INTEGER NOT NULL,\r
87 EndLine INTEGER NOT NULL,\r
88 EndColumn INTEGER NOT NULL,\r
89 Enabled INTEGER DEFAULT 0\r
90 '''\r
91 # used as table end flag, in case the changes to database is not committed to db file\r
92 _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1"\r
93\r
94 ## Constructor\r
0d2711a6
LG
95 def __init__(self, Cursor, MetaFile, Temporary):\r
96 MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_INF, Temporary)\r
30fdf114
LG
97\r
98 ## Insert a record into table Inf\r
99 #\r
100 # @param Model: Model of a Inf item\r
101 # @param Value1: Value1 of a Inf item\r
102 # @param Value2: Value2 of a Inf item\r
103 # @param Value3: Value3 of a Inf item\r
104 # @param Scope1: Arch of a Inf item\r
105 # @param Scope2 Platform os a Inf item\r
106 # @param BelongsToItem: The item belongs to which another item\r
107 # @param StartLine: StartLine of a Inf item\r
108 # @param StartColumn: StartColumn of a Inf item\r
109 # @param EndLine: EndLine of a Inf item\r
110 # @param EndColumn: EndColumn of a Inf item\r
111 # @param Enabled: If this item enabled\r
112 #\r
55c84777 113 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,\r
30fdf114
LG
114 BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):\r
115 (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2))\r
116 return Table.Insert(\r
f7496d71
LG
117 self,\r
118 Model,\r
119 Value1,\r
120 Value2,\r
121 Value3,\r
122 Scope1,\r
30fdf114 123 Scope2,\r
f7496d71
LG
124 BelongsToItem,\r
125 StartLine,\r
126 StartColumn,\r
127 EndLine,\r
128 EndColumn,\r
30fdf114
LG
129 Enabled\r
130 )\r
131\r
132 ## Query table\r
133 #\r
f7496d71
LG
134 # @param Model: The Model of Record\r
135 # @param Arch: The Arch attribute of Record\r
136 # @param Platform The Platform attribute of Record\r
30fdf114 137 #\r
f7496d71 138 # @retval: A recordSet of all found records\r
30fdf114 139 #\r
e8a47801 140 def Query(self, Model, Arch=None, Platform=None, BelongsToItem=None):\r
30fdf114
LG
141 ConditionString = "Model=%s AND Enabled>=0" % Model\r
142 ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"\r
143\r
55c84777 144 if Arch is not None and Arch != TAB_ARCH_COMMON:\r
30fdf114 145 ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch\r
55c84777 146 if Platform is not None and Platform != TAB_COMMON:\r
30fdf114 147 ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Platform\r
4231a819 148 if BelongsToItem is not None:\r
e8a47801 149 ConditionString += " AND BelongsToItem=%s" % BelongsToItem\r
30fdf114
LG
150\r
151 SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)\r
152 return self.Exec(SqlCommand)\r
153\r
154## Python class representation of table storing package data\r
0d2711a6 155class PackageTable(MetaFileTable):\r
30fdf114
LG
156 _COLUMN_ = '''\r
157 ID REAL PRIMARY KEY,\r
158 Model INTEGER NOT NULL,\r
159 Value1 TEXT NOT NULL,\r
160 Value2 TEXT,\r
161 Value3 TEXT,\r
162 Scope1 TEXT,\r
163 Scope2 TEXT,\r
164 BelongsToItem REAL NOT NULL,\r
165 StartLine INTEGER NOT NULL,\r
166 StartColumn INTEGER NOT NULL,\r
167 EndLine INTEGER NOT NULL,\r
168 EndColumn INTEGER NOT NULL,\r
169 Enabled INTEGER DEFAULT 0\r
170 '''\r
171 # used as table end flag, in case the changes to database is not committed to db file\r
172 _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1"\r
173\r
174 ## Constructor\r
0d2711a6
LG
175 def __init__(self, Cursor, MetaFile, Temporary):\r
176 MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DEC, Temporary)\r
30fdf114
LG
177\r
178 ## Insert table\r
179 #\r
180 # Insert a record into table Dec\r
181 #\r
182 # @param Model: Model of a Dec item\r
183 # @param Value1: Value1 of a Dec item\r
184 # @param Value2: Value2 of a Dec item\r
185 # @param Value3: Value3 of a Dec item\r
186 # @param Scope1: Arch of a Dec item\r
187 # @param Scope2: Module type of a Dec item\r
188 # @param BelongsToItem: The item belongs to which another item\r
189 # @param StartLine: StartLine of a Dec item\r
190 # @param StartColumn: StartColumn of a Dec item\r
191 # @param EndLine: EndLine of a Dec item\r
192 # @param EndColumn: EndColumn of a Dec item\r
193 # @param Enabled: If this item enabled\r
194 #\r
55c84777 195 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,\r
30fdf114
LG
196 BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):\r
197 (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2))\r
198 return Table.Insert(\r
f7496d71
LG
199 self,\r
200 Model,\r
201 Value1,\r
202 Value2,\r
203 Value3,\r
204 Scope1,\r
30fdf114 205 Scope2,\r
f7496d71
LG
206 BelongsToItem,\r
207 StartLine,\r
208 StartColumn,\r
209 EndLine,\r
210 EndColumn,\r
30fdf114
LG
211 Enabled\r
212 )\r
213\r
214 ## Query table\r
215 #\r
f7496d71
LG
216 # @param Model: The Model of Record\r
217 # @param Arch: The Arch attribute of Record\r
30fdf114 218 #\r
f7496d71 219 # @retval: A recordSet of all found records\r
30fdf114
LG
220 #\r
221 def Query(self, Model, Arch=None):\r
222 ConditionString = "Model=%s AND Enabled>=0" % Model\r
c28d2e10 223 ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"\r
30fdf114 224\r
55c84777 225 if Arch is not None and Arch != TAB_ARCH_COMMON:\r
30fdf114
LG
226 ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch\r
227\r
228 SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)\r
229 return self.Exec(SqlCommand)\r
230\r
82a6a960 231 def GetValidExpression(self, TokenSpaceGuid, PcdCName):\r
901fd822 232 SqlCommand = "select Value1,StartLine from %s WHERE Value2='%s' and Value3='%s'" % (self.Table, TokenSpaceGuid, PcdCName)\r
82a6a960
BF
233 self.Cur.execute(SqlCommand)\r
234 validateranges = []\r
235 validlists = []\r
236 expressions = []\r
901fd822
BF
237 try:\r
238 for row in self.Cur:\r
239 comment = row[0]\r
f7496d71 240\r
901fd822
BF
241 LineNum = row[1]\r
242 comment = comment.strip("#")\r
243 comment = comment.strip()\r
244 oricomment = comment\r
245 if comment.startswith("@ValidRange"):\r
246 comment = comment.replace("@ValidRange", "", 1)\r
247 validateranges.append(comment.split("|")[1].strip())\r
248 if comment.startswith("@ValidList"):\r
249 comment = comment.replace("@ValidList", "", 1)\r
250 validlists.append(comment.split("|")[1].strip())\r
251 if comment.startswith("@Expression"):\r
252 comment = comment.replace("@Expression", "", 1)\r
253 expressions.append(comment.split("|")[1].strip())\r
5b0671c1 254 except Exception as Exc:\r
901fd822
BF
255 ValidType = ""\r
256 if oricomment.startswith("@ValidRange"):\r
257 ValidType = "@ValidRange"\r
258 if oricomment.startswith("@ValidList"):\r
259 ValidType = "@ValidList"\r
260 if oricomment.startswith("@Expression"):\r
261 ValidType = "@Expression"\r
ccaa7754
GL
262 EdkLogger.error('Parser', FORMAT_INVALID, "The syntax for %s of PCD %s.%s is incorrect" % (ValidType, TokenSpaceGuid, PcdCName),\r
263 ExtraData=oricomment, File=self.MetaFile, Line=LineNum)\r
901fd822 264 return set(), set(), set()\r
82a6a960 265 return set(validateranges), set(validlists), set(expressions)\r
30fdf114 266## Python class representation of table storing platform data\r
0d2711a6 267class PlatformTable(MetaFileTable):\r
30fdf114
LG
268 _COLUMN_ = '''\r
269 ID REAL PRIMARY KEY,\r
270 Model INTEGER NOT NULL,\r
271 Value1 TEXT NOT NULL,\r
272 Value2 TEXT,\r
273 Value3 TEXT,\r
274 Scope1 TEXT,\r
275 Scope2 TEXT,\r
8518bf0b 276 Scope3 TEXT,\r
30fdf114
LG
277 BelongsToItem REAL NOT NULL,\r
278 FromItem REAL NOT NULL,\r
279 StartLine INTEGER NOT NULL,\r
280 StartColumn INTEGER NOT NULL,\r
281 EndLine INTEGER NOT NULL,\r
282 EndColumn INTEGER NOT NULL,\r
283 Enabled INTEGER DEFAULT 0\r
284 '''\r
285 # used as table end flag, in case the changes to database is not committed to db file\r
8518bf0b 286 _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====','====', -1, -1, -1, -1, -1, -1, -1"\r
30fdf114
LG
287\r
288 ## Constructor\r
395f3336
YF
289 def __init__(self, Cursor, MetaFile, Temporary, FromItem=0):\r
290 MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DSC, Temporary, FromItem)\r
30fdf114
LG
291\r
292 ## Insert table\r
293 #\r
294 # Insert a record into table Dsc\r
295 #\r
296 # @param Model: Model of a Dsc item\r
297 # @param Value1: Value1 of a Dsc item\r
298 # @param Value2: Value2 of a Dsc item\r
299 # @param Value3: Value3 of a Dsc item\r
300 # @param Scope1: Arch of a Dsc item\r
301 # @param Scope2: Module type of a Dsc item\r
302 # @param BelongsToItem: The item belongs to which another item\r
303 # @param FromItem: The item belongs to which dsc file\r
304 # @param StartLine: StartLine of a Dsc item\r
305 # @param StartColumn: StartColumn of a Dsc item\r
306 # @param EndLine: EndLine of a Dsc item\r
307 # @param EndColumn: EndColumn of a Dsc item\r
308 # @param Enabled: If this item enabled\r
309 #\r
55c84777 310 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON, Scope3=TAB_DEFAULT_STORES_DEFAULT,BelongsToItem=-1,\r
30fdf114 311 FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1):\r
ccaa7754 312 (Value1, Value2, Value3, Scope1, Scope2, Scope3) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2, Scope3))\r
30fdf114 313 return Table.Insert(\r
f7496d71
LG
314 self,\r
315 Model,\r
316 Value1,\r
317 Value2,\r
318 Value3,\r
319 Scope1,\r
30fdf114 320 Scope2,\r
8518bf0b 321 Scope3,\r
f7496d71 322 BelongsToItem,\r
30fdf114 323 FromItem,\r
f7496d71
LG
324 StartLine,\r
325 StartColumn,\r
326 EndLine,\r
327 EndColumn,\r
30fdf114
LG
328 Enabled\r
329 )\r
330\r
331 ## Query table\r
332 #\r
f7496d71 333 # @param Model: The Model of Record\r
30fdf114
LG
334 # @param Scope1: Arch of a Dsc item\r
335 # @param Scope2: Module type of a Dsc item\r
336 # @param BelongsToItem: The item belongs to which another item\r
337 # @param FromItem: The item belongs to which dsc file\r
338 #\r
f7496d71 339 # @retval: A recordSet of all found records\r
30fdf114
LG
340 #\r
341 def Query(self, Model, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None):\r
0d2711a6 342 ConditionString = "Model=%s AND Enabled>0" % Model\r
8518bf0b 343 ValueString = "Value1,Value2,Value3,Scope1,Scope2,Scope3,ID,StartLine"\r
30fdf114 344\r
55c84777 345 if Scope1 is not None and Scope1 != TAB_ARCH_COMMON:\r
30fdf114 346 ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Scope1\r
55c84777 347 if Scope2 is not None and Scope2 != TAB_COMMON:\r
35dc964b
YZ
348 # Cover the case that CodeBase is 'COMMON' for BuildOptions section\r
349 if '.' in Scope2:\r
350 Index = Scope2.index('.')\r
55c84777 351 NewScope = TAB_COMMON + Scope2[Index:]\r
35dc964b
YZ
352 ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT' OR Scope2='%s')" % (Scope2, NewScope)\r
353 else:\r
354 ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Scope2\r
30fdf114 355\r
4231a819 356 if BelongsToItem is not None:\r
30fdf114
LG
357 ConditionString += " AND BelongsToItem=%s" % BelongsToItem\r
358 else:\r
359 ConditionString += " AND BelongsToItem<0"\r
360\r
4231a819 361 if FromItem is not None:\r
30fdf114
LG
362 ConditionString += " AND FromItem=%s" % FromItem\r
363\r
364 SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)\r
365 return self.Exec(SqlCommand)\r
366\r
0d2711a6
LG
367## Factory class to produce different storage for different type of meta-file\r
368class MetaFileStorage(object):\r
369 _FILE_TABLE_ = {\r
370 MODEL_FILE_INF : ModuleTable,\r
371 MODEL_FILE_DEC : PackageTable,\r
372 MODEL_FILE_DSC : PlatformTable,\r
373 MODEL_FILE_OTHERS : MetaFileTable,\r
374 }\r
375\r
376 _FILE_TYPE_ = {\r
377 ".inf" : MODEL_FILE_INF,\r
378 ".dec" : MODEL_FILE_DEC,\r
379 ".dsc" : MODEL_FILE_DSC,\r
380 }\r
381\r
382 ## Constructor\r
395f3336 383 def __new__(Class, Cursor, MetaFile, FileType=None, Temporary=False, FromItem=None):\r
0d2711a6
LG
384 # no type given, try to find one\r
385 if not FileType:\r
386 if MetaFile.Type in self._FILE_TYPE_:\r
387 FileType = Class._FILE_TYPE_[MetaFile.Type]\r
388 else:\r
389 FileType = MODEL_FILE_OTHERS\r
390\r
391 # don't pass the type around if it's well known\r
392 if FileType == MODEL_FILE_OTHERS:\r
393 Args = (Cursor, MetaFile, FileType, Temporary)\r
394 else:\r
395 Args = (Cursor, MetaFile, Temporary)\r
395f3336
YF
396 if FromItem:\r
397 Args = Args + (FromItem,)\r
0d2711a6
LG
398\r
399 # create the storage object and return it to caller\r
400 return Class._FILE_TABLE_[FileType](*Args)\r
401\r