]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/Python/Workspace/MetaFileTable.py
BaseTools: Use absolute import in Workspace
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / MetaFileTable.py
... / ...
CommitLineData
1## @file\r
2# This file is used to create/update/query/erase a meta file table\r
3#\r
4# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r
5# This program and the accompanying materials\r
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
17from __future__ import absolute_import\r
18import uuid\r
19\r
20import Common.EdkLogger as EdkLogger\r
21from Common.BuildToolError import FORMAT_INVALID\r
22\r
23from .MetaDataTable import Table, TableFile\r
24from .MetaDataTable import ConvertToSqlString\r
25from CommonDataClass.DataClass import MODEL_FILE_DSC, MODEL_FILE_DEC, MODEL_FILE_INF, \\r
26 MODEL_FILE_OTHERS\r
27from Common.DataType import *\r
28\r
29class MetaFileTable(Table):\r
30 # TRICK: use file ID as the part before '.'\r
31 _ID_STEP_ = 0.00000001\r
32 _ID_MAX_ = 0.99999999\r
33\r
34 ## Constructor\r
35 def __init__(self, Cursor, MetaFile, FileType, Temporary, FromItem=None):\r
36 self.MetaFile = MetaFile\r
37\r
38 self._FileIndexTable = TableFile(Cursor)\r
39 self._FileIndexTable.Create(False)\r
40\r
41 FileId = self._FileIndexTable.GetFileId(MetaFile, FromItem)\r
42 if not FileId:\r
43 FileId = self._FileIndexTable.InsertFile(MetaFile, FileType, FromItem)\r
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
56 TimeStamp = self.MetaFile.TimeStamp\r
57 Result = self.Cur.execute("select ID from %s where ID<0" % (self.Table)).fetchall()\r
58 if not Result:\r
59 # update the timestamp in database\r
60 self._FileIndexTable.SetFileTimeStamp(self.IdBase, TimeStamp)\r
61 return False\r
62\r
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
67 except Exception as Exc:\r
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
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
95 def __init__(self, Cursor, MetaFile, Temporary):\r
96 MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_INF, Temporary)\r
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
113 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,\r
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
117 self,\r
118 Model,\r
119 Value1,\r
120 Value2,\r
121 Value3,\r
122 Scope1,\r
123 Scope2,\r
124 BelongsToItem,\r
125 StartLine,\r
126 StartColumn,\r
127 EndLine,\r
128 EndColumn,\r
129 Enabled\r
130 )\r
131\r
132 ## Query table\r
133 #\r
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
137 #\r
138 # @retval: A recordSet of all found records\r
139 #\r
140 def Query(self, Model, Arch=None, Platform=None, BelongsToItem=None):\r
141 ConditionString = "Model=%s AND Enabled>=0" % Model\r
142 ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"\r
143\r
144 if Arch is not None and Arch != TAB_ARCH_COMMON:\r
145 ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch\r
146 if Platform is not None and Platform != TAB_COMMON:\r
147 ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Platform\r
148 if BelongsToItem is not None:\r
149 ConditionString += " AND BelongsToItem=%s" % BelongsToItem\r
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
155class PackageTable(MetaFileTable):\r
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
175 def __init__(self, Cursor, MetaFile, Temporary):\r
176 MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DEC, Temporary)\r
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
195 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,\r
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
199 self,\r
200 Model,\r
201 Value1,\r
202 Value2,\r
203 Value3,\r
204 Scope1,\r
205 Scope2,\r
206 BelongsToItem,\r
207 StartLine,\r
208 StartColumn,\r
209 EndLine,\r
210 EndColumn,\r
211 Enabled\r
212 )\r
213\r
214 ## Query table\r
215 #\r
216 # @param Model: The Model of Record\r
217 # @param Arch: The Arch attribute of Record\r
218 #\r
219 # @retval: A recordSet of all found records\r
220 #\r
221 def Query(self, Model, Arch=None):\r
222 ConditionString = "Model=%s AND Enabled>=0" % Model\r
223 ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"\r
224\r
225 if Arch is not None and Arch != TAB_ARCH_COMMON:\r
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
231 def GetValidExpression(self, TokenSpaceGuid, PcdCName):\r
232 SqlCommand = "select Value1,StartLine from %s WHERE Value2='%s' and Value3='%s'" % (self.Table, TokenSpaceGuid, PcdCName)\r
233 self.Cur.execute(SqlCommand)\r
234 validateranges = []\r
235 validlists = []\r
236 expressions = []\r
237 try:\r
238 for row in self.Cur:\r
239 comment = row[0]\r
240\r
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
254 except Exception as Exc:\r
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
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
264 return set(), set(), set()\r
265 return set(validateranges), set(validlists), set(expressions)\r
266## Python class representation of table storing platform data\r
267class PlatformTable(MetaFileTable):\r
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
276 Scope3 TEXT,\r
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
286 _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====','====', -1, -1, -1, -1, -1, -1, -1"\r
287\r
288 ## Constructor\r
289 def __init__(self, Cursor, MetaFile, Temporary, FromItem=0):\r
290 MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DSC, Temporary, FromItem)\r
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
310 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON, Scope3=TAB_DEFAULT_STORES_DEFAULT,BelongsToItem=-1,\r
311 FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1):\r
312 (Value1, Value2, Value3, Scope1, Scope2, Scope3) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2, Scope3))\r
313 return Table.Insert(\r
314 self,\r
315 Model,\r
316 Value1,\r
317 Value2,\r
318 Value3,\r
319 Scope1,\r
320 Scope2,\r
321 Scope3,\r
322 BelongsToItem,\r
323 FromItem,\r
324 StartLine,\r
325 StartColumn,\r
326 EndLine,\r
327 EndColumn,\r
328 Enabled\r
329 )\r
330\r
331 ## Query table\r
332 #\r
333 # @param Model: The Model of Record\r
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
339 # @retval: A recordSet of all found records\r
340 #\r
341 def Query(self, Model, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None):\r
342 ConditionString = "Model=%s AND Enabled>0" % Model\r
343 ValueString = "Value1,Value2,Value3,Scope1,Scope2,Scope3,ID,StartLine"\r
344\r
345 if Scope1 is not None and Scope1 != TAB_ARCH_COMMON:\r
346 ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Scope1\r
347 if Scope2 is not None and Scope2 != TAB_COMMON:\r
348 # Cover the case that CodeBase is 'COMMON' for BuildOptions section\r
349 if '.' in Scope2:\r
350 Index = Scope2.index('.')\r
351 NewScope = TAB_COMMON + Scope2[Index:]\r
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
355\r
356 if BelongsToItem is not None:\r
357 ConditionString += " AND BelongsToItem=%s" % BelongsToItem\r
358 else:\r
359 ConditionString += " AND BelongsToItem<0"\r
360\r
361 if FromItem is not None:\r
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
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
383 def __new__(Class, Cursor, MetaFile, FileType=None, Temporary=False, FromItem=None):\r
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
396 if FromItem:\r
397 Args = Args + (FromItem,)\r
398\r
399 # create the storage object and return it to caller\r
400 return Class._FILE_TABLE_[FileType](*Args)\r
401\r