1## @file
2# This file is used to create/update/query/erase table for files
3#
4# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
5# SPDX-License-Identifier: BSD-2-Clause-Patent
6#
7
8##
9# Import Modules
10#
11import Common.LongFilePathOs as os
12
13import Common.EdkLogger as EdkLogger
14from CommonDataClass import DataClass
15from CommonDataClass.DataClass import FileClass
16
17## Convert to SQL required string format
18def ConvertToSqlString(StringList):
19    return list(map(lambda s: "'" + s.replace("'", "''") + "'", StringList))
20
21## TableFile
22#
23# This class defined a common table
24#
25# @param object:     Inherited from object class
26#
27# @param Cursor:     Cursor of the database
28# @param TableName:  Name of the table
29#
30class Table(object):
31    _COLUMN_ = ''
32    _ID_STEP_ = 1
33    _ID_MAX_ = 0x80000000
34    _DUMMY_ = 0
35
36    def __init__(self, Db, Name='', IdBase=0, Temporary=False):
37        self.Db = Db
38        self.Table = Name
39        self.IdBase = int(IdBase)
40        self.ID = int(IdBase)
41        self.Temporary = Temporary
42        self.Contents = []
43
44    def __str__(self):
45        return self.Table
46
47    ## Create table
48    #
49    # Create a table
50    #
51    def Create(self, NewTable=True):
52        self.Db.CreateEmptyTable(self.Table)
53        self.ID = self.GetId()
54
55    ## Insert table
56    #
57    # Insert a record into a table
58    #
59    def Insert(self, *Args):
60        self.ID = self.ID + self._ID_STEP_
61        if self.ID >= (self.IdBase + self._ID_MAX_):
62            self.ID = self.IdBase + self._ID_STEP_
63        row = [self.ID]
64        row.extend(Args)
65        self.Contents.append(row)
66
67        return self.ID
68
69
70    ## Get count
71    #
72    # Get a count of all records of the table
73    #
74    # @retval Count:  Total count of all records
75    #
76    def GetCount(self):
77        tab = self.Db.GetTable(self.Table)
78        return len(tab)
79
80
81    def GetId(self):
82        tab = self.Db.GetTable(self.Table)
83        Id = max([int(item[0]) for item in tab])
84        if Id is None:
85            Id = self.IdBase
86        return Id
87
88    ## Init the ID of the table
89    #
90    # Init the ID of the table
91    #
92    def InitID(self):
93        self.ID = self.GetId()
94
95    ## Exec
96    #
97    # Exec Sql Command, return result
98    #
99    # @param SqlCommand:  The SqlCommand to be executed
100    #
101    # @retval RecordSet:  The result after executed
102    #
103    def Exec(self, SqlCommand):
104        EdkLogger.debug(EdkLogger.DEBUG_5, SqlCommand)
105        self.Db.execute(SqlCommand)
106        RecordSet = self.Db.fetchall()
107        return RecordSet
108
109    def SetEndFlag(self):
110        Tab = self.Db.GetTable(self.Table)
111        Tab.append(self._DUMMY_)
112
113
114    def IsIntegral(self):
115        tab = self.Db.GetTable(self.Table)
116        Id = min([int(item[0]) for item in tab])
117        if Id != -1:
118            return False
119        return True
120
121    def GetAll(self):
122        tab = self.Db.GetTable(self.Table)
123        return tab
124
125
126## TableFile
127#
128# This class defined a table used for file
129#
130# @param object:       Inherited from object class
131#
132class TableFile(Table):
133    _COLUMN_ = '''
134        ID INTEGER PRIMARY KEY,
135        Name VARCHAR NOT NULL,
136        ExtName VARCHAR,
137        Path VARCHAR,
138        FullPath VARCHAR NOT NULL,
139        Model INTEGER DEFAULT 0,
140        TimeStamp SINGLE NOT NULL,
141        FromItem REAL NOT NULL
142        '''
143    def __init__(self, Cursor):
144        Table.__init__(self, Cursor, 'File')
145
146    ## Insert table
147    #
148    # Insert a record into table File
149    #
150    # @param Name:      Name of a File
151    # @param ExtName:   ExtName of a File
152    # @param Path:      Path of a File
153    # @param FullPath:  FullPath of a File
154    # @param Model:     Model of a File
155    # @param TimeStamp: TimeStamp of a File
156    #
157    def Insert(self, Name, ExtName, Path, FullPath, Model, TimeStamp, FromItem=0):
158        (Name, ExtName, Path, FullPath) = ConvertToSqlString((Name, ExtName, Path, FullPath))
159        return Table.Insert(
160            self,
161            Name,
162            ExtName,
163            Path,
164            FullPath,
165            Model,
166            TimeStamp,
167            FromItem
168            )
169
170    ## InsertFile
171    #
172    # Insert one file to table
173    #
174    # @param FileFullPath:  The full path of the file
175    # @param Model:         The model of the file
176    #
177    # @retval FileID:       The ID after record is inserted
178    #
179    def InsertFile(self, File, Model, FromItem=''):
180        if FromItem:
181            return self.Insert(
182                        File.Name,
183                        File.Ext,
184                        File.Dir,
185                        File.Path,
186                        Model,
187                        File.TimeStamp,
188                        FromItem
189                        )
190        return self.Insert(
191                        File.Name,
192                        File.Ext,
193                        File.Dir,
194                        File.Path,
195                        Model,
196                        File.TimeStamp
197                        )
198
199    ## Get type of a given file
200    #
201    #   @param  FileId      ID of a file
202    #
203    #   @retval file_type   Model value of given file in the table
204    #
205    def GetFileType(self, FileId):
206        QueryScript = "select Model from %s where ID = '%s'" % (self.Table, FileId)
207        RecordList = self.Exec(QueryScript)
208        if len(RecordList) == 0:
209            return None
210        return RecordList[0][0]
211
212    ## Get file timestamp of a given file
213    #
214    #   @param  FileId      ID of file
215    #
216    #   @retval timestamp   TimeStamp value of given file in the table
217    #
218    def GetFileTimeStamp(self, FileId):
219        QueryScript = "select TimeStamp from %s where ID = '%s'" % (self.Table, FileId)
220        RecordList = self.Exec(QueryScript)
221        if len(RecordList) == 0:
222            return None
223        return RecordList[0][0]
224
225    ## Update the timestamp of a given file
226    #
227    #   @param  FileId      ID of file
228    #   @param  TimeStamp   Time stamp of file
229    #
230    def SetFileTimeStamp(self, FileId, TimeStamp):
231        self.Exec("update %s set TimeStamp=%s where ID='%s'" % (self.Table, TimeStamp, FileId))
232
233    ## Get list of file with given type
234    #
235    #   @param  FileType    Type value of file
236    #
237    #   @retval file_list   List of files with the given type
238    #
239    def GetFileList(self, FileType):
240        RecordList = self.Exec("select FullPath from %s where Model=%s" % (self.Table, FileType))
241        if len(RecordList) == 0:
242            return []
243        return [R[0] for R in RecordList]
244
245## TableDataModel
246#
247# This class defined a table used for data model
248#
249# @param object:       Inherited from object class
250#
251#
252class TableDataModel(Table):
253    _COLUMN_ = """
254        ID INTEGER PRIMARY KEY,
255        CrossIndex INTEGER NOT NULL,
256        Name VARCHAR NOT NULL,
257        Description VARCHAR
258        """
259    def __init__(self, Cursor):
260        Table.__init__(self, Cursor, 'DataModel')
261
262    ## Insert table
263    #
264    # Insert a record into table DataModel
265    #
266    # @param ID:           ID of a ModelType
267    # @param CrossIndex:   CrossIndex of a ModelType
268    # @param Name:         Name of a ModelType
269    # @param Description:  Description of a ModelType
270    #
271    def Insert(self, CrossIndex, Name, Description):
272        (Name, Description) = ConvertToSqlString((Name, Description))
273        return Table.Insert(self, CrossIndex, Name, Description)
274
275    ## Init table
276    #
277    # Create all default records of table DataModel
278    #
279    def InitTable(self):
280        EdkLogger.verbose("\nInitialize table DataModel started ...")
281        Count = self.GetCount()
282        if Count is not None and Count != 0:
283            return
284        for Item in DataClass.MODEL_LIST:
285            CrossIndex = Item[1]
286            Name = Item[0]
287            Description = Item[0]
288            self.Insert(CrossIndex, Name, Description)
289        EdkLogger.verbose("Initialize table DataModel ... DONE!")
290
291    ## Get CrossIndex
292    #
293    # Get a model's cross index from its name
294    #
295    # @param ModelName:    Name of the model
296    # @retval CrossIndex:  CrossIndex of the model
297    #
298    def GetCrossIndex(self, ModelName):
299        CrossIndex = -1
300        SqlCommand = """select CrossIndex from DataModel where name = '""" + ModelName + """'"""
301        self.Db.execute(SqlCommand)
302        for Item in self.Db:
303            CrossIndex = Item[0]
304
305        return CrossIndex
306
307