]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Workspace/MetaFileTable.py
BaseTools: Replace the sqlite database with list
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / MetaFileTable.py
1 ## @file
2 # This file is used to create/update/query/erase a meta file table
3 #
4 # Copyright (c) 2008 - 2018, 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 from __future__ import absolute_import
18 import uuid
19
20 import Common.EdkLogger as EdkLogger
21 from Common.BuildToolError import FORMAT_INVALID
22
23 from CommonDataClass.DataClass import MODEL_FILE_DSC, MODEL_FILE_DEC, MODEL_FILE_INF, \
24 MODEL_FILE_OTHERS
25 from Common.DataType import *
26
27 class MetaFileTable():
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, DB, MetaFile, FileType, Temporary, FromItem=None):
34 self.MetaFile = MetaFile
35 self.TableName = ""
36 self.DB = DB
37 self._NumpyTab = None
38 self.FileId = len(DB.TblFile)
39 self.ID = self.FileId
40 self.CurrentContent = []
41 DB.TblFile.append([MetaFile.Name,
42 MetaFile.Ext,
43 MetaFile.Dir,
44 MetaFile.Path,
45 FileType,
46 MetaFile.TimeStamp,
47 FromItem])
48 if Temporary:
49 self.TableName = "_%s_%s_%s" % (FileType, len(DB.TblFile), uuid.uuid4().hex)
50 else:
51 self.TableName = "_%s_%s" % (FileType, len(DB.TblFile))
52
53 def IsIntegrity(self):
54 try:
55 TimeStamp = self.MetaFile.TimeStamp
56 Result = int(self.CurrentContent[-1][0]) < 0
57 if not Result:
58 # update the timestamp in database
59 self.DB.SetFileTimeStamp(self.FileId, TimeStamp)
60 return False
61
62 if TimeStamp != self.DB.GetFileTimeStamp(self.FileId):
63 # update the timestamp in database
64 self.DB.SetFileTimeStamp(self.FileId, TimeStamp)
65 return False
66 except Exception as Exc:
67 EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc))
68 return False
69 return True
70
71 def SetEndFlag(self):
72 self.CurrentContent.append(self._DUMMY_)
73
74 def GetAll(self):
75 return [item for item in self.CurrentContent if item[0] > 0 ]
76
77 ## Python class representation of table storing module data
78 class ModuleTable(MetaFileTable):
79 _ID_STEP_ = 0.00000001
80 _ID_MAX_ = 0.99999999
81 _COLUMN_ = '''
82 ID REAL PRIMARY KEY,
83 Model INTEGER NOT NULL,
84 Value1 TEXT NOT NULL,
85 Value2 TEXT,
86 Value3 TEXT,
87 Scope1 TEXT,
88 Scope2 TEXT,
89 BelongsToItem REAL NOT NULL,
90 StartLine INTEGER NOT NULL,
91 StartColumn INTEGER NOT NULL,
92 EndLine INTEGER NOT NULL,
93 EndColumn INTEGER NOT NULL,
94 Enabled INTEGER DEFAULT 0
95 '''
96 # used as table end flag, in case the changes to database is not committed to db file
97 _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]
98
99 ## Constructor
100 def __init__(self, Db, MetaFile, Temporary):
101 MetaFileTable.__init__(self, Db, MetaFile, MODEL_FILE_INF, Temporary)
102
103 ## Insert a record into table Inf
104 #
105 # @param Model: Model of a Inf item
106 # @param Value1: Value1 of a Inf item
107 # @param Value2: Value2 of a Inf item
108 # @param Value3: Value3 of a Inf item
109 # @param Scope1: Arch of a Inf item
110 # @param Scope2 Platform os a Inf item
111 # @param BelongsToItem: The item belongs to which another item
112 # @param StartLine: StartLine of a Inf item
113 # @param StartColumn: StartColumn of a Inf item
114 # @param EndLine: EndLine of a Inf item
115 # @param EndColumn: EndColumn of a Inf item
116 # @param Enabled: If this item enabled
117 #
118 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,
119 BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):
120
121 (Value1, Value2, Value3, Scope1, Scope2) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip())
122 self.ID = self.ID + self._ID_STEP_
123 if self.ID >= (MODEL_FILE_INF + self._ID_MAX_):
124 self.ID = MODEL_FILE_INF + self._ID_STEP_
125
126 row = [ self.ID,
127 Model,
128 Value1,
129 Value2,
130 Value3,
131 Scope1,
132 Scope2,
133 BelongsToItem,
134 StartLine,
135 StartColumn,
136 EndLine,
137 EndColumn,
138 Enabled
139 ]
140 self.CurrentContent.append(row)
141 return self.ID
142
143
144 ## Query table
145 #
146 # @param Model: The Model of Record
147 # @param Arch: The Arch attribute of Record
148 # @param Platform The Platform attribute of Record
149 #
150 # @retval: A recordSet of all found records
151 #
152 def Query(self, Model, Arch=None, Platform=None, BelongsToItem=None):
153
154 QueryTab = self.CurrentContent
155 result = [item for item in QueryTab if item[1] == Model and item[-1]>=0 ]
156
157 if Arch is not None and Arch != TAB_ARCH_COMMON:
158 ArchList = set(['COMMON'])
159 ArchList.add(Arch)
160 result = [item for item in result if item[5] in ArchList]
161
162 if Platform is not None and Platform != TAB_COMMON:
163 Platformlist = set( ['COMMON','DEFAULT'])
164 Platformlist.add(Platform)
165 result = [item for item in result if item[6] in Platformlist]
166
167 if BelongsToItem is not None:
168 result = [item for item in result if item[7] == BelongsToItem]
169
170 result = [ [r[2],r[3],r[4],r[5],r[6],r[0],r[9]] for r in result ]
171 return result
172
173 ## Python class representation of table storing package data
174 class PackageTable(MetaFileTable):
175 _COLUMN_ = '''
176 ID REAL PRIMARY KEY,
177 Model INTEGER NOT NULL,
178 Value1 TEXT NOT NULL,
179 Value2 TEXT,
180 Value3 TEXT,
181 Scope1 TEXT,
182 Scope2 TEXT,
183 BelongsToItem REAL NOT NULL,
184 StartLine INTEGER NOT NULL,
185 StartColumn INTEGER NOT NULL,
186 EndLine INTEGER NOT NULL,
187 EndColumn INTEGER NOT NULL,
188 Enabled INTEGER DEFAULT 0
189 '''
190 # used as table end flag, in case the changes to database is not committed to db file
191 _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1]
192
193 ## Constructor
194 def __init__(self, Cursor, MetaFile, Temporary):
195 MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DEC, Temporary)
196
197 ## Insert table
198 #
199 # Insert a record into table Dec
200 #
201 # @param Model: Model of a Dec item
202 # @param Value1: Value1 of a Dec item
203 # @param Value2: Value2 of a Dec item
204 # @param Value3: Value3 of a Dec item
205 # @param Scope1: Arch of a Dec item
206 # @param Scope2: Module type of a Dec item
207 # @param BelongsToItem: The item belongs to which another item
208 # @param StartLine: StartLine of a Dec item
209 # @param StartColumn: StartColumn of a Dec item
210 # @param EndLine: EndLine of a Dec item
211 # @param EndColumn: EndColumn of a Dec item
212 # @param Enabled: If this item enabled
213 #
214 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON,
215 BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0):
216 (Value1, Value2, Value3, Scope1, Scope2) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip())
217 self.ID = self.ID + self._ID_STEP_
218 if self.ID >= (MODEL_FILE_INF + self._ID_MAX_):
219 self.ID = MODEL_FILE_INF + self._ID_STEP_
220
221 row = [ self.ID,
222 Model,
223 Value1,
224 Value2,
225 Value3,
226 Scope1,
227 Scope2,
228 BelongsToItem,
229 StartLine,
230 StartColumn,
231 EndLine,
232 EndColumn,
233 Enabled
234 ]
235 self.CurrentContent.append(row)
236 return self.ID
237
238 ## Query table
239 #
240 # @param Model: The Model of Record
241 # @param Arch: The Arch attribute of Record
242 #
243 # @retval: A recordSet of all found records
244 #
245 def Query(self, Model, Arch=None):
246
247 QueryTab = self.CurrentContent
248 result = [item for item in QueryTab if item[1] == Model and item[-1]>=0 ]
249
250 if Arch is not None and Arch != TAB_ARCH_COMMON:
251 ArchList = set(['COMMON'])
252 ArchList.add(Arch)
253 result = [item for item in result if item[5] in ArchList]
254
255 return [[r[2], r[3], r[4], r[5], r[6], r[0], r[8]] for r in result]
256
257 def GetValidExpression(self, TokenSpaceGuid, PcdCName):
258
259 QueryTab = self.CurrentContent
260 result = [[item[2], item[8]] for item in QueryTab if item[3] == TokenSpaceGuid and item[4] == PcdCName]
261 validateranges = []
262 validlists = []
263 expressions = []
264 try:
265 for row in result:
266 comment = row[0]
267
268 LineNum = row[1]
269 comment = comment.strip("#")
270 comment = comment.strip()
271 oricomment = comment
272 if comment.startswith("@ValidRange"):
273 comment = comment.replace("@ValidRange", "", 1)
274 validateranges.append(comment.split("|")[1].strip())
275 if comment.startswith("@ValidList"):
276 comment = comment.replace("@ValidList", "", 1)
277 validlists.append(comment.split("|")[1].strip())
278 if comment.startswith("@Expression"):
279 comment = comment.replace("@Expression", "", 1)
280 expressions.append(comment.split("|")[1].strip())
281 except Exception as Exc:
282 ValidType = ""
283 if oricomment.startswith("@ValidRange"):
284 ValidType = "@ValidRange"
285 if oricomment.startswith("@ValidList"):
286 ValidType = "@ValidList"
287 if oricomment.startswith("@Expression"):
288 ValidType = "@Expression"
289 EdkLogger.error('Parser', FORMAT_INVALID, "The syntax for %s of PCD %s.%s is incorrect" % (ValidType, TokenSpaceGuid, PcdCName),
290 ExtraData=oricomment, File=self.MetaFile, Line=LineNum)
291 return set(), set(), set()
292 return set(validateranges), set(validlists), set(expressions)
293 ## Python class representation of table storing platform data
294 class PlatformTable(MetaFileTable):
295 _COLUMN_ = '''
296 ID REAL PRIMARY KEY,
297 Model INTEGER NOT NULL,
298 Value1 TEXT NOT NULL,
299 Value2 TEXT,
300 Value3 TEXT,
301 Scope1 TEXT,
302 Scope2 TEXT,
303 Scope3 TEXT,
304 BelongsToItem REAL NOT NULL,
305 FromItem REAL NOT NULL,
306 StartLine INTEGER NOT NULL,
307 StartColumn INTEGER NOT NULL,
308 EndLine INTEGER NOT NULL,
309 EndColumn INTEGER NOT NULL,
310 Enabled INTEGER DEFAULT 0
311 '''
312 # used as table end flag, in case the changes to database is not committed to db file
313 _DUMMY_ = [-1, -1, '====', '====', '====', '====', '====','====', -1, -1, -1, -1, -1, -1, -1]
314
315 ## Constructor
316 def __init__(self, Cursor, MetaFile, Temporary, FromItem=0):
317 MetaFileTable.__init__(self, Cursor, MetaFile, MODEL_FILE_DSC, Temporary, FromItem)
318
319 ## Insert table
320 #
321 # Insert a record into table Dsc
322 #
323 # @param Model: Model of a Dsc item
324 # @param Value1: Value1 of a Dsc item
325 # @param Value2: Value2 of a Dsc item
326 # @param Value3: Value3 of a Dsc item
327 # @param Scope1: Arch of a Dsc item
328 # @param Scope2: Module type of a Dsc item
329 # @param BelongsToItem: The item belongs to which another item
330 # @param FromItem: The item belongs to which dsc file
331 # @param StartLine: StartLine of a Dsc item
332 # @param StartColumn: StartColumn of a Dsc item
333 # @param EndLine: EndLine of a Dsc item
334 # @param EndColumn: EndColumn of a Dsc item
335 # @param Enabled: If this item enabled
336 #
337 def Insert(self, Model, Value1, Value2, Value3, Scope1=TAB_ARCH_COMMON, Scope2=TAB_COMMON, Scope3=TAB_DEFAULT_STORES_DEFAULT,BelongsToItem=-1,
338 FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1):
339 (Value1, Value2, Value3, Scope1, Scope2, Scope3) = (Value1.strip(), Value2.strip(), Value3.strip(), Scope1.strip(), Scope2.strip(), Scope3.strip())
340 self.ID = self.ID + self._ID_STEP_
341 if self.ID >= (MODEL_FILE_INF + self._ID_MAX_):
342 self.ID = MODEL_FILE_INF + self._ID_STEP_
343
344 row = [ self.ID,
345 Model,
346 Value1,
347 Value2,
348 Value3,
349 Scope1,
350 Scope2,
351 Scope3,
352 BelongsToItem,
353 FromItem,
354 StartLine,
355 StartColumn,
356 EndLine,
357 EndColumn,
358 Enabled
359 ]
360 self.CurrentContent.append(row)
361 return self.ID
362
363
364 ## Query table
365 #
366 # @param Model: The Model of Record
367 # @param Scope1: Arch of a Dsc item
368 # @param Scope2: Module type of a Dsc item
369 # @param BelongsToItem: The item belongs to which another item
370 # @param FromItem: The item belongs to which dsc file
371 #
372 # @retval: A recordSet of all found records
373 #
374 def Query(self, Model, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None):
375
376 QueryTab = self.CurrentContent
377 result = [item for item in QueryTab if item[1] == Model and item[-1]>0 ]
378
379 if Scope1 is not None and Scope1 != TAB_ARCH_COMMON:
380 Sc1 = set(['COMMON'])
381 Sc1.add(Scope1)
382 result = [item for item in result if item[5] in Sc1]
383 Sc2 = set( ['COMMON','DEFAULT'])
384 if Scope2 and Scope2 != TAB_COMMON:
385 if '.' in Scope2:
386 Index = Scope2.index('.')
387 NewScope = TAB_COMMON + Scope2[Index:]
388 Sc2.add(NewScope)
389 Sc2.add(Scope2)
390 result = [item for item in result if item[6] in Sc2]
391
392 if BelongsToItem is not None:
393 result = [item for item in result if item[8] == BelongsToItem]
394 else:
395 result = [item for item in result if item[8] < 0]
396 if FromItem is not None:
397 result = [item for item in result if item[9] == FromItem]
398
399 result = [ [r[2],r[3],r[4],r[5],r[6],r[7],r[0],r[9]] for r in result ]
400 return result
401
402
403 ## Factory class to produce different storage for different type of meta-file
404 class MetaFileStorage(object):
405 _FILE_TABLE_ = {
406 MODEL_FILE_INF : ModuleTable,
407 MODEL_FILE_DEC : PackageTable,
408 MODEL_FILE_DSC : PlatformTable,
409 MODEL_FILE_OTHERS : MetaFileTable,
410 }
411
412 _FILE_TYPE_ = {
413 ".inf" : MODEL_FILE_INF,
414 ".dec" : MODEL_FILE_DEC,
415 ".dsc" : MODEL_FILE_DSC,
416 }
417
418 ## Constructor
419 def __new__(Class, Cursor, MetaFile, FileType=None, Temporary=False, FromItem=None):
420 # no type given, try to find one
421 if not FileType:
422 if MetaFile.Type in self._FILE_TYPE_:
423 FileType = Class._FILE_TYPE_[MetaFile.Type]
424 else:
425 FileType = MODEL_FILE_OTHERS
426
427 # don't pass the type around if it's well known
428 if FileType == MODEL_FILE_OTHERS:
429 Args = (Cursor, MetaFile, FileType, Temporary)
430 else:
431 Args = (Cursor, MetaFile, Temporary)
432 if FromItem:
433 Args = Args + (FromItem,)
434
435 # create the storage object and return it to caller
436 return Class._FILE_TABLE_[FileType](*Args)
437