2 # This file is used to create a database used by ECC tool
4 # Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
5 # SPDX-License-Identifier: BSD-2-Clause-Patent
11 from __future__
import absolute_import
13 import Common
.LongFilePathOs
as os
, time
15 import Common
.EdkLogger
as EdkLogger
16 import CommonDataClass
.DataClass
as DataClass
18 from Table
.TableDataModel
import TableDataModel
19 from Table
.TableFile
import TableFile
20 from Table
.TableFunction
import TableFunction
21 from Table
.TablePcd
import TablePcd
22 from Table
.TableIdentifier
import TableIdentifier
23 from Table
.TableReport
import TableReport
24 from Ecc
.MetaFileWorkspace
.MetaFileTable
import ModuleTable
25 from Ecc
.MetaFileWorkspace
.MetaFileTable
import PackageTable
26 from Ecc
.MetaFileWorkspace
.MetaFileTable
import PlatformTable
27 from Table
.TableFdf
import TableFdf
32 DATABASE_PATH
= "Ecc.db"
36 # This class defined the ECC database
37 # During the phase of initialization, the database will create all tables and
38 # insert all records of table DataModel
40 # @param object: Inherited from object class
41 # @param DbPath: A string for the path of the ECC database
43 # @var Conn: Connection of the ECC database
44 # @var Cur: Cursor of the connection
45 # @var TblDataModel: Local instance for TableDataModel
47 class Database(object):
48 def __init__(self
, DbPath
):
52 self
.TblDataModel
= None
54 self
.TblFunction
= None
55 self
.TblIdentifier
= None
63 ## Initialize ECC database
65 # 1. Delete all old existing tables
66 # 2. Create new tables
67 # 3. Initialize table DataModel
69 def InitDatabase(self
, NewDatabase
= True):
70 EdkLogger
.verbose("\nInitialize ECC database started ...")
72 # Drop all old existing tables
75 if os
.path
.exists(self
.DbPath
):
76 os
.remove(self
.DbPath
)
77 self
.Conn
= sqlite3
.connect(self
.DbPath
, isolation_level
= 'DEFERRED')
78 self
.Conn
.execute("PRAGMA page_size=4096")
79 self
.Conn
.execute("PRAGMA synchronous=OFF")
80 # to avoid non-ascii character conversion error
81 self
.Conn
.text_factory
= str
82 self
.Cur
= self
.Conn
.cursor()
84 self
.TblDataModel
= TableDataModel(self
.Cur
)
85 self
.TblFile
= TableFile(self
.Cur
)
86 self
.TblFunction
= TableFunction(self
.Cur
)
87 self
.TblIdentifier
= TableIdentifier(self
.Cur
)
88 self
.TblPcd
= TablePcd(self
.Cur
)
89 self
.TblReport
= TableReport(self
.Cur
)
90 self
.TblInf
= ModuleTable(self
.Cur
)
91 self
.TblDec
= PackageTable(self
.Cur
)
92 self
.TblDsc
= PlatformTable(self
.Cur
)
93 self
.TblFdf
= TableFdf(self
.Cur
)
99 self
.TblDataModel
.Create()
100 self
.TblFile
.Create()
101 self
.TblFunction
.Create()
103 self
.TblReport
.Create()
110 # Init each table's ID
112 self
.TblDataModel
.InitID()
113 self
.TblFile
.InitID()
114 self
.TblFunction
.InitID()
116 self
.TblReport
.InitID()
123 # Initialize table DataModel
126 self
.TblDataModel
.InitTable()
128 EdkLogger
.verbose("Initialize ECC database ... DONE!")
132 # @param Table: The instance of the table to be queried
134 def QueryTable(self
, Table
):
137 ## Close entire database
140 # Close the connection and cursor
149 # Close connection and cursor
154 ## Insert one file information
156 # Insert one file's information to the database
157 # 1. Create a record in TableFile
158 # 2. Create functions one by one
159 # 2.1 Create variables of function one by one
160 # 2.2 Create pcds of function one by one
161 # 3. Create variables one by one
162 # 4. Create pcds one by one
164 def InsertOneFile(self
, File
):
166 # Insert a record for file
168 FileID
= self
.TblFile
.Insert(File
.Name
, File
.ExtName
, File
.Path
, File
.FullPath
, Model
= File
.Model
, TimeStamp
= File
.TimeStamp
)
170 if File
.Model
== DataClass
.MODEL_FILE_C
or File
.Model
== DataClass
.MODEL_FILE_H
:
171 IdTable
= TableIdentifier(self
.Cur
)
172 IdTable
.Table
= "Identifier%s" % FileID
175 # Insert function of file
177 for Function
in File
.FunctionList
:
178 FunctionID
= self
.TblFunction
.Insert(Function
.Header
, Function
.Modifier
, Function
.Name
, Function
.ReturnStatement
, \
179 Function
.StartLine
, Function
.StartColumn
, Function
.EndLine
, Function
.EndColumn
, \
180 Function
.BodyStartLine
, Function
.BodyStartColumn
, FileID
, \
181 Function
.FunNameStartLine
, Function
.FunNameStartColumn
)
183 # Insert Identifier of function
185 for Identifier
in Function
.IdentifierList
:
186 IdentifierID
= IdTable
.Insert(Identifier
.Modifier
, Identifier
.Type
, Identifier
.Name
, Identifier
.Value
, Identifier
.Model
, \
187 FileID
, FunctionID
, Identifier
.StartLine
, Identifier
.StartColumn
, Identifier
.EndLine
, Identifier
.EndColumn
)
189 # Insert Pcd of function
191 for Pcd
in Function
.PcdList
:
192 PcdID
= self
.TblPcd
.Insert(Pcd
.CName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Token
, Pcd
.DatumType
, Pcd
.Model
, \
193 FileID
, FunctionID
, Pcd
.StartLine
, Pcd
.StartColumn
, Pcd
.EndLine
, Pcd
.EndColumn
)
195 # Insert Identifier of file
197 for Identifier
in File
.IdentifierList
:
198 IdentifierID
= IdTable
.Insert(Identifier
.Modifier
, Identifier
.Type
, Identifier
.Name
, Identifier
.Value
, Identifier
.Model
, \
199 FileID
, -1, Identifier
.StartLine
, Identifier
.StartColumn
, Identifier
.EndLine
, Identifier
.EndColumn
)
203 for Pcd
in File
.PcdList
:
204 PcdID
= self
.TblPcd
.Insert(Pcd
.CName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Token
, Pcd
.DatumType
, Pcd
.Model
, \
205 FileID
, -1, Pcd
.StartLine
, Pcd
.StartColumn
, Pcd
.EndLine
, Pcd
.EndColumn
)
207 EdkLogger
.verbose("Insert information from file %s ... DONE!" % File
.FullPath
)
209 ## UpdateIdentifierBelongsToFunction
211 # Update the field "BelongsToFunction" for each Identifier
214 def UpdateIdentifierBelongsToFunction_disabled(self
):
215 EdkLogger
.verbose("Update 'BelongsToFunction' for Identifiers started ...")
217 SqlCommand
= """select ID, BelongsToFile, StartLine, EndLine, Model from Identifier"""
218 EdkLogger
.debug(4, "SqlCommand: %s" %SqlCommand
)
219 self
.Cur
.execute(SqlCommand
)
220 Records
= self
.Cur
.fetchall()
221 for Record
in Records
:
222 IdentifierID
= Record
[0]
223 BelongsToFile
= Record
[1]
224 StartLine
= Record
[2]
229 # Check whether an identifier belongs to a function
231 EdkLogger
.debug(4, "For common identifiers ... ")
232 SqlCommand
= """select ID from Function
233 where StartLine < %s and EndLine > %s
234 and BelongsToFile = %s""" % (StartLine
, EndLine
, BelongsToFile
)
235 EdkLogger
.debug(4, "SqlCommand: %s" %SqlCommand
)
236 self
.Cur
.execute(SqlCommand
)
237 IDs
= self
.Cur
.fetchall()
239 SqlCommand
= """Update Identifier set BelongsToFunction = %s where ID = %s""" % (ID
[0], IdentifierID
)
240 EdkLogger
.debug(4, "SqlCommand: %s" %SqlCommand
)
241 self
.Cur
.execute(SqlCommand
)
244 # Check whether the identifier is a function header
246 EdkLogger
.debug(4, "For function headers ... ")
247 if Model
== DataClass
.MODEL_IDENTIFIER_COMMENT
:
248 SqlCommand
= """select ID from Function
249 where StartLine = %s + 1
250 and BelongsToFile = %s""" % (EndLine
, BelongsToFile
)
251 EdkLogger
.debug(4, "SqlCommand: %s" %SqlCommand
)
252 self
.Cur
.execute(SqlCommand
)
253 IDs
= self
.Cur
.fetchall()
255 SqlCommand
= """Update Identifier set BelongsToFunction = %s, Model = %s where ID = %s""" % (ID
[0], DataClass
.MODEL_IDENTIFIER_FUNCTION_HEADER
, IdentifierID
)
256 EdkLogger
.debug(4, "SqlCommand: %s" %SqlCommand
)
257 self
.Cur
.execute(SqlCommand
)
259 EdkLogger
.verbose("Update 'BelongsToFunction' for Identifiers ... DONE")
262 ## UpdateIdentifierBelongsToFunction
264 # Update the field "BelongsToFunction" for each Identifier
267 def UpdateIdentifierBelongsToFunction(self
):
268 EdkLogger
.verbose("Update 'BelongsToFunction' for Identifiers started ...")
270 SqlCommand
= """select ID, BelongsToFile, StartLine, EndLine from Function"""
271 Records
= self
.TblFunction
.Exec(SqlCommand
)
274 for Record
in Records
:
275 FunctionID
= Record
[0]
276 BelongsToFile
= Record
[1]
277 StartLine
= Record
[2]
279 #Data1.append(("'file%s'" % BelongsToFile, FunctionID, BelongsToFile, StartLine, EndLine))
280 #Data2.append(("'file%s'" % BelongsToFile, FunctionID, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, BelongsToFile, DataClass.MODEL_IDENTIFIER_COMMENT, StartLine - 1))
282 SqlCommand
= """Update Identifier%s set BelongsToFunction = %s where BelongsToFile = %s and StartLine > %s and EndLine < %s""" % \
283 (BelongsToFile
, FunctionID
, BelongsToFile
, StartLine
, EndLine
)
284 self
.TblIdentifier
.Exec(SqlCommand
)
286 SqlCommand
= """Update Identifier%s set BelongsToFunction = %s, Model = %s where BelongsToFile = %s and Model = %s and EndLine = %s""" % \
287 (BelongsToFile
, FunctionID
, DataClass
.MODEL_IDENTIFIER_FUNCTION_HEADER
, BelongsToFile
, DataClass
.MODEL_IDENTIFIER_COMMENT
, StartLine
- 1)
288 self
.TblIdentifier
.Exec(SqlCommand
)
290 # # Check whether an identifier belongs to a function
293 # SqlCommand = """Update ? set BelongsToFunction = ? where BelongsToFile = ? and StartLine > ? and EndLine < ?"""
295 # EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
296 # self.Cur.executemany(SqlCommand, Data1)
299 # # Check whether the identifier is a function header
301 # EdkLogger.debug(4, "For function headers ... ")
302 # SqlCommand = """Update ? set BelongsToFunction = ?, Model = ? where BelongsToFile = ? and Model = ? and EndLine = ?"""
303 # EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand)
304 # self.Cur.executemany(SqlCommand, Data2)
306 # EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers ... DONE")
311 # This acts like the main() function for the script, unless it is 'import'ed into another
314 if __name__
== '__main__':
315 EdkLogger
.Initialize()
316 #EdkLogger.SetLevel(EdkLogger.VERBOSE)
317 EdkLogger
.SetLevel(EdkLogger
.DEBUG_0
)
318 EdkLogger
.verbose("Start at " + time
.strftime('%H:%M:%S', time
.localtime()))
320 Db
= Database(DATABASE_PATH
)
322 Db
.QueryTable(Db
.TblDataModel
)
324 identifier1
= DataClass
.IdentifierClass(-1, '', '', "i''1", 'aaa', DataClass
.MODEL_IDENTIFIER_COMMENT
, 1, -1, 32, 43, 54, 43)
325 identifier2
= DataClass
.IdentifierClass(-1, '', '', 'i1', 'aaa', DataClass
.MODEL_IDENTIFIER_COMMENT
, 1, -1, 15, 43, 20, 43)
326 identifier3
= DataClass
.IdentifierClass(-1, '', '', 'i1', 'aaa', DataClass
.MODEL_IDENTIFIER_COMMENT
, 1, -1, 55, 43, 58, 43)
327 identifier4
= DataClass
.IdentifierClass(-1, '', '', "i1'", 'aaa', DataClass
.MODEL_IDENTIFIER_COMMENT
, 1, -1, 77, 43, 88, 43)
328 fun1
= DataClass
.FunctionClass(-1, '', '', 'fun1', '', 21, 2, 60, 45, 1, 23, 0, [], [])
329 file = DataClass
.FileClass(-1, 'F1', 'c', 'C:\\', 'C:\\F1.exe', DataClass
.MODEL_FILE_C
, '2007-12-28', [fun1
], [identifier1
, identifier2
, identifier3
, identifier4
], [])
330 Db
.InsertOneFile(file)
331 Db
.UpdateIdentifierBelongsToFunction()
333 Db
.QueryTable(Db
.TblFile
)
334 Db
.QueryTable(Db
.TblFunction
)
335 Db
.QueryTable(Db
.TblPcd
)
336 Db
.QueryTable(Db
.TblIdentifier
)
339 EdkLogger
.verbose("End at " + time
.strftime('%H:%M:%S', time
.localtime()))