]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Workspace/MetaFileTable.py
aedcacada199d094047e7c599630be88cabb0d54
[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 - 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