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# SPDX-License-Identifier: BSD-2-Clause-Patent 6# 7 8## 9# Import Modules 10# 11from __future__ import absolute_import 12import sqlite3 13import Common.LongFilePathOs as os, time 14 15import Common.EdkLogger as EdkLogger 16import CommonDataClass.DataClass as DataClass 17 18from Table.TableDataModel import TableDataModel 19from Table.TableFile import TableFile 20from Table.TableFunction import TableFunction 21from Table.TablePcd import TablePcd 22from Table.TableIdentifier import TableIdentifier 23from Table.TableReport import TableReport 24from Ecc.MetaFileWorkspace.MetaFileTable import ModuleTable 25from Ecc.MetaFileWorkspace.MetaFileTable import PackageTable 26from Ecc.MetaFileWorkspace.MetaFileTable import PlatformTable 27from Table.TableFdf import TableFdf 28 29## 30# Static definitions 31# 32DATABASE_PATH = "Ecc.db" 33 34## Database 35# 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 39# 40# @param object: Inherited from object class 41# @param DbPath: A string for the path of the ECC database 42# 43# @var Conn: Connection of the ECC database 44# @var Cur: Cursor of the connection 45# @var TblDataModel: Local instance for TableDataModel 46# 47class Database(object): 48 def __init__(self, DbPath): 49 self.DbPath = DbPath 50 self.Conn = None 51 self.Cur = None 52 self.TblDataModel = None 53 self.TblFile = None 54 self.TblFunction = None 55 self.TblIdentifier = None 56 self.TblPcd = None 57 self.TblReport = None 58 self.TblInf = None 59 self.TblDec = None 60 self.TblDsc = None 61 self.TblFdf = None 62 63 ## Initialize ECC database 64 # 65 # 1. Delete all old existing tables 66 # 2. Create new tables 67 # 3. Initialize table DataModel 68 # 69 def InitDatabase(self, NewDatabase = True): 70 EdkLogger.verbose("\nInitialize ECC database started ...") 71 # 72 # Drop all old existing tables 73 # 74 if NewDatabase: 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() 83 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) 94 95 # 96 # Create new tables 97 # 98 if NewDatabase: 99 self.TblDataModel.Create() 100 self.TblFile.Create() 101 self.TblFunction.Create() 102 self.TblPcd.Create() 103 self.TblReport.Create() 104 self.TblInf.Create() 105 self.TblDec.Create() 106 self.TblDsc.Create() 107 self.TblFdf.Create() 108 109 # 110 # Init each table's ID 111 # 112 self.TblDataModel.InitID() 113 self.TblFile.InitID() 114 self.TblFunction.InitID() 115 self.TblPcd.InitID() 116 self.TblReport.InitID() 117 self.TblInf.InitID() 118 self.TblDec.InitID() 119 self.TblDsc.InitID() 120 self.TblFdf.InitID() 121 122 # 123 # Initialize table DataModel 124 # 125 if NewDatabase: 126 self.TblDataModel.InitTable() 127 128 EdkLogger.verbose("Initialize ECC database ... DONE!") 129 130 ## Query a table 131 # 132 # @param Table: The instance of the table to be queried 133 # 134 def QueryTable(self, Table): 135 Table.Query() 136 137 ## Close entire database 138 # 139 # Commit all first 140 # Close the connection and cursor 141 # 142 def Close(self): 143 # 144 # Commit to file 145 # 146 self.Conn.commit() 147 148 # 149 # Close connection and cursor 150 # 151 self.Cur.close() 152 self.Conn.close() 153 154 ## Insert one file information 155 # 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 163 # 164 def InsertOneFile(self, File): 165 # 166 # Insert a record for file 167 # 168 FileID = self.TblFile.Insert(File.Name, File.ExtName, File.Path, File.FullPath, Model = File.Model, TimeStamp = File.TimeStamp) 169 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 173 IdTable.Create() 174 # 175 # Insert function of file 176 # 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) 182 # 183 # Insert Identifier of function 184 # 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) 188 # 189 # Insert Pcd of function 190 # 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) 194 # 195 # Insert Identifier of file 196 # 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) 200 # 201 # Insert Pcd of file 202 # 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) 206 207 EdkLogger.verbose("Insert information from file %s ... DONE!" % File.FullPath) 208 209 ## UpdateIdentifierBelongsToFunction 210 # 211 # Update the field "BelongsToFunction" for each Identifier 212 # 213 # 214 def UpdateIdentifierBelongsToFunction_disabled(self): 215 EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers started ...") 216 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] 225 EndLine = Record[3] 226 Model = Record[4] 227 228 # 229 # Check whether an identifier belongs to a function 230 # 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() 238 for ID in IDs: 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) 242 243 # 244 # Check whether the identifier is a function header 245 # 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() 254 for ID in IDs: 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) 258 259 EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers ... DONE") 260 261 262 ## UpdateIdentifierBelongsToFunction 263 # 264 # Update the field "BelongsToFunction" for each Identifier 265 # 266 # 267 def UpdateIdentifierBelongsToFunction(self): 268 EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers started ...") 269 270 SqlCommand = """select ID, BelongsToFile, StartLine, EndLine from Function""" 271 Records = self.TblFunction.Exec(SqlCommand) 272 Data1 = [] 273 Data2 = [] 274 for Record in Records: 275 FunctionID = Record[0] 276 BelongsToFile = Record[1] 277 StartLine = Record[2] 278 EndLine = Record[3] 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)) 281 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) 285 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) 289# # 290# # Check whether an identifier belongs to a function 291# # 292# print Data1 293# SqlCommand = """Update ? set BelongsToFunction = ? where BelongsToFile = ? and StartLine > ? and EndLine < ?""" 294# print SqlCommand 295# EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand) 296# self.Cur.executemany(SqlCommand, Data1) 297# 298# # 299# # Check whether the identifier is a function header 300# # 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) 305# 306# EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers ... DONE") 307 308 309## 310# 311# This acts like the main() function for the script, unless it is 'import'ed into another 312# script. 313# 314if __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())) 319 320 Db = Database(DATABASE_PATH) 321 Db.InitDatabase() 322 Db.QueryTable(Db.TblDataModel) 323 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() 332 333 Db.QueryTable(Db.TblFile) 334 Db.QueryTable(Db.TblFunction) 335 Db.QueryTable(Db.TblPcd) 336 Db.QueryTable(Db.TblIdentifier) 337 338 Db.Close() 339 EdkLogger.verbose("End at " + time.strftime('%H:%M:%S', time.localtime())) 340 341