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# 17import sqlite3 18import Common.LongFilePathOs as os, time 19 20import Common.EdkLogger as EdkLogger 21import CommonDataClass.DataClass as DataClass 22 23from Table.TableDataModel import TableDataModel 24from Table.TableFile import TableFile 25from Table.TableFunction import TableFunction 26from Table.TablePcd import TablePcd 27from Table.TableIdentifier import TableIdentifier 28from Table.TableReport import TableReport 29from MetaFileWorkspace.MetaFileTable import ModuleTable 30from MetaFileWorkspace.MetaFileTable import PackageTable 31from MetaFileWorkspace.MetaFileTable import PlatformTable 32from Table.TableFdf import TableFdf 33 34## 35# Static definitions 36# 37DATABASE_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# 52class 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# 319if __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 346