1## @file
2# This file is used to create a database used by EOT 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#
11import sqlite3
12import Common.LongFilePathOs as os, time
13
14import Common.EdkLogger as EdkLogger
15import CommonDataClass.DataClass as DataClass
16
17from Table.TableDataModel import TableDataModel
18from Table.TableFile import TableFile
19from Table.TableFunction import TableFunction
20from Table.TableIdentifier import TableIdentifier
21from Table.TableEotReport import TableEotReport
22from Table.TableInf import TableInf
23from Table.TableDec import TableDec
24from Table.TableDsc import TableDsc
25from Table.TableFdf import TableFdf
26from Table.TableQuery import TableQuery
27
28##
29# Static definitions
30#
31DATABASE_PATH = "Eot.db"
32
33## Database class
34#
35# This class defined the EOT database
36# During the phase of initialization, the database will create all tables and
37# insert all records of table DataModel
38#
39class Database(object):
40    ## The constructor
41    #
42    #   @param  self:      The object pointer
43    #   @param  DbPath:    The file path of the database
44    #
45    def __init__(self, DbPath):
46        self.DbPath = DbPath
47        self.Conn = None
48        self.Cur = None
49        self.TblDataModel = None
50        self.TblFile = None
51        self.TblFunction = None
52        self.TblIdentifier = None
53        self.TblReport = None
54        self.TblInf = None
55        self.TblDec = None
56        self.TblDsc = None
57        self.TblFdf = None
58        self.TblQuery = None
59        self.TblQuery2 = None
60
61    ## InitDatabase() method
62    #  1. Delete all old existing tables
63    #  2. Create new tables
64    #  3. Initialize table DataModel
65    #
66    #  @param self: The object pointer
67    #  @param NewDatabase: Check if it needs to create a new database
68    #
69    def InitDatabase(self, NewDatabase = True):
70        EdkLogger.verbose("\nInitialize EOT 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=8192")
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.TblReport = TableEotReport(self.Cur)
89        self.TblInf = TableInf(self.Cur)
90        self.TblDec = TableDec(self.Cur)
91        self.TblDsc = TableDsc(self.Cur)
92        self.TblFdf = TableFdf(self.Cur)
93        self.TblQuery = TableQuery(self.Cur)
94        self.TblQuery2 = TableQuery(self.Cur)
95        self.TblQuery2.Table = 'Query2'
96
97        # Create new tables
98        if NewDatabase:
99            self.TblDataModel.Create()
100            self.TblFile.Create()
101            self.TblFunction.Create()
102            self.TblReport.Create()
103            self.TblInf.Create()
104            self.TblDec.Create()
105            self.TblDsc.Create()
106            self.TblFdf.Create()
107            self.TblQuery.Create()
108            self.TblQuery2.Create()
109
110        # Init each table's ID
111        self.TblDataModel.InitID()
112        self.TblFile.InitID()
113        self.TblFunction.InitID()
114        self.TblReport.InitID()
115        self.TblInf.InitID()
116        self.TblDec.InitID()
117        self.TblDsc.InitID()
118        self.TblFdf.InitID()
119        self.TblQuery.Drop()
120        self.TblQuery.Create()
121        self.TblQuery.InitID()
122        self.TblQuery2.Drop()
123        self.TblQuery2.Create()
124        self.TblQuery2.InitID()
125
126        # Initialize table DataModel
127        if NewDatabase:
128            self.TblDataModel.InitTable()
129
130        EdkLogger.verbose("Initialize EOT database ... DONE!")
131
132    ## QueryTable() method
133    #
134    #  Query a table
135    #
136    #  @param self: The object pointer
137    #  @param Table: The instance of the table to be queried
138    #
139    def QueryTable(self, Table):
140        Table.Query()
141
142    ## Close() method
143    #
144    # Commit all first
145    # Close the connection and cursor
146    #
147    def Close(self):
148        # Commit to file
149        self.Conn.commit()
150
151        # Close connection and cursor
152        self.Cur.close()
153        self.Conn.close()
154
155    ## InsertOneFile() method
156    #
157    # Insert one file's information to the database
158    # 1. Create a record in TableFile
159    # 2. Create functions one by one
160    #    2.1 Create variables of function one by one
161    #    2.2 Create pcds of function one by one
162    # 3. Create variables one by one
163    # 4. Create pcds one by one
164    #
165    # @param self: The object pointer
166    # @param File: The object of the file to be inserted
167    #
168    def InsertOneFile(self, File):
169        # Insert a record for file
170        FileID = self.TblFile.Insert(File.Name, File.ExtName, File.Path, File.FullPath, Model = File.Model, TimeStamp = File.TimeStamp)
171        IdTable = TableIdentifier(self.Cur)
172        IdTable.Table = "Identifier%s" % FileID
173        IdTable.Create()
174
175        # Insert function of file
176        for Function in File.FunctionList:
177            FunctionID = self.TblFunction.Insert(Function.Header, Function.Modifier, Function.Name, Function.ReturnStatement, \
178                                    Function.StartLine, Function.StartColumn, Function.EndLine, Function.EndColumn, \
179                                    Function.BodyStartLine, Function.BodyStartColumn, FileID, \
180                                    Function.FunNameStartLine, Function.FunNameStartColumn)
181
182            # Insert Identifier of function
183            for Identifier in Function.IdentifierList:
184                IdentifierID = IdTable.Insert(Identifier.Modifier, Identifier.Type, Identifier.Name, Identifier.Value, Identifier.Model, \
185                                        FileID, FunctionID, Identifier.StartLine, Identifier.StartColumn, Identifier.EndLine, Identifier.EndColumn)
186        # Insert Identifier of file
187        for Identifier in File.IdentifierList:
188            IdentifierID = IdTable.Insert(Identifier.Modifier, Identifier.Type, Identifier.Name, Identifier.Value, Identifier.Model, \
189                                    FileID, -1, Identifier.StartLine, Identifier.StartColumn, Identifier.EndLine, Identifier.EndColumn)
190
191        EdkLogger.verbose("Insert information from file %s ... DONE!" % File.FullPath)
192
193    ## UpdateIdentifierBelongsToFunction() method
194    #
195    #  Update the field "BelongsToFunction" for each Identifier
196    #
197    #  @param self: The object pointer
198    #
199    def UpdateIdentifierBelongsToFunction(self):
200        EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers started ...")
201
202        SqlCommand = """select ID, BelongsToFile, StartLine, EndLine from Function"""
203        Records = self.TblFunction.Exec(SqlCommand)
204        Data1 = []
205        Data2 = []
206        for Record in Records:
207            FunctionID = Record[0]
208            BelongsToFile = Record[1]
209            StartLine = Record[2]
210            EndLine = Record[3]
211
212            SqlCommand = """Update Identifier%s set BelongsToFunction = %s where BelongsToFile = %s and StartLine > %s and EndLine < %s""" % \
213                        (BelongsToFile, FunctionID, BelongsToFile, StartLine, EndLine)
214            self.TblIdentifier.Exec(SqlCommand)
215
216            SqlCommand = """Update Identifier%s set BelongsToFunction = %s, Model = %s where BelongsToFile = %s and Model = %s and EndLine = %s""" % \
217                         (BelongsToFile, FunctionID, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, BelongsToFile, DataClass.MODEL_IDENTIFIER_COMMENT, StartLine - 1)
218            self.TblIdentifier.Exec(SqlCommand)
219
220
221##
222#
223# This acts like the main() function for the script, unless it is 'import'ed into another
224# script.
225#
226if __name__ == '__main__':
227    EdkLogger.Initialize()
228    EdkLogger.SetLevel(EdkLogger.DEBUG_0)
229    EdkLogger.verbose("Start at " + time.strftime('%H:%M:%S', time.localtime()))
230
231    Db = Database(DATABASE_PATH)
232    Db.InitDatabase()
233    Db.QueryTable(Db.TblDataModel)
234
235    identifier1 = DataClass.IdentifierClass(-1, '', '', "i''1", 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 32,  43,  54,  43)
236    identifier2 = DataClass.IdentifierClass(-1, '', '', 'i1', 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 15,  43,  20,  43)
237    identifier3 = DataClass.IdentifierClass(-1, '', '', 'i1', 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 55,  43,  58,  43)
238    identifier4 = DataClass.IdentifierClass(-1, '', '', "i1'", 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 77,  43,  88,  43)
239    fun1 = DataClass.FunctionClass(-1, '', '', 'fun1', '', 21, 2, 60,  45, 1, 23, 0, [], [])
240    file = DataClass.FileClass(-1, 'F1', 'c', 'C:\\', 'C:\\F1.exe', DataClass.MODEL_FILE_C, '2007-12-28', [fun1], [identifier1, identifier2, identifier3, identifier4], [])
241    Db.InsertOneFile(file)
242
243    Db.QueryTable(Db.TblFile)
244    Db.QueryTable(Db.TblFunction)
245    Db.QueryTable(Db.TblIdentifier)
246
247    Db.Close()
248    EdkLogger.verbose("End at " + time.strftime('%H:%M:%S', time.localtime()))
249
250