204117512452b4d0d2d4c1cb8fdc50b2e9cf30b1
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / Database.py
1 ## @file
2 # This file is used to create a database used by ECC tool
3 #
4 # Copyright (c) 2007 - 2014, 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 sqlite3
18 import Common.LongFilePathOs as os, time
19
20 import Common.EdkLogger as EdkLogger
21 import CommonDataClass.DataClass as DataClass
22
23 from Table.TableDataModel import TableDataModel
24 from Table.TableFile import TableFile
25 from Table.TableFunction import TableFunction
26 from Table.TablePcd import TablePcd
27 from Table.TableIdentifier import TableIdentifier
28 from Table.TableReport import TableReport
29 from MetaFileWorkspace.MetaFileTable import ModuleTable
30 from MetaFileWorkspace.MetaFileTable import PackageTable
31 from MetaFileWorkspace.MetaFileTable import PlatformTable
32 from Table.TableFdf import TableFdf
33
34 ##
35 # Static definitions
36 #
37 DATABASE_PATH = "Ecc.db"
38
39 ## Database
40 #
41 # This class defined the ECC databse
42 # During the phase of initialization, the database will create all tables and
43 # insert all records of table DataModel
44 #
45 # @param object: Inherited from object class
46 # @param DbPath: A string for the path of the ECC database
47 #
48 # @var Conn: Connection of the ECC database
49 # @var Cur: Cursor of the connection
50 # @var TblDataModel: Local instance for TableDataModel
51 #
52 class Database(object):
53 def __init__(self, DbPath):
54 self.DbPath = DbPath
55 self.Conn = None
56 self.Cur = None
57 self.TblDataModel = None
58 self.TblFile = None
59 self.TblFunction = None
60 self.TblIdentifier = None
61 self.TblPcd = None
62 self.TblReport = None
63 self.TblInf = None
64 self.TblDec = None
65 self.TblDsc = None
66 self.TblFdf = None
67
68 ## Initialize ECC database
69 #
70 # 1. Delete all old existing tables
71 # 2. Create new tables
72 # 3. Initialize table DataModel
73 #
74 def InitDatabase(self, NewDatabase = True):
75 EdkLogger.verbose("\nInitialize ECC database started ...")
76 #
77 # Drop all old existing tables
78 #
79 if NewDatabase:
80 if os.path.exists(self.DbPath):
81 os.remove(self.DbPath)
82 self.Conn = sqlite3.connect(self.DbPath, isolation_level = 'DEFERRED')
83 self.Conn.execute("PRAGMA page_size=4096")
84 self.Conn.execute("PRAGMA synchronous=OFF")
85 # to avoid non-ascii charater conversion error
86 self.Conn.text_factory = str
87 self.Cur = self.Conn.cursor()
88
89 self.TblDataModel = TableDataModel(self.Cur)
90 self.TblFile = TableFile(self.Cur)
91 self.TblFunction = TableFunction(self.Cur)
92 self.TblIdentifier = TableIdentifier(self.Cur)
93 self.TblPcd = TablePcd(self.Cur)
94 self.TblReport = TableReport(self.Cur)
95 self.TblInf = ModuleTable(self.Cur)
96 self.TblDec = PackageTable(self.Cur)
97 self.TblDsc = PlatformTable(self.Cur)
98 self.TblFdf = TableFdf(self.Cur)
99
100 #
101 # Create new tables
102 #
103 if NewDatabase:
104 self.TblDataModel.Create()
105 self.TblFile.Create()
106 self.TblFunction.Create()
107 self.TblPcd.Create()
108 self.TblReport.Create()
109 self.TblInf.Create()
110 self.TblDec.Create()
111 self.TblDsc.Create()
112 self.TblFdf.Create()
113
114 #
115 # Init each table's ID
116 #
117 self.TblDataModel.InitID()
118 self.TblFile.InitID()
119 self.TblFunction.InitID()
120 self.TblPcd.InitID()
121 self.TblReport.InitID()
122 self.TblInf.InitID()
123 self.TblDec.InitID()
124 self.TblDsc.InitID()
125 self.TblFdf.InitID()
126
127 #
128 # Initialize table DataModel
129 #
130 if NewDatabase:
131 self.TblDataModel.InitTable()
132
133 EdkLogger.verbose("Initialize ECC database ... DONE!")
134
135 ## Query a table
136 #
137 # @param Table: The instance of the table to be queried
138 #
139 def QueryTable(self, Table):
140 Table.Query()
141
142 ## Close entire database
143 #
144 # Commit all first
145 # Close the connection and cursor
146 #
147 def Close(self):
148 #
149 # Commit to file
150 #
151 self.Conn.commit()
152
153 #
154 # Close connection and cursor
155 #
156 self.Cur.close()
157 self.Conn.close()
158
159 ## Insert one file information
160 #
161 # Insert one file's information to the database
162 # 1. Create a record in TableFile
163 # 2. Create functions one by one
164 # 2.1 Create variables of function one by one
165 # 2.2 Create pcds of function one by one
166 # 3. Create variables one by one
167 # 4. Create pcds one by one
168 #
169 def InsertOneFile(self, File):
170 #
171 # Insert a record for file
172 #
173 FileID = self.TblFile.Insert(File.Name, File.ExtName, File.Path, File.FullPath, Model = File.Model, TimeStamp = File.TimeStamp)
174
175 if File.Model == DataClass.MODEL_FILE_C or File.Model == DataClass.MODEL_FILE_H:
176 IdTable = TableIdentifier(self.Cur)
177 IdTable.Table = "Identifier%s" % FileID
178 IdTable.Create()
179 #
180 # Insert function of file
181 #
182 for Function in File.FunctionList:
183 FunctionID = self.TblFunction.Insert(Function.Header, Function.Modifier, Function.Name, Function.ReturnStatement, \
184 Function.StartLine, Function.StartColumn, Function.EndLine, Function.EndColumn, \
185 Function.BodyStartLine, Function.BodyStartColumn, FileID, \
186 Function.FunNameStartLine, Function.FunNameStartColumn)
187 #
188 # Insert Identifier of function
189 #
190 for Identifier in Function.IdentifierList:
191 IdentifierID = IdTable.Insert(Identifier.Modifier, Identifier.Type, Identifier.Name, Identifier.Value, Identifier.Model, \
192 FileID, FunctionID, Identifier.StartLine, Identifier.StartColumn, Identifier.EndLine, Identifier.EndColumn)
193 #
194 # Insert Pcd of function
195 #
196 for Pcd in Function.PcdList:
197 PcdID = self.TblPcd.Insert(Pcd.CName, Pcd.TokenSpaceGuidCName, Pcd.Token, Pcd.DatumType, Pcd.Model, \
198 FileID, FunctionID, Pcd.StartLine, Pcd.StartColumn, Pcd.EndLine, Pcd.EndColumn)
199 #
200 # Insert Identifier of file
201 #
202 for Identifier in File.IdentifierList:
203 IdentifierID = IdTable.Insert(Identifier.Modifier, Identifier.Type, Identifier.Name, Identifier.Value, Identifier.Model, \
204 FileID, -1, Identifier.StartLine, Identifier.StartColumn, Identifier.EndLine, Identifier.EndColumn)
205 #
206 # Insert Pcd of file
207 #
208 for Pcd in File.PcdList:
209 PcdID = self.TblPcd.Insert(Pcd.CName, Pcd.TokenSpaceGuidCName, Pcd.Token, Pcd.DatumType, Pcd.Model, \
210 FileID, -1, Pcd.StartLine, Pcd.StartColumn, Pcd.EndLine, Pcd.EndColumn)
211
212 EdkLogger.verbose("Insert information from file %s ... DONE!" % File.FullPath)
213
214 ## UpdateIdentifierBelongsToFunction
215 #
216 # Update the field "BelongsToFunction" for each Indentifier
217 #
218 #
219 def UpdateIdentifierBelongsToFunction_disabled(self):
220 EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers started ...")
221
222 SqlCommand = """select ID, BelongsToFile, StartLine, EndLine, Model from Identifier"""
223 EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
224 self.Cur.execute(SqlCommand)
225 Records = self.Cur.fetchall()
226 for Record in Records:
227 IdentifierID = Record[0]
228 BelongsToFile = Record[1]
229 StartLine = Record[2]
230 EndLine = Record[3]
231 Model = Record[4]
232
233 #
234 # Check whether an identifier belongs to a function
235 #
236 EdkLogger.debug(4, "For common identifiers ... ")
237 SqlCommand = """select ID from Function
238 where StartLine < %s and EndLine > %s
239 and BelongsToFile = %s""" % (StartLine, EndLine, BelongsToFile)
240 EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
241 self.Cur.execute(SqlCommand)
242 IDs = self.Cur.fetchall()
243 for ID in IDs:
244 SqlCommand = """Update Identifier set BelongsToFunction = %s where ID = %s""" % (ID[0], IdentifierID)
245 EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
246 self.Cur.execute(SqlCommand)
247
248 #
249 # Check whether the identifier is a function header
250 #
251 EdkLogger.debug(4, "For function headers ... ")
252 if Model == DataClass.MODEL_IDENTIFIER_COMMENT:
253 SqlCommand = """select ID from Function
254 where StartLine = %s + 1
255 and BelongsToFile = %s""" % (EndLine, BelongsToFile)
256 EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
257 self.Cur.execute(SqlCommand)
258 IDs = self.Cur.fetchall()
259 for ID in IDs:
260 SqlCommand = """Update Identifier set BelongsToFunction = %s, Model = %s where ID = %s""" % (ID[0], DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, IdentifierID)
261 EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
262 self.Cur.execute(SqlCommand)
263
264 EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers ... DONE")
265
266
267 ## UpdateIdentifierBelongsToFunction
268 #
269 # Update the field "BelongsToFunction" for each Indentifier
270 #
271 #
272 def UpdateIdentifierBelongsToFunction(self):
273 EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers started ...")
274
275 SqlCommand = """select ID, BelongsToFile, StartLine, EndLine from Function"""
276 Records = self.TblFunction.Exec(SqlCommand)
277 Data1 = []
278 Data2 = []
279 for Record in Records:
280 FunctionID = Record[0]
281 BelongsToFile = Record[1]
282 StartLine = Record[2]
283 EndLine = Record[3]
284 #Data1.append(("'file%s'" % BelongsToFile, FunctionID, BelongsToFile, StartLine, EndLine))
285 #Data2.append(("'file%s'" % BelongsToFile, FunctionID, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, BelongsToFile, DataClass.MODEL_IDENTIFIER_COMMENT, StartLine - 1))
286
287 SqlCommand = """Update Identifier%s set BelongsToFunction = %s where BelongsToFile = %s and StartLine > %s and EndLine < %s""" % \
288 (BelongsToFile, FunctionID, BelongsToFile, StartLine, EndLine)
289 self.TblIdentifier.Exec(SqlCommand)
290
291 SqlCommand = """Update Identifier%s set BelongsToFunction = %s, Model = %s where BelongsToFile = %s and Model = %s and EndLine = %s""" % \
292 (BelongsToFile, FunctionID, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, BelongsToFile, DataClass.MODEL_IDENTIFIER_COMMENT, StartLine - 1)
293 self.TblIdentifier.Exec(SqlCommand)
294 # #
295 # # Check whether an identifier belongs to a function
296 # #
297 # print Data1
298 # SqlCommand = """Update ? set BelongsToFunction = ? where BelongsToFile = ? and StartLine > ? and EndLine < ?"""
299 # print SqlCommand
300 # EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
301 # self.Cur.executemany(SqlCommand, Data1)
302 #
303 # #
304 # # Check whether the identifier is a function header
305 # #
306 # EdkLogger.debug(4, "For function headers ... ")
307 # SqlCommand = """Update ? set BelongsToFunction = ?, Model = ? where BelongsToFile = ? and Model = ? and EndLine = ?"""
308 # EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
309 # self.Cur.executemany(SqlCommand, Data2)
310 #
311 # EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers ... DONE")
312
313
314 ##
315 #
316 # This acts like the main() function for the script, unless it is 'import'ed into another
317 # script.
318 #
319 if __name__ == '__main__':
320 EdkLogger.Initialize()
321 #EdkLogger.SetLevel(EdkLogger.VERBOSE)
322 EdkLogger.SetLevel(EdkLogger.DEBUG_0)
323 EdkLogger.verbose("Start at " + time.strftime('%H:%M:%S', time.localtime()))
324
325 Db = Database(DATABASE_PATH)
326 Db.InitDatabase()
327 Db.QueryTable(Db.TblDataModel)
328
329 identifier1 = DataClass.IdentifierClass(-1, '', '', "i''1", 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 32, 43, 54, 43)
330 identifier2 = DataClass.IdentifierClass(-1, '', '', 'i1', 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 15, 43, 20, 43)
331 identifier3 = DataClass.IdentifierClass(-1, '', '', 'i1', 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 55, 43, 58, 43)
332 identifier4 = DataClass.IdentifierClass(-1, '', '', "i1'", 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 77, 43, 88, 43)
333 fun1 = DataClass.FunctionClass(-1, '', '', 'fun1', '', 21, 2, 60, 45, 1, 23, 0, [], [])
334 file = DataClass.FileClass(-1, 'F1', 'c', 'C:\\', 'C:\\F1.exe', DataClass.MODEL_FILE_C, '2007-12-28', [fun1], [identifier1, identifier2, identifier3, identifier4], [])
335 Db.InsertOneFile(file)
336 Db.UpdateIdentifierBelongsToFunction()
337
338 Db.QueryTable(Db.TblFile)
339 Db.QueryTable(Db.TblFunction)
340 Db.QueryTable(Db.TblPcd)
341 Db.QueryTable(Db.TblIdentifier)
342
343 Db.Close()
344 EdkLogger.verbose("End at " + time.strftime('%H:%M:%S', time.localtime()))
345