9520be4345f9af735ee34404bfc76ffd66a76bb4
[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 - 2008, 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 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 Table.TableInf import TableInf
30 from Table.TableDec import TableDec
31 from Table.TableDsc import TableDsc
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 = TableInf(self.Cur)
96 self.TblDec = TableDec(self.Cur)
97 self.TblDsc = TableDsc(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 IdTable = TableIdentifier(self.Cur)
175 IdTable.Table = "Identifier%s" % FileID
176 IdTable.Create()
177
178 #
179 # Insert function of file
180 #
181 for Function in File.FunctionList:
182 FunctionID = self.TblFunction.Insert(Function.Header, Function.Modifier, Function.Name, Function.ReturnStatement, \
183 Function.StartLine, Function.StartColumn, Function.EndLine, Function.EndColumn, \
184 Function.BodyStartLine, Function.BodyStartColumn, FileID, \
185 Function.FunNameStartLine, Function.FunNameStartColumn)
186 #
187 # Insert Identifier of function
188 #
189 for Identifier in Function.IdentifierList:
190 IdentifierID = IdTable.Insert(Identifier.Modifier, Identifier.Type, Identifier.Name, Identifier.Value, Identifier.Model, \
191 FileID, FunctionID, Identifier.StartLine, Identifier.StartColumn, Identifier.EndLine, Identifier.EndColumn)
192 #
193 # Insert Pcd of function
194 #
195 for Pcd in Function.PcdList:
196 PcdID = self.TblPcd.Insert(Pcd.CName, Pcd.TokenSpaceGuidCName, Pcd.Token, Pcd.DatumType, Pcd.Model, \
197 FileID, FunctionID, Pcd.StartLine, Pcd.StartColumn, Pcd.EndLine, Pcd.EndColumn)
198 #
199 # Insert Identifier of file
200 #
201 for Identifier in File.IdentifierList:
202 IdentifierID = IdTable.Insert(Identifier.Modifier, Identifier.Type, Identifier.Name, Identifier.Value, Identifier.Model, \
203 FileID, -1, Identifier.StartLine, Identifier.StartColumn, Identifier.EndLine, Identifier.EndColumn)
204 #
205 # Insert Pcd of file
206 #
207 for Pcd in File.PcdList:
208 PcdID = self.TblPcd.Insert(Pcd.CName, Pcd.TokenSpaceGuidCName, Pcd.Token, Pcd.DatumType, Pcd.Model, \
209 FileID, -1, Pcd.StartLine, Pcd.StartColumn, Pcd.EndLine, Pcd.EndColumn)
210
211 EdkLogger.verbose("Insert information from file %s ... DONE!" % File.FullPath)
212
213 ## UpdateIdentifierBelongsToFunction
214 #
215 # Update the field "BelongsToFunction" for each Indentifier
216 #
217 #
218 def UpdateIdentifierBelongsToFunction_disabled(self):
219 EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers started ...")
220
221 SqlCommand = """select ID, BelongsToFile, StartLine, EndLine, Model from Identifier"""
222 EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
223 self.Cur.execute(SqlCommand)
224 Records = self.Cur.fetchall()
225 for Record in Records:
226 IdentifierID = Record[0]
227 BelongsToFile = Record[1]
228 StartLine = Record[2]
229 EndLine = Record[3]
230 Model = Record[4]
231
232 #
233 # Check whether an identifier belongs to a function
234 #
235 EdkLogger.debug(4, "For common identifiers ... ")
236 SqlCommand = """select ID from Function
237 where StartLine < %s and EndLine > %s
238 and BelongsToFile = %s""" % (StartLine, EndLine, BelongsToFile)
239 EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
240 self.Cur.execute(SqlCommand)
241 IDs = self.Cur.fetchall()
242 for ID in IDs:
243 SqlCommand = """Update Identifier set BelongsToFunction = %s where ID = %s""" % (ID[0], IdentifierID)
244 EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
245 self.Cur.execute(SqlCommand)
246
247 #
248 # Check whether the identifier is a function header
249 #
250 EdkLogger.debug(4, "For function headers ... ")
251 if Model == DataClass.MODEL_IDENTIFIER_COMMENT:
252 SqlCommand = """select ID from Function
253 where StartLine = %s + 1
254 and BelongsToFile = %s""" % (EndLine, BelongsToFile)
255 EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
256 self.Cur.execute(SqlCommand)
257 IDs = self.Cur.fetchall()
258 for ID in IDs:
259 SqlCommand = """Update Identifier set BelongsToFunction = %s, Model = %s where ID = %s""" % (ID[0], DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, IdentifierID)
260 EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
261 self.Cur.execute(SqlCommand)
262
263 EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers ... DONE")
264
265
266 ## UpdateIdentifierBelongsToFunction
267 #
268 # Update the field "BelongsToFunction" for each Indentifier
269 #
270 #
271 def UpdateIdentifierBelongsToFunction(self):
272 EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers started ...")
273
274 SqlCommand = """select ID, BelongsToFile, StartLine, EndLine from Function"""
275 Records = self.TblFunction.Exec(SqlCommand)
276 Data1 = []
277 Data2 = []
278 for Record in Records:
279 FunctionID = Record[0]
280 BelongsToFile = Record[1]
281 StartLine = Record[2]
282 EndLine = Record[3]
283 #Data1.append(("'file%s'" % BelongsToFile, FunctionID, BelongsToFile, StartLine, EndLine))
284 #Data2.append(("'file%s'" % BelongsToFile, FunctionID, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, BelongsToFile, DataClass.MODEL_IDENTIFIER_COMMENT, StartLine - 1))
285
286 SqlCommand = """Update Identifier%s set BelongsToFunction = %s where BelongsToFile = %s and StartLine > %s and EndLine < %s""" % \
287 (BelongsToFile, FunctionID, BelongsToFile, StartLine, EndLine)
288 self.TblIdentifier.Exec(SqlCommand)
289
290 SqlCommand = """Update Identifier%s set BelongsToFunction = %s, Model = %s where BelongsToFile = %s and Model = %s and EndLine = %s""" % \
291 (BelongsToFile, FunctionID, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, BelongsToFile, DataClass.MODEL_IDENTIFIER_COMMENT, StartLine - 1)
292 self.TblIdentifier.Exec(SqlCommand)
293 # #
294 # # Check whether an identifier belongs to a function
295 # #
296 # print Data1
297 # SqlCommand = """Update ? set BelongsToFunction = ? where BelongsToFile = ? and StartLine > ? and EndLine < ?"""
298 # print SqlCommand
299 # EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
300 # self.Cur.executemany(SqlCommand, Data1)
301 #
302 # #
303 # # Check whether the identifier is a function header
304 # #
305 # EdkLogger.debug(4, "For function headers ... ")
306 # SqlCommand = """Update ? set BelongsToFunction = ?, Model = ? where BelongsToFile = ? and Model = ? and EndLine = ?"""
307 # EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
308 # self.Cur.executemany(SqlCommand, Data2)
309 #
310 # EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers ... DONE")
311
312
313 ##
314 #
315 # This acts like the main() function for the script, unless it is 'import'ed into another
316 # script.
317 #
318 if __name__ == '__main__':
319 EdkLogger.Initialize()
320 #EdkLogger.SetLevel(EdkLogger.VERBOSE)
321 EdkLogger.SetLevel(EdkLogger.DEBUG_0)
322 EdkLogger.verbose("Start at " + time.strftime('%H:%M:%S', time.localtime()))
323
324 Db = Database(DATABASE_PATH)
325 Db.InitDatabase()
326 Db.QueryTable(Db.TblDataModel)
327
328 identifier1 = DataClass.IdentifierClass(-1, '', '', "i''1", 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 32, 43, 54, 43)
329 identifier2 = DataClass.IdentifierClass(-1, '', '', 'i1', 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 15, 43, 20, 43)
330 identifier3 = DataClass.IdentifierClass(-1, '', '', 'i1', 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 55, 43, 58, 43)
331 identifier4 = DataClass.IdentifierClass(-1, '', '', "i1'", 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 77, 43, 88, 43)
332 fun1 = DataClass.FunctionClass(-1, '', '', 'fun1', '', 21, 2, 60, 45, 1, 23, 0, [], [])
333 file = DataClass.FileClass(-1, 'F1', 'c', 'C:\\', 'C:\\F1.exe', DataClass.MODEL_FILE_C, '2007-12-28', [fun1], [identifier1, identifier2, identifier3, identifier4], [])
334 Db.InsertOneFile(file)
335 Db.UpdateIdentifierBelongsToFunction()
336
337 Db.QueryTable(Db.TblFile)
338 Db.QueryTable(Db.TblFunction)
339 Db.QueryTable(Db.TblPcd)
340 Db.QueryTable(Db.TblIdentifier)
341
342 Db.Close()
343 EdkLogger.verbose("End at " + time.strftime('%H:%M:%S', time.localtime()))
344