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